2017-05-24 79 views
-2

我有一个表,我在运行时加载行。加载后,用户需要从每行的第一列中的JComboBox中选择一个项目。然后他需要在每一行的同一行上选择另一个JComboBox的项目。第二个JComboBox的内容取决于第一个JComboBox的选择。JTable与每个行不同的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(); 
      } 
     }); 
    } 
} 
+2

请在[MCVE]或发表您的最好的尝试[sscce](http://sscce.org)将您的代码压缩到最小的位置,小到足以将您的问题发布为代码格式的文本,仍然编译并运行,没有外部依赖关系(例如需要链接到数据库或图像),没有额外的代码与您的问题无关,但仍然表明您的问题。这会让人们更容易回答你的问题并帮助你解决问题。 –

+0

一个解决方案是让你的单元编辑器*扩展* DefaultCellEditor,覆盖'getTableCellEditorComponent(...)',并且改变这个编辑器保存的JComboBox的模型。有关更多详情,请再次向我们展示您的[mcve]。 –

+0

我已经添加了代码。谢谢! –

回答

2

说你有与地图的代表值的键一Map<String, List<String>>举行举行您的数据通过第一个JComboBox,以及Map的值代表第二列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()); 
    } 
} 
+0

非常感谢,我能够运行此代码,现在明白我需要做什么。这真的很感激 –