每行

时间:2017-05-24 15:36:10

标签: java swing jtable jcombobox

我有一张表,我在运行时加载了行。加载后,用户需要从第一列的JComboBox中为每一行选择一个项目。然后他需要在每行的同一行中从另一个JComboBox中选择一个项目。第二个JComboBox的内容取决于第一个JComboBox的选择。

我现在编码的方式是改变整个第二列的组合框内容。

columnProfile.setCellEditor(new DefaultCellEditor(comboBoxProf))

有没有办法让每一行的组合框对象都不同,所以每次在第一个组合框中选择一个值时我都可以使用它?

在用户点击提交之前,行数不固定。他可以添加和删除行。

我使用了Oracle的基本表示例并进行了更改以反映我当前正在做的事情

import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;


import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;


public class TableRenderDemo extends JPanel {
    private boolean DEBUG = false;
    JComboBox comboBox2;
    JComboBox comboBox1;
    public TableRenderDemo() {
        super(new GridLayout(1,0));

        JTable table = new JTable(new MyTableModel());
        table.setPreferredScrollableViewportSize(new Dimension(500, 70));
        table.setFillsViewportHeight(true);
        JScrollPane scrollPane = new JScrollPane(table);
        initColumnSizes(table);

        setUpSportColumn(table, table.getColumnModel().getColumn(2));
        setUpYearsColumn(table, table.getColumnModel().getColumn(3));

        add(scrollPane);
        table.getModel().addTableModelListener(new TableModelListener() {

            public void tableChanged(TableModelEvent e) {

                if (e.getColumn() == 2){
                    comboBox2.removeAllItems();
                    /*REFILL COMBOBOX WITH WHAT I NEED FOR THIS ROW ONLY*/
                }


            }
                  }); 
    }

    private void initColumnSizes(JTable table) {
        MyTableModel model = (MyTableModel)table.getModel();
        TableColumn column = null;
        Component comp = null;
        int headerWidth = 0;
        int cellWidth = 0;
        Object[] longValues = model.longValues;
        TableCellRenderer headerRenderer =
            table.getTableHeader().getDefaultRenderer();

        for (int i = 0; i < 5; i++) {
            column = table.getColumnModel().getColumn(i);

            comp = headerRenderer.getTableCellRendererComponent(
                                 null, column.getHeaderValue(),
                                 false, false, 0, 0);
            headerWidth = comp.getPreferredSize().width;

            comp = table.getDefaultRenderer(model.getColumnClass(i)).
                             getTableCellRendererComponent(
                                 table, longValues[i],
                                 false, false, 0, i);
            cellWidth = comp.getPreferredSize().width;

            if (DEBUG) {
                System.out.println("Initializing width of column "
                                   + i + ". "
                                   + "headerWidth = " + headerWidth
                                   + "; cellWidth = " + cellWidth);
            }

            column.setPreferredWidth(Math.max(headerWidth, cellWidth));
        }
    }

    public void setUpSportColumn(JTable table,
                                 TableColumn sportColumn) {
        //Set up the editor for the sport cells.
        comboBox1 = new JComboBox();
        comboBox1.addItem("Snowboarding");
        comboBox1.addItem("Rowing");
        comboBox1.addItem("Knitting");
        comboBox1.addItem("Speed reading");
        comboBox1.addItem("Pool");
        comboBox1.addItem("None of the above");
        sportColumn.setCellEditor(new DefaultCellEditor(comboBox1));


        DefaultTableCellRenderer renderer =
                new DefaultTableCellRenderer();
        renderer.setToolTipText("Click for combo box");
        sportColumn.setCellRenderer(renderer);
    }
    public void setUpYearsColumn(JTable table,
            TableColumn yearColumn) {

comboBox2 = new JComboBox();
comboBox2.addItem("1");
comboBox2.addItem("2");
comboBox2.addItem("3");
comboBox2.addItem("4");
comboBox2.addItem("5");
comboBox2.addItem("6");
yearColumn.setCellEditor(new DefaultCellEditor(comboBox2));

//Set up tool tips for the sport cells.
DefaultTableCellRenderer renderer =
new DefaultTableCellRenderer();
renderer.setToolTipText("Click for combo box");
yearColumn.setCellRenderer(renderer);
}

    class MyTableModel extends AbstractTableModel {
        private String[] columnNames = {"First Name",
                                        "Last Name",
                                        "Sport",
                                        "# of Years",
                                        "Vegetarian"};
        private Object[][] data = {
        {"Kathy", "Smith",
         "Snowboarding", "1", new Boolean(false)},
        {"John", "Doe",
         "Rowing", "1", new Boolean(true)},
        {"Sue", "Black",
         "Knitting", "1", new Boolean(false)},
        {"Jane", "White",
         "Speed reading", "1", new Boolean(true)},
        {"Joe", "Brown",
         "Pool", "1", new Boolean(false)}
        };

        public final Object[] longValues = {"Jane", "Kathy",
                                            "None of the above",
                                            new Integer(20), Boolean.TRUE};

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

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

        public String getColumnName(int col) {
            return columnNames[col];
        }

        public Object getValueAt(int row, int col) {
            return data[row][col];
        }


        public Class getColumnClass(int c) {
            return getValueAt(0, c).getClass();
        }


        public boolean isCellEditable(int row, int col) {

            if (col < 2) {
                return false;
            } else {
                return true;
            }
        }


