如何在JTable中正确实现JComboBox?

时间:2014-12-14 01:29:32

标签: java swing jtable jcombobox

我唯一想要的是使用JComboBox正确实现我的Jtable的第六列。当我单击该字段时,组合框突然出现,但是没有单击我将JComponent引用作为String。 我定义了一个自己的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

1 个答案:

答案 0 :(得分:2)

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

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

然后你可以使用该值。

setText(value);

我也注意到你打电话了

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

在getTableCellRendererComponent()中。 不要这样做,它会一次又一次地调用getTableCellRendererComponent()本身,它会使堆栈溢出。

我也对模型进行了一些更改。它有一些像@ getRowCount()&#34;返回数据[0] .length - 1;&#34; (列数返回而不是行数)必须是&#34;返回data.length;&#34;

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