2016-10-12 145 views
1

我有一個JTable,我將三個JComboBoxes添加到三個不同的列。 現在我想爲每一行設置選定的項目。問題是,我需要每行的ID來做到這一點。 所以我嘗試了不同的聽衆,最好的結果來了一個FocusListener,但是我總是先點擊行,然後點擊JComboBox,這很費力。 下面是一個例子:JTable中JCombobox的setSelectedItem

JTable table = new JTable(); 
    Vector<ArrayList<Object>> data = new Vector<ArrayList<Object>>(); 
    for (int i = 0; i < 5; i++) 
    { 
     ArrayList<Object> object = new ArrayList<Object>(); 
     object.add(i); 
     object.add("name"); 
     object.add(i+1); 
     object.add(i+1); 
     object.add(i+1); 
     data.add(object); 
    } 
    DefaultTableModel tableModel = new DefaultTableModel() { 
     /** 
     * 
     */ 
     private static final long serialVersionUID = 1L; 

     @Override 
     public boolean isCellEditable(int row, int column) { 
      if (column < 2) 
       return false; 
      return true; 
     } 
    }; 
    tableModel.setColumnIdentifiers(new String[] {"ID", "Name", "OK", "Other", "Error"}); 
    tableModel.addTableModelListener(new TableModelListener() 
    { 

     @Override 
     public void tableChanged(TableModelEvent e) 
     { 
      if (e.getType() == TableModelEvent.UPDATE) 
      { 
       int row = e.getFirstRow(); 
       int column = e.getColumn(); 
       TableModel table_model = (TableModel) e.getSource(); 
       ArrayList<Object> changed_data = (ArrayList<Object>) table_model.getValueAt(row, column); 
       String row_id = String.valueOf(table_model.getValueAt(row, 0)); 
       for (ArrayList<Object> list : data) 
       { 
        String compare_id = String.valueOf(list.get(0)); 
        if (row_id.equals(compare_id)) 
        { 
         list.set(column, String.valueOf(changed_data.get(0))); 
         for (int i = table_model.getRowCount()-1; i >= 0 ; i--) 
         { 
          tableModel.removeRow(i); 
         } 

         for (ArrayList<Object> object : data) 
         { 
          Vector<String> vector = new Vector<String>(); 
          vector.addElement(String.valueOf(object.get(0))); 
          vector.addElement(String.valueOf(object.get(1))); 
          vector.addElement(String.valueOf(object.get(2))); 
          vector.addElement(String.valueOf(object.get(3))); 
          vector.addElement(String.valueOf(object.get(4))); 
          tableModel.addRow(vector); 
         } 

         TableColumn column_ok = table.getColumnModel().getColumn(2); 
         TableColumn column_other = table.getColumnModel().getColumn(3); 
         TableColumn column_error = table.getColumnModel().getColumn(4); 

         JComboBox<ArrayList<Object>> combobox_ok = new JComboBox<ArrayList<Object>>(data); 
         JComboBox<ArrayList<Object>> combobox_other = new JComboBox<ArrayList<Object>>(data); 
         JComboBox<ArrayList<Object>> combobox_error = new JComboBox<ArrayList<Object>>(data); 

         column_ok.setCellEditor(new DefaultCellEditor(combobox_ok)); 
         column_other.setCellEditor(new DefaultCellEditor(combobox_other)); 
         column_error.setCellEditor(new DefaultCellEditor(combobox_error)); 
         break; 
        } 
       } 
      } 
     } 
    }); 
    table.setModel(tableModel); 
    for (ArrayList<Object> object : data) 
    { 
     Vector<String> vector = new Vector<String>(); 
     vector.addElement(String.valueOf(object.get(0))); 
     vector.addElement(String.valueOf(object.get(1))); 
     vector.addElement(String.valueOf(object.get(2))); 
     vector.addElement(String.valueOf(object.get(3))); 
     vector.addElement(String.valueOf(object.get(4))); 
     tableModel.addRow(vector); 
    } 

    TableColumn column_ok = table.getColumnModel().getColumn(2); 
    TableColumn column_other = table.getColumnModel().getColumn(3); 
    TableColumn column_error = table.getColumnModel().getColumn(4); 

    JComboBox<ArrayList<Object>> combobox_ok = new JComboBox<ArrayList<Object>>(data); 
    JComboBox<ArrayList<Object>> combobox_other = new JComboBox<ArrayList<Object>>(data); 
    JComboBox<ArrayList<Object>> combobox_error = new JComboBox<ArrayList<Object>>(data); 

    column_ok.setCellEditor(new DefaultCellEditor(combobox_ok)); 
    column_other.setCellEditor(new DefaultCellEditor(combobox_other)); 
    column_error.setCellEditor(new DefaultCellEditor(combobox_error)); 

    JScrollPane scrollPane = new JScrollPane(); 
    scrollPane.getViewport().add(table); 

    JFrame frame = new JFrame(); 
    frame.add(scrollPane); 
    frame.setSize(400, 200); 
    frame.setVisible(true); 