        public void setValueAt(Object value, int row, int col) {
            if (DEBUG) {
                System.out.println("Setting value at " + row + "," + col
                                   + " to " + value
                                   + " (an instance of "
                                   + value.getClass() + ")");
            }

            data[row][col] = value;
            fireTableCellUpdated(row, col);

            if (DEBUG) {
                System.out.println("New value of data:");
                printDebugData();
            }
        }

        private void printDebugData() {
            int numRows = getRowCount();
            int numCols = getColumnCount();

            for (int i=0; i < numRows; i++) {
                System.out.print("    row " + i + ":");
                for (int j=0; j < numCols; j++) {
                    System.out.print("  " + data[i][j]);
                }
                System.out.println();
            }
            System.out.println("--------------------------");
        }
    }


    private static void createAndShowGUI() {
        //Create and set up the window.
        JFrame frame = new JFrame("TableRenderDemo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


        TableRenderDemo newContentPane = new TableRenderDemo();
        newContentPane.setOpaque(true); 
        frame.setContentPane(newContentPane);

        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {

        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}

1 个答案:

答案 0 :(得分:2)

假设您的数据保存在Map<String, List<String>>中,地图的键代表第一个JComboBox所持有的值,而地图的值代表第二列所拥有的变化值& #39; s JComboBox(数据不需要以这种方式设置,但它很容易用于MCVE /演示目的),并调用此地图dataMap,然后您的列编辑器可能看起来像:

    column1.setCellEditor(new DefaultCellEditor(combo1) {
        @SuppressWarnings("unchecked")
        @Override
        public Component getTableCellEditorComponent(JTable table, Object value,
                boolean isSelected, int row, int column) {

            // the items that will fill our JComboBox. Initially its empty
            Object[] items = new Object[]{};

            // get the value in the column to the left
            Object column0Value = table.getValueAt(row, column - 1);
            if (column0Value != null) {
                // if the value is not null, then get the map's values
                // and use it to fill our items array
                items = dataMap.get(column0Value).toArray();
            } 

            // get the super component, the JComboBox that is being used
            // as an editor:
            JComboBox<Object> superCombo = (JComboBox<Object>) super.getTableCellEditorComponent(table, value, isSelected,
                    row, column);

            // create a model and fill with items
            DefaultComboBoxModel<Object> comboModel = new DefaultComboBoxModel<>(items);

            // set the cell editor's model and return
            superCombo.setModel(comboModel);
            return superCombo;
        }
    });

例如,请将此MCVE作为使用上述单元格编辑器的示例进行检查,并将其作为MCVE的示例,以便在将来的问题中使用得很好

import java.awt.Component;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;

@SuppressWarnings("serial")
public class TableWithMultCombos extends JPanel {
    private static final String[] COLUMN_NAMES = { "Day of Week", "Number" };
    private Map<String, List<String>> dataMap = new LinkedHashMap<>();
    private DefaultTableModel tblModel = new DefaultTableModel(COLUMN_NAMES, 5);
    private JTable table = new JTable(tblModel);
    private DefaultComboBoxModel<Object> combo2Model = new DefaultComboBoxModel<>();
    private JComboBox<Object> combo0 = null;
    private JComboBox<Object> combo1 = new JComboBox<>(combo2Model);

    public TableWithMultCombos() {
        dataMap.put("Monday", Arrays.asList(new String[] { "Mon - 1", "Mon - 2", "Mon - 3", "Mon - 4" }));
        dataMap.put("Tuesday", Arrays.asList(new String[] { "Tues - 1", "Tues - 2", "Tues - 3", "Tues - 4" }));
        dataMap.put("Wednesday", Arrays.asList(new String[] { "Wed - 1", "Wed - 2", "Wed - 3", "Wed - 4" }));
        dataMap.put("Thursday", Arrays.asList(new String[] { "Thurs - 1", "Thurs - 2", "Thurs - 3", "Thurs - 4" }));
        dataMap.put("Friday", Arrays.asList(new String[] { "Fri - 1", "Fri - 2", "Fri - 3", "Fri - 4" }));
        combo0 = new JComboBox<>(dataMap.keySet().toArray());

        TableColumn column0 = table.getColumnModel().getColumn(0);
        column0.setCellEditor(new DefaultCellEditor(combo0));

        TableColumn column1 = table.getColumnModel().getColumn(1);
        column1.setCellEditor(new DefaultCellEditor(combo1) {
            @SuppressWarnings("unchecked")
            @Override
            public Component getTableCellEditorComponent(JTable table, Object value,
                    boolean isSelected, int row, int column) {

                // the items that will fill our JComboBox. Initially its empty
                Object[] items = new Object[]{};

                // get the value in the column to the left
                Object column0Value = table.getValueAt(row, column - 1);
                if (column0Value != null) {
                    // if the value is not null, then get the map's values
                    // and use it to fill our items array
                    items = dataMap.get(column0Value).toArray();
                } 

                // get the super component, the JComboBox that is being used
                // as an editor:
                JComboBox<Object> superCombo = (JComboBox<Object>) super.getTableCellEditorComponent(table, value, isSelected,
                        row, column);

                // create a model and fill with items
                DefaultComboBoxModel<Object> comboModel = new DefaultComboBoxModel<>(items);

                // set the cell editor's model and return
                superCombo.setModel(comboModel);
                return superCombo;
            }
        });

        table.setFillsViewportHeight(true);
        add(new JScrollPane(table));
    }

    private static void createAndShowGui() {
        TableWithMultCombos mainPanel = new TableWithMultCombos();

        JFrame frame = new JFrame("TableWithMultCombos");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}