【发布时间】:2017-05-24 15:36:10
【问题描述】:
我有一个在运行时加载行的表。加载后,用户需要从每行第一列的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();
}
});
}
}
【问题讨论】:
-
请在minimal reproducible example 或sscce 上发布您的最佳尝试,在那里您将代码压缩成最小的位,小到足以将您的问题作为代码格式的文本发布,仍然可以编译和运行,没有外部依赖项(例如需要链接到数据库或图像),没有与您的问题无关的额外代码,但仍然可以演示您的问题。这将使人们更容易回答您的问题并帮助您解决问题。
-
一种解决方案是让您的单元格编辑器扩展 DefaultCellEditor,覆盖
getTableCellEditorComponent(...),并更改此编辑器拥有的JComboBox 的模型。欲了解更多详情,请再次向我们展示您的minimal reproducible example。 -
我已经添加了代码。谢谢!
-
请您的自己的代码,显示您尝试使用这两个组合框的代码。
-
那里可以看到,我有combobox1和combobox2。您可以运行此代码。我只是不愿意分享我的整个代码,因为我的工作不喜欢它。但是那里的东西代表了我想做的事情。查看行 /*REFILL COMBOBOX WITH WHAT I NEED FOR this ROW */
标签: java swing jtable jcombobox