2017-05-24 84 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

非常感謝,我能夠運行此代碼,現在明白我需要做什麼。這真的很感激 –