为什么我的 table 中的每个 JCombobox 都显示相同的值列表?
Why is every JCombo box in my table is showing the same list of values?
两行中仅显示最新的组合框值。
更新的 MVCE 示例:
package main;
import java.awt.Color;
import java.awt.Font;
import java.util.ArrayList;
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;
public class SwingDemo {
public static void main(String[] argv) throws Exception {
DefaultTableModel model = new DefaultTableModel();
model.addColumn("Column 1");
JTable table = new JTable(model);
Font font = new Font("Verdana", Font.PLAIN, 12);
table.setFont(font);
table.setRowHeight(30);
table.setBackground(Color.orange);
table.setForeground(Color.white);
JFrame frame = new JFrame();
frame.setSize(600, 400);
frame.add(new JScrollPane(table));
frame.setVisible(true);
//add 1st row
model.addRow("".split(""));
TableColumn testColumn1stRow = table.getColumnModel().getColumn(0);
JComboBox<String> comboBoxTest = new JComboBox<String>();
ArrayList<String> testArray = new ArrayList<String>();
testArray.add("one");
testArray.add("two");
testArray.add("three");
for (int i = 0; i < testArray.size(); i++) {
comboBoxTest.addItem(testArray.get(i));
}
testColumn1stRow.setCellEditor(new DefaultCellEditor(comboBoxTest));
//add 2nd row
model.addRow("".split(""));
TableColumn testColumn2ndRow = table.getColumnModel().getColumn(0);
JComboBox<String> comboBoxTest2 = new JComboBox<String>();
ArrayList<String> testArray2 = new ArrayList<String>();
testArray2.add("four");
testArray2.add("five");
testArray2.add("six");
for (int i = 0; i < testArray2.size(); i++) {
comboBoxTest2.addItem(testArray2.get(i));
}
testColumn2ndRow.setCellEditor(new DefaultCellEditor(comboBoxTest2));
}
}
基本上每次我添加一行时,它都会运行这段代码,然后列中的每一行都具有最近添加的组合框的值。
关于如何解决这个问题的任何想法?
我认为存在一个误解:JTable
没有针对每一行和每一列的 TableColumn
个对象 - 它只有 TableColumn
个针对列的对象。
这意味着
TableColumn testColumn1stRow = table.getColumnModel().getColumn(0);
// [...]
TableColumn testColumn2ndRow = table.getColumnModel().getColumn(0);
变量 testColumn1stRow
和 testColumn2ndRow
引用相同的 TableColumn
对象(第一列的对象。)
如果您需要不同的 JComboBox
es 作为不同行的单元格编辑器,您必须创建自己的 JTable
子类并覆盖 public TableCellEditor getCellEditor(int row, int column)
:
public class MyTable extends JTable {
// [...]
@Override
public TableCellEditor getCellEditor(int row, int column) {
if (column == 0) {
List<String> values = getValuesForRow(row);
JComboBox<String> comboBoxTest = new JComboBox<String>();
for (int i = 0; i < testArray.size(); i++) {
comboBoxTest.addItem(testArray.get(i));
}
return new DefaultCellEditor(comboBoxTest);
} else {
return super.getCellEditor(row, column);
}
}
// [...]
}
我发明了一种方法 List<String> getValuesForRow(int row)
来为一行填写可能的值,只是为了使示例简短。
两行中仅显示最新的组合框值。
更新的 MVCE 示例:
package main;
import java.awt.Color;
import java.awt.Font;
import java.util.ArrayList;
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;
public class SwingDemo {
public static void main(String[] argv) throws Exception {
DefaultTableModel model = new DefaultTableModel();
model.addColumn("Column 1");
JTable table = new JTable(model);
Font font = new Font("Verdana", Font.PLAIN, 12);
table.setFont(font);
table.setRowHeight(30);
table.setBackground(Color.orange);
table.setForeground(Color.white);
JFrame frame = new JFrame();
frame.setSize(600, 400);
frame.add(new JScrollPane(table));
frame.setVisible(true);
//add 1st row
model.addRow("".split(""));
TableColumn testColumn1stRow = table.getColumnModel().getColumn(0);
JComboBox<String> comboBoxTest = new JComboBox<String>();
ArrayList<String> testArray = new ArrayList<String>();
testArray.add("one");
testArray.add("two");
testArray.add("three");
for (int i = 0; i < testArray.size(); i++) {
comboBoxTest.addItem(testArray.get(i));
}
testColumn1stRow.setCellEditor(new DefaultCellEditor(comboBoxTest));
//add 2nd row
model.addRow("".split(""));
TableColumn testColumn2ndRow = table.getColumnModel().getColumn(0);
JComboBox<String> comboBoxTest2 = new JComboBox<String>();
ArrayList<String> testArray2 = new ArrayList<String>();
testArray2.add("four");
testArray2.add("five");
testArray2.add("six");
for (int i = 0; i < testArray2.size(); i++) {
comboBoxTest2.addItem(testArray2.get(i));
}
testColumn2ndRow.setCellEditor(new DefaultCellEditor(comboBoxTest2));
}
}
基本上每次我添加一行时,它都会运行这段代码,然后列中的每一行都具有最近添加的组合框的值。
关于如何解决这个问题的任何想法?
我认为存在一个误解:JTable
没有针对每一行和每一列的 TableColumn
个对象 - 它只有 TableColumn
个针对列的对象。
这意味着
TableColumn testColumn1stRow = table.getColumnModel().getColumn(0);
// [...]
TableColumn testColumn2ndRow = table.getColumnModel().getColumn(0);
变量 testColumn1stRow
和 testColumn2ndRow
引用相同的 TableColumn
对象(第一列的对象。)
如果您需要不同的 JComboBox
es 作为不同行的单元格编辑器,您必须创建自己的 JTable
子类并覆盖 public TableCellEditor getCellEditor(int row, int column)
:
public class MyTable extends JTable {
// [...]
@Override
public TableCellEditor getCellEditor(int row, int column) {
if (column == 0) {
List<String> values = getValuesForRow(row);
JComboBox<String> comboBoxTest = new JComboBox<String>();
for (int i = 0; i < testArray.size(); i++) {
comboBoxTest.addItem(testArray.get(i));
}
return new DefaultCellEditor(comboBoxTest);
} else {
return super.getCellEditor(row, column);
}
}
// [...]
}
我发明了一种方法 List<String> getValuesForRow(int row)
来为一行填写可能的值,只是为了使示例简短。