使用自定义对象的 JTable、JComboBox

发布于 2024-12-26 03:01:01 字数 3959 浏览 3 评论 0原文

您好,如果您将 JComboBox 放入 JTable 中并将 String[] 数组放入 JComboBox 中,则一切正常。如果您将自己的数据类型放入 JComboBox,则在同一列中选择值会变得很复杂。这是官方示例。尝试将以下部分更改

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));

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));

:并创建新的数据类型:

public class Test {
    private String name;

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

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

您将看到,当您单击表格单元格时,会出现具有自定义数据类型的 JComboBox。自动选择第一列单元格的值。如何解决这个问题?

编辑1:我添加了SSCCE。

主类:

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);
    }

}

渲染器:

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;
    }
}

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;
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

纸短情长 2025-01-02 03:01:01

问题是您的 TableModel 正在存储一个 String 对象,而 ComboBox 包含一个 Test 对象。这些对象不相等,因此没有可供选择的项目,并且看起来第一个会自动突出显示。

将您的代码更改为以下内容,您将看到未知字符串的相同问题:

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

要解决该问题,我猜您需要执行以下操作:

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

然后您需要在 Test 类中实现 equals() 方法进行比较两个组件的名称属性。此外,您还需要实现 hashcode() 方法。

将来,正如 Andrew 建议的那样,将您的 SSCCE 包含在您的问题中,因为我们没有时间复制/粘贴/编辑和测试代码,因为我们永远不知道我们是否按照您的方式进行操作。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文