Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JTable, JComboBox using custom Objects

Hi if You put JComboBox in JTable and String[] array to JComboBox everything works fine. Buf if You put your own data type to JComboBox selecting values in same column becomes complicated. Here is official example. Try changing following part:

JComboBox comboBox = new JComboBox();
comboBox.addItem("Snowboarding");
comboBox.addItem("Rowing");
comboBox.addItem("Knitting");
comboBox.addItem("Speed reading");
comboBox.addItem("Pool");
comboBox.addItem("None of the above");
sportColumn.setCellEditor(new DefaultCellEditor(comboBox));

Into:

JComboBox comboBox = new JComboBox();
comboBox.addItem(new Test("Snowboarding"));
comboBox.addItem(new Test("Rowing"));
comboBox.addItem(new Test("Knitting"));
comboBox.addItem(new Test("Speed reading"));
comboBox.addItem(new Test("Pool"));
comboBox.addItem(new Test("None of the above"));
sportColumn.setCellEditor(new DefaultCellEditor(comboBox));

And create new data type:

public class Test {
    private String name;

    public Test(String name) {
        this.name = name;
    }

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

You will see, that when you click on table cell in witch there is JComboBox with custom data type. First column cell's value get's selected automaticlly. How to fix this issue?

EDIT 1: I added SSCCE.

Main Class:

import java.awt.BorderLayout;

public class windw extends JFrame {

    private JPanel contentPane;
    private JTable table;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    windw frame = new windw();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public windw() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();

        contentPane.setLayout(new BorderLayout(0, 0));
        setContentPane(contentPane);

        table = new JTable();
        String[] grupes2 = new String[3];
        grupes2[0] = "first";
        grupes2[1] = "second";
        grupes2[2] = "third";

        table.setModel(new DefaultTableModel(
            new Object[][] {
                {new JComboBox<String>(grupes2)},
                {new JComboBox<String>(grupes2)},
                {new JComboBox<String>(grupes2)},
                {new JComboBox<String>(grupes2)},
                {new JComboBox<String>(grupes2)},
                {new JComboBox<String>(grupes2)},
                {new JComboBox<String>(grupes2)},
            },
            new String[] {
                "Column name"
            }
        ));
        TableColumn sportColumn = table.getColumnModel().getColumn(0);
        sportColumn.setCellEditor(new DefaultCellEditor(new JComboBox<String>(grupes2)));
        sportColumn.setCellRenderer(new Renderer(grupes2));
        contentPane.add(table, BorderLayout.CENTER);
    }

}

Renderer:

import java.awt.Component;

import javax.swing.JComboBox;
import javax.swing.JTable;
import javax.swing.table.TableCellRenderer;

public class Renderer extends JComboBox implements TableCellRenderer {
    public Renderer(String[] items) {
        super(items);
    }

    public Component getTableCellRendererComponent(JTable table, Object value,
            boolean isSelected, boolean hasFocus, int row, int column) {
        if (isSelected) {
            setForeground(table.getSelectionForeground());
            super.setBackground(table.getSelectionBackground());
        } else {
            setForeground(table.getForeground());
            setBackground(table.getBackground());
        }

        // Select the current value
        setSelectedItem(value);
        return this;
    }
}
like image 520
Minutis Avatar asked Jan 10 '12 14:01

Minutis


1 Answers

The problem is that your TableModel is storing a String object and the ComboBox contains a Test object. These objects are not equal so there is no item to select and it looks the first is automatically highlighted.

Change your code to the following and you will see the same problem with an unknown string:

{"Joe", "Brown", "Pool?????", new Integer(10), new Boolean(false)}

To fix the problem, I would guess you need to do the following:

{"Joe", "Brown", new Test("Pool"), new Integer(10), new Boolean(false)}

You would then need to implement the equals() method in your Test class to compare the name property of both components. As well, you would need to implement the hashcode() method.

In the future, as Andrew suggested, include your SSCCE with your question as we don't have time to copy/paste/edit and test code because we never know if we do it exactly the same way you do.

like image 76
camickr Avatar answered Sep 28 '22 03:09

camickr