我有一个在运行时加载行的表。加载后,用户需要在每一行的第一列中从JComboBox
中选择一个项目。然后他需要在每行的同一行上从另一个JComboBox
中选择一个项目。第二个JComboBox
的内容取决于第一个JComboBox
的选择。
我现在的编码方式是更改整个第二列的combobox内容。
columnProfile.setCellEditor(new DefaultCellEditor(comboBoxProf))
有没有一种方法可以让每一行的组合框对象都不一样,这样我就可以在第一个组合框中选择一个值的时候处理它?
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();
}
});
}
}
假设您将数据保存在map
中,其中map的键表示第一个JComboBox保存的值,而map的值表示第二列的JComboBox保存的变化值(数据不需要这样设置,但对于MCVE/演示来说很容易),并将此map称为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());
}
}
我创建了包含员工信息的。在这个JTable中,我添加了名为“资历”的列。此列由表示(每行的内容不同)。例如: 内容取自。 问题是在第1行和第2行中选择的项目是“程序员”,但是“程序员”不应该出现在第2行中。只有当我单击时,才会出现正确的列表,即第2行-{“writer”,“editor”}。
我正在尝试使用GridLayoutManager构建一个RecyclerView,它每行有一个可变的列计数,如下所示: 同一行中所有项目的宽度之和将始终为屏幕宽度。 我试图重新组织项目列表,按行列表分组,然后每行膨胀一个线性布局。它不太好。 所以我被困住了,没有任何想法。任何帮助都将非常感激
我想在我的应用程序中创建一个JTable。该表将包含两个库,第一个是软件模块的名称。第二列需要包含一个JComboBox,第一列中包含软件模块的修订号。 这甚至可能,或者我需要找到另一种方法来做到这一点?(例如:将按钮放在单元格中,然后从弹出窗口中选择修订版本) 提前谢谢你!
问题内容: 我试图用来创建我的,以确保我的构建/项目的质量。该项目也需要使用和。一切在我的本地计算机上都可以正常运行,但是现在我正在尝试使环境一致,可重现。当我尝试在新的虚拟机中运行时,会中断一个在本机中正常运行但 不在 新vm中运行的。 我检查了版本,,,(其)一切都是一样的。但是,我的Maven项目在此测试中失败了。 我在这里想念什么?任何想法,建议都会受到赞赏,因为我现在还没有想法,到目前为
问题内容: 使用Pandas或CSV模块将每行具有不同列数的CSV导入Pandas DataFrame的最佳方法是什么。 使用此代码: 产生以下错误 问题答案: 在read_csv()中提供列名列表应该可以解决问题。 例如:names = [‘a’,’b’,’c’,’d’,’e’] https://github.com/pydata/pandas/issues/2981 编辑:如果您不想提供列名,
问题内容: 我遇到的情况是可以从多个不同的域访问应用程序。例如, foo.com 和 bar.com 在理论上都可以指向我的应用程序。此外,它们的子域也可以指向我的应用程序,例如 red.foo.com 和 blue.foo.com 。我正在使用Express cookie会话,该会话的初始化代码如下所示: 当用户访问 foo.com 或其任何子域时,这种方法效果很好,但是 bar.com 无法正