0

I have an object called "Book" with columns like title, author, bookID etc... created on Microsoft SQL Server. Everything is connected with Netbeans and works fine. I also have the filter/search option which works well too but I want to have a combo box filled with Book columns like title, author etc where I want to select a column and search only within them.

I already have a class called BookComboBoxModel that returns books (code below) but I want the book columns from that table and not the Book.toString() method on comboBox

//this is my book combo model that returns books into combobox

public class BookComboBoxModel extends AbstractListModel<Book> implements ComboBoxModel<Book> {

    private List <Book> data;
    private Book selectedItem;


    public BookComboBoxModel(List<Book> data) {
        this.data = data;
    }

    public BookComboBoxModel() {
    }

    public void add(List<Book> data) {
        this.data = data;
    }

    @Override
    public int getSize() {
        return data.size();
    }

    @Override
    public Book getElementAt(int index) {
        return data.get(index);
    }

    @Override
    public void setSelectedItem(Object anItem) {
        selectedItem = (Book) anItem;
    }

    @Override
    public Object getSelectedItem() {
        return selectedItem;
    }
}
2
  • Do you wish to make a JComboBox containing all titles, and another JComboBox containing all authors, and so on? Or do you want to make a single JComboBox, each of whose items is laid out in columns? Commented Jun 4, 2019 at 16:06
  • imgur.com/a/VPrDVDb I want something like this, containing all columns from the Book table. I already have one that lists all the books Commented Jun 4, 2019 at 16:11

2 Answers 2

0

You can create an array of objects (customers),and then pass it to the combobox like this: combo = new JComboBox(customers);

Take a look to the example:

import java.awt.BorderLayout;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Main extends JFrame {
  JLabel label;
  JComboBox combo;
  public static void main(String args[]) {
    new Main();
  }

  public Main() {
    label = new JLabel("Select a Customer");
    add(label, BorderLayout.NORTH);

    Customer customers[] = new Customer[6];
    customers[0] = new Customer("A", 1);
    customers[1] = new Customer("B", 6);
    customers[2] = new Customer("C", 2);
    customers[3] = new Customer("D", 3);
    customers[4] = new Customer("E", 4);
    customers[5] = new Customer("F", 5);

    combo = new JComboBox(customers);
    combo.addItemListener(e -> {
      Customer c = (Customer) e.getItem();
      label.setText("You selected customer id: " + c.getId());
    });
    JPanel panel = new JPanel();
    panel.add(combo);
    add(panel, BorderLayout.CENTER);

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setSize(400, 200);
    setVisible(true);
  }
}

class Customer {
  private String name;
  private int id;

  public Customer(String name, int id) {
    this.name = name;
    this.id = id;
  }

  public String toString() {
    return getName();
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public int getId() {
    return id;
  }

  public void setId(int id) {
    this.id = id;
  }
}
Sign up to request clarification or add additional context in comments.

2 Comments

the class I have returns me a list of books (or customers) but I want it to return only the columns like for example name and id in the combobox and not the customers list
Okey, so take a look here: stackoverflow.com/questions/19094845/…
0

Based on comments, it is evident that what you want is not a model of Book objects, but rather a model containing the attributes of the Book class.

A good approach is to create a small custom object to serve as a JComboBox item:

public class BookAttribute {
    private final String name;
    private final int columnNumber;

    public BookAttribute(String name,
                         int columnNumber) {

        this.name = Objects.requireNonNull(name, "Name cannot be null");
        this.columnNumber = columnNumber;
    }

    public String getName() {
        return name;
    }

    public int getColumnNumber() {
        return columnNumber;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof BookAttribute) {
            return this.columnNumber == ((BookAttribute) obj).columnNumber;
        }
        return false;
    }

    @Override
    public int hashCode() {
        return Integer.hashCode(columnNumber);
    }

    @Override
    public String toString() {
        return name;
    }
}

With that class, you don’t need a custom model. You can simply pass the instances directly to a standard JComboBox constructor:

TableModel model = table.getModel();

int count = model.getColumnCount();
Vector<BookAttribute> fields = new Vector<>(count);
for (int col = 0; col < count; col++) {
    fields.add(new BookAttribute(model.getColumnName(col), col));
}

JComboBox<BookAttribute> fieldList = new JComboBox<>(fields);

To make use of it, you’d add a filter to your table’s RowSorter:

table.setAutoCreateRowSorter(true);

ActionListener filterUpdater = e -> {
    String searchText = searchField.getText();

    BookAttribute bookAttribute =
        (BookAttribute) fieldList.getSelectedItem();
    int columnNumber = bookAttribute.getColumnNumber();

    TableRowSorter<? extends TableModel> sorter =
        (TableRowSorter<? extends TableModel>) table.getRowSorter();

    sorter.setRowFilter(new RowFilter<TableModel, Integer>() {
        @Override
        public boolean include(
            Entry<? extends TableModel, ? extends Integer> entry) {

            return entry.getStringValue(columnNumber).contains(searchText);
        }
    });
};

searchField.addActionListener(filterUpdater);
fieldList.addActionListener(filterUpdater);

(You could use reflection for this, but you shouldn’t. Reflection is unreliable and error-prone, because it cannot be checked for correctness by the compiler. It also cannot be optimized by the Java runtime, usually.)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.