我有一個 JTable,其中第 3 列和第 4 列使用 JComboBox 作為單元格編輯器。第 3 列指定型別,第 4 列指定子型別。第 4 列中可用的子型別串列取決于用戶為該型別選擇的值。此外,型別和子型別的串列是用戶可以編輯的(這里的細節并不重要,只是型別和子型別的串列都可以在運行時改變)。
因為子型別組合框的內容是動態的,所以我的意圖是檢測用戶何時單擊子型別單元格,并根據該型別的內容在那個時刻設定串列模型(設定可用的子型別專案串列)排。
但是,我在檢測所需單元格中的滑鼠點擊時遇到了困難。我已經在下面發布了我的代碼和輸出。
問題是滑鼠偵聽器沒有檢測到組合框中的點擊。據推測,該事件是由組合框而不是表格觸發的。我可以將 ListSelectionListener 與 TableColumnModelListener 結合使用,但我不得不想象有更好的方法。我嘗試使用與組合框相關的事件,但我無法獲得有關選擇了哪個組合框的資訊(所以我不知道我在表中的哪個位置)。我試圖獲取組合框的容器并以這種方式定位單擊,但組合框的 getParent() 方法回傳 null。
編輯:在 ComboBox ActionListener 中,我還嘗試使用 JTable 的 getSelectedRow() 和 getSelectedColumn() 方法,但它們回傳舊單元格的值,而不是新單元格的值。
任何關于如何更簡潔地做到這一點的建議都值得贊賞。
以下是相關的代碼片段(事件處理程式還沒有做太多,只是試圖獲取資訊):
// Setup table and table model
tableTypeDataModel = new TypeAssignmentTableModel();
JTable typeTable = new JTable(tableTypeDataModel);
// Add a mouse listener to the table.
typeTable.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e)
{
Point pnt = e.getPoint();
int row = typeTable.rowAtPoint(pnt);
int col = typeTable.columnAtPoint(pnt);
System.out.println(Integer.toString(row) ", " Integer.toString(col));
}
});
typeTable.getSelectionModel().addListSelectionListener(new myListSelectionListener());
typeTable.setFillsViewportHeight(true);
JScrollPane scpnTypeTable = new JScrollPane(typeTable);
// Set columns and model listener
TableColumnModel cm = typeTable.getColumnModel();
cm.addColumnModelListener(new myColumnListSelectionListener());
// Setup type column
JComboBox<String> cmbTableTypes = new JComboBox<>(arrOfTypes);
cmbTableTypes.addActionListener(new myCBOActionListener());
cm.getColumn(TYPECOL_TYPE).setCellEditor(new DefaultCellEditor(cmbTableTypes));
// This just adds left padding to the cell
IndentedTableCellRenderer tableTypeRenderer = new IndentedTableCellRenderer(5, 0);
cm.getColumn(TYPECOL_TYPE).setCellRenderer(tableTypeRenderer);
// Setup subtype column
tableSubtypeCboModel = new DefaultComboBoxModel<>();
JComboBox<String> cmbTableSubtypes = new JComboBox<>(tableSubtypeCboModel);
cm.getColumn(TYPECOL_SUBTYPE).setCellEditor(new DefaultCellEditor(cmbTableSubtypes));
IndentedTableCellRenderer tableSubtypeRenderer = new IndentedTableCellRenderer(5, 0);
cm.getColumn(TYPECOL_SUBTYPE).setCellRenderer(tableSubtypeRenderer);
和...
class myListSelectionListener implements ListSelectionListener {
@Override
public void valueChanged(ListSelectionEvent e) {
System.out.println("Table List selection listener = " e.getSource().toString());
}
}
class myColumnListSelectionListener implements TableColumnModelListener {
// other methods empty and not shown...
@Override
public void columnSelectionChanged(ListSelectionEvent e) {
// TODO Auto-generated method stub
System.out.println("Table column model listener Source = "
e.getSource().toString());
}
}
class myCBOActionListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
JComboBox item = (JComboBox) e.getSource();
System.out.println("CBO Action Listener = " item.getClass().toString());
String msg = item.getParent() == null ? "null" : item.getParent().toString();
System.out.println("CBO Action Listener item parent is " msg);
}
}
這是單擊以下單元格后的控制臺輸出:
Row 1, Col 0 (just a regular cell)
Row 2, Col 1 (just a regular cell)
Row 3, Col 2 (just a regular cell)
Row 4, Col 3 (this is the Type column with a combo box editor)
Console Output:
Table column model listener Source = javax.swing.DefaultListSelectionModel 724380095 ~{0}
Table List selection listener = javax.swing.DefaultListSelectionModel 1902920301 ~{1}
Table List selection listener = javax.swing.DefaultListSelectionModel 1902920301 ={1}
Table column model listener Source = javax.swing.DefaultListSelectionModel 724380095 ={0}
1, 0
Table column model listener Source = javax.swing.DefaultListSelectionModel 724380095 ~{1}
Table List selection listener = javax.swing.DefaultListSelectionModel 1902920301 ~{2}
Table List selection listener = javax.swing.DefaultListSelectionModel 1902920301 ={2}
Table column model listener Source = javax.swing.DefaultListSelectionModel 724380095 ={1}
2, 1
Table column model listener Source = javax.swing.DefaultListSelectionModel 724380095 ~{2}
Table List selection listener = javax.swing.DefaultListSelectionModel 1902920301 ~{3}
Table List selection listener = javax.swing.DefaultListSelectionModel 1902920301 ={3}
Table column model listener Source = javax.swing.DefaultListSelectionModel 724380095 ={2}
3, 2
CBO Action Listener = class javax.swing.JComboBox
CBO Action Listener item parent is null
Table column model listener Source = javax.swing.DefaultListSelectionModel 724380095 ~{3}
Table List selection listener = javax.swing.DefaultListSelectionModel 1902920301 ~{4}
Table List selection listener = javax.swing.DefaultListSelectionModel 1902920301 ={4}
Table column model listener Source = javax.swing.DefaultListSelectionModel 724380095 ={3}
謝謝。
uj5u.com熱心網友回復:
您可以將您的子型別JCombobox作為全域管理,然后在 UI 中“選擇”ActionListener子型別組件時添加一個更新子型別值的子型別。JCombobox
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.*;
import javax.swing.*;
public class whatev{
JComboBox types = new JComboBox();
JComboBox subtypes = new JComboBox();
Map<String,int[]> m = new HashMap<String,int[]>(); //example source mapping types to sub-types
int[] t1 = {1,3};
int[] t2 = {4, 5};
public static void main(String[] args){ new whatev(); }
whatev(){
//Add example data to types
types.addItem("Type 1");
types.addItem("Type 2");
types.setSelectedIndex(0);
//init map data for example
m.put("Type 1", t1);
m.put("Type 2", t2);
//initialize subtype JCombobox
updateSubtypes();
//add appropriate listener to subtype box
subtypes.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
updateSubtypes();
}
});
}
private void updateSubtypes() {
int[] x = m.get(types.getSelectedItem()); //pull appropriate subtypes from type/subtype mapping source
subtypes.removeAllItems(); //purge old objects in subtype
for(int v : x) { subtypes.addItem(v); } //Add appropriate subtypes
}
}
uj5u.com熱心網友回復:
@camickr - 謝謝你的回答。我按照建議覆寫了 prepareEditor 方法,該方法根據需要更新了組合框中的 ListModel。
JTable typeTable = new JTable() {
@Override
public Component prepareEditor(TableCellEditor editor, int row, int column) {
if (column == SUBTYPE_COLUMN) {
// User has entered a subtype cell
// Get value of the adjacent type cell
updateCBOSubtypeDataModel(myTableModel.getValueAt(row, TYPE_COLUMN);
}
return super.prepareEditor(editor, row, column);
}
};
和
private void updateCBOSubtypeDataModel(TypeObject newType) {
myComboBoxListModel.removeAllElements();
myComboBoxListModel.addAll(getListOfSubtypesForThisType(newType));
}
作業得很好。謝謝。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/456055.html
