java - 如何在 JTable 中正确实现 JComboBox?

标签 java swing jtable jcombobox

我只想用 JComboBox 正确实现 Jtable 的第六列。当我单击该字段时,组合框突然出现,但如果不单击,我就会将 JComponent 引用作为字符串。 我定义了自己的 tableModel 和 tableCellrenderer。

这是我的代码:

package examples;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.util.EventObject;

import javax.swing.DefaultCellEditor;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.CellEditorListener;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableModel;

public class MyTableExample2 {
    public static void main(String[] args) {

        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {

                try {
                    UIManager.setLookAndFeel(UIManager
                            .getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException
                        | IllegalAccessException
                        | UnsupportedLookAndFeelException e) {
                    e.printStackTrace();
                }

                @SuppressWarnings("unused")
                JFrame frame = new MyFrame();
            }
        });

    }
}

class MyFrame extends JFrame {

    private static final long serialVersionUID = 1L;
    private JComboBox<String> comboBox = new JComboBox<String>(new String[] {
            "Me", "You", "They" });
    private String[] columnNames = { "First Name", "Last Name", "Sport",
            "# of Years", "Vegetarian", "ComboBox" };
    private Object[][] data = {
            { "Kathy", "Smith", "Snowboarding", new Integer(5),
                    new Boolean(true), comboBox },
            { "John", "Doe", "Rowing", new Integer(3), new Boolean(true),
                    comboBox },
            { "Sue", "Black", "Knitting", new Integer(2), new Boolean(false),
                    comboBox },
            { "Jane", "White", "Speed reading", new Integer(20),
                    new Boolean(true), comboBox },
            { "Joe", "Brown", "Pool", new Integer(10), new Boolean(false),
                    comboBox } };

    private JTable jTable = new JTable(new MyTableModel());
    private JScrollPane scrollPane = new JScrollPane(jTable);
    private Font font = getContentPane().getFont().deriveFont(Font.BOLD, 15);

    private class MyTableCellRenderer extends JLabel implements
            TableCellRenderer {

        private static final long serialVersionUID = 1L;

        public MyTableCellRenderer() {
            setOpaque(true);
            setLayout(new BorderLayout());
        }

        @Override
        public Component getTableCellRendererComponent(JTable table,
                Object value, boolean isSelected, boolean hasFocus, int row,
                int column) {
            Font font = getFont().deriveFont(Font.BOLD, 15);
            table.setRowHeight((int) getPreferredSize().getHeight() + 5);

            if ((row % 2) == 0) {
                setBackground(new Color(224, 255, 255));
            } else {
                setBackground(new Color(135, 206, 250));
            }

            if (isSelected) {
                setBackground(new Color(0, 0, 255));
            }

            setForeground(Color.BLACK);
            setText(value.toString());
            setFont(font);

            return this;
        }

    }

    private TableCellRenderer tableCellRend = new MyTableCellRenderer();

    public MyFrame() {
        super("JTable");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        jTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);

        jTable.setColumnSelectionAllowed(false);
        jTable.setRowSelectionAllowed(true);
        jTable.setFillsViewportHeight(true);
        jTable.setFont(font);
        jTable.setRowHeight(20);
        jTable.setGridColor(new Color(100, 149, 237));
        jTable.getColumnModel().getColumn(5)
                .setCellEditor(new DefaultCellEditor(comboBox));
         jTable.setDefaultRenderer(Object.class, tableCellRend);
         jTable.setAutoCreateRowSorter(true); 

        getContentPane().add(scrollPane);

        pack();
        centerWindow();
        setVisible(true);

    }

    private class MyTableModel implements TableModel {

        @Override
        public void addTableModelListener(TableModelListener l) {
        }

        @Override
        public Class<?> getColumnClass(int columnIndex) {

            switch (columnIndex) {
            case 0:
                return String.class;
            case 1:
                return String.class;
            case 2:
                return String.class;
            case 3:
                return Object.class;
            case 4:
                return Object.class;
            case 5:
                return String.class;
            default:
                return null;
            }

        }

        @Override
        public int getColumnCount() {
            return columnNames.length;
        }

        @Override
        public String getColumnName(int columnIndex) {
            switch (columnIndex) {
            case 0:
                return columnNames[0];
            case 1:
                return columnNames[1];
            case 2:
                return columnNames[2];
            case 3:
                return columnNames[3];
            case 4:
                return columnNames[4];
            case 5:
                return columnNames[5];
            default:
                return null;
            }
        }

        @Override
        public int getRowCount() {
            return data[0].length - 1;
        }

        @Override
        public Object getValueAt(int rowIndex, int columnIndex) {
            return data[rowIndex][columnIndex];
        }

        @Override
        public boolean isCellEditable(int rowIndex, int columnIndex) {
            switch (columnIndex) {
            case 5:
                return true;
            default:
                return false;
            }

        }

        @Override
        public void removeTableModelListener(TableModelListener l) {
        }

        @Override
        public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
            data[rowIndex][columnIndex] = aValue;
        }

    }

    public void centerWindow() {
        Dimension dimension = getToolkit().getScreenSize();
        setLocation(((int) dimension.getWidth()) / 2 - (getWidth() / 2),
                ((int) dimension.getHeight()) / 2 - (getHeight() / 2));
    }

}

这是点击之前的结果:

enter image description here

最佳答案

在调用 Object.toString() 之前,必须过滤对象类型并捕获 String 值; 因为 Object.toString() 方法返回有关对象的详细信息,除非它是字符串。

value = value instanceof JComboBox ? ((JComboBox) value).getSelectedItem().toString() : value.toString();

然后您就可以使用该值。

setText(value);

我还注意到你打电话

 table.setRowHeight((int) getPreferredSize().getHeight() + 5);

在 getTableCellRendererComponent() 内。 不要这样做,它会一次又一次地调用 getTableCellRendererComponent() 本身,并且会导致堆栈溢出。

我还对模型做了一些更改。它有一些错误,例如 @ getRowCount()“return data[0].length - 1;” (返回列数而不是行数)必须是“return data.length;”

 @Override
        public Class<?> getColumnClass(int columnIndex) {
            Object value = this.getValueAt(0, columnIndex);
            return (value == null ? Object.class : value.getClass());
        }

        @Override
        public int getColumnCount() {
            return columnNames.length;
        }

        @Override
        public String getColumnName(int columnIndex) {
            return columnNames[columnIndex];
        }

        @Override
        public int getRowCount() {
            return data.length;
        }

关于java - 如何在 JTable 中正确实现 JComboBox?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27465466/

相关文章:

java - JTextPane 显示与 HTML 浏览器不同的颜色

java - Java 中的 jTable 编码

java - 更改 JTable 的背景颜色

java - 使用SwingWorker动态加载jTable中的大数据

java - 在 JavaFX 中同时按下按键

java - 如何检查日历/日期对象中的特定变量是否与java匹配?

java - 标记为 'standalone' 的语句是否有用途?

java - 如何消除动画过程中出现的闪烁?

java - 密码保护 XSSFWorkBook Apache POI

java - 更改关键事件的表条目