現在,在第一行,第三列(「OK」),你可以在其中表示連續的JComboBox不同的條目中選擇。所以一行有三個引用另一行的JComboBoxes。 如果您在這樣的JComboBox中單擊,您會注意到它總是選擇第一個條目,而不是單擊它之前所看到的數字。

也許現在你明白我想要做什麼了?

+1

爲了更好地幫助越早,張貼[MCVE]或[簡要,獨立的,正確的示例](http://www.sscce.org/)。 –

+0

請儘可能詳細地說明什麼地方以及如何出錯,以及期望的效果。我不能用這種形式來解釋你的問題。 –

+0

我會在編寫示例時更新問題。 – mavok

回答

2

如果你在這樣一個JComboBox點擊,你會發現它總是選擇第一項,並不會與你點擊它之前看到的數量的條目。

着眼於該問題的這個方面,下面的簡化,完整的例子始終顯示所選定的條目時該單元的編輯器是活動的。您可以根據需要替換組合的default renderer以顯示不同的結果。另外,

  • 重寫getPreferredScrollableViewportSize()以建立所需的表的大小。

  • 儘可能使用類型參數;根據需要覆蓋getColumnClass(),對於example

  • 替代getValueAt(),如圖所示herehere,用於從屬數據。

  • 請注意下面的isCellEditable()的簡化實現。

image

import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.util.Arrays; 
import java.util.Vector; 
import javax.swing.DefaultCellEditor; 
import javax.swing.JComboBox; 
import javax.swing.JFrame; 
import javax.swing.JScrollPane; 
import javax.swing.JTable; 
import javax.swing.table.DefaultTableModel; 
import javax.swing.table.TableColumn; 

/** 
* @see https://stackoverflow.com/q/39993746/230513 
*/ 
public class TableComboTest { 

    private Vector<Vector<String>> createData() { 
     Vector<Vector<String>> data = new Vector<Vector<String>>(); 
     for (int i = 0; i < 5; i++) { 
      Vector<String> rowVector = new Vector<String>(); 
      rowVector.add(String.valueOf(i)); 
      rowVector.add("name"); 
      rowVector.add(String.valueOf(i + 1)); 
      rowVector.add(String.valueOf(i + 1)); 
      rowVector.add(String.valueOf(i + 1)); 
      data.add(rowVector); 
     } 
     return data; 
    } 

    private void display() { 
     Vector<Vector<String>> data = createData(); 
     Vector<String> names = new Vector<>(Arrays.asList("ID", "Name", "OK", "Other", "Error")); 
     DefaultTableModel tableModel = new DefaultTableModel(data, names) { 

      @Override 
      public boolean isCellEditable(int row, int column) { 
       return column > 1; 
      } 
     }; 
     JTable table = new JTable(tableModel) { 
      @Override 
      public Dimension getPreferredScrollableViewportSize() { 
       return new Dimension(getPreferredSize().width, getRowHeight() * 4); 
      } 
     }; 

     TableColumn column_ok = table.getColumnModel().getColumn(2); 
     TableColumn column_other = table.getColumnModel().getColumn(3); 
     TableColumn column_error = table.getColumnModel().getColumn(4); 

     String[] choices = new String[]{"1", "2", "3", "4", "5"}; 
     JComboBox<String> combobox_ok = new JComboBox<>(choices); 
     JComboBox<String> combobox_other = new JComboBox<String>(choices); 
     JComboBox<String> combobox_error = new JComboBox<String>(choices); 

     column_ok.setCellEditor(new DefaultCellEditor(combobox_ok)); 
     column_other.setCellEditor(new DefaultCellEditor(combobox_other)); 
     column_error.setCellEditor(new DefaultCellEditor(combobox_error)); 

     JFrame frame = new JFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(new JScrollPane(table)); 
     frame.pack(); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new TableComboTest()::display); 
    } 
} 
+0

非常感謝! – mavok

+0

不客氣;很高興它有幫助。 – trashgod