我在列中使用自定义CellEditor
更新:添加了SSCCE
public class TestJFrame extends javax.swing.JFrame {
public TestJFrame() {
initComponents();
jTable1.getTableHeader().addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(final MouseEvent e) {
final JTableHeader tableHeader = (JTableHeader) e.getSource();
final JTable table = tableHeader.getTable();
final int column = tableHeader.columnAtPoint(e.getPoint());
if (column == 1) {
TableCellEditor editor = table.getColumnModel()
.getColumn(column)
.getCellEditor();
for (int row = 0; row < table.getModel().getRowCount(); row++) {
if (table.getModel().isCellEditable(row, column)) {
editor.getTableCellEditorComponent(table, (e.getButton() == MouseEvent.BUTTON1),
false,
row,
column);
tableHeader.getTable().setValueAt((e.getButton() == MouseEvent.BUTTON1),
row,
column);
}
}
}
}
});
}
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jScrollPane1 = new javax.swing.JScrollPane();
jTable1 = new javax.swing.JTable();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jTable1.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
{null, null},
{null, null},
{null, null}
},
new String [] {
"name", "click me"
}
) {
Class[] types = new Class [] {
java.lang.String.class, java.lang.Boolean.class
};
boolean[] canEdit = new boolean [] {
false, true
};
public Class getColumnClass(int columnIndex) {
return types [columnIndex];
}
public boolean isCellEditable(int rowIndex, int columnIndex) {
return canEdit [columnIndex];
}
});
jScrollPane1.setViewportView(jTable1);
if (jTable1.getColumnModel().getColumnCount() > 0) {
jTable1.getColumnModel().getColumn(0).setResizable(false);
jTable1.getColumnModel().getColumn(0).setPreferredWidth(100);
jTable1.getColumnModel().getColumn(1).setCellEditor(new SwitchCellEditor(new EnableCheckbox(jTable1), jTable1));
}
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 91, Short.MAX_VALUE)
.addGap(0, 0, 0))
);
pack();
}// </editor-fold>
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(TestJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(TestJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(TestJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(TestJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new TestJFrame().setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JTable jTable1;
// End of variables declaration
private static class EnableCheckbox extends JCheckBox {
public EnableCheckbox(final JTable table) {
addItemListener(new EnableCheckboxItemListenerImpl(table));
}
private final class EnableCheckboxItemListenerImpl implements ItemListener {
private final JTable _table;
public EnableCheckboxItemListenerImpl(final JTable table) {
_table = table;
}
@Override
public void itemStateChanged(ItemEvent e) {
final JCheckBox checkBox = (JCheckBox) e.getSource();
final int selectedRow = _table.rowAtPoint(checkBox.getLocation());
final int selectedColumn = _table.columnAtPoint(checkBox.getLocation());
// doStuff
}
}
}
private class SwitchCellEditor extends DefaultCellEditor {
private final JTable _table;
private final JCheckBox _checkBox;
public SwitchCellEditor(final JCheckBox checkBox, final JTable table) {
super(checkBox);
_checkBox = checkBox;
_table = table;
}
@Override
public final Component getTableCellEditorComponent(
final JTable table,
final Object value,
final boolean isSelected,
final int row,
final int column) {
Rectangle r = _table.getCellRect(row, column, false);
if (_checkBox != null) {
_checkBox.setLocation(new Point(r.x, r.y + r.height));
return super.getTableCellEditorComponent(table, value, isSelected, row, column);
}
return super.getTableCellEditorComponent(table, value, isSelected, row, column);
}
}
}
itemStateChanged方法仅在第一个迭代步骤中调用,但不在以下迭代步骤中调用。
为什么它的行为与此类似,如何在每次迭代步骤中调用itemStateChanged?
答案 0 :(得分:1)
您的implementation ...不会为每行中的每个编辑器调用
itemStateChanged
。
完全。 JTable
使用editors的flyweight模式,在编辑器结束后仅更新TableModel
。如果你想看到编辑器的状态变化,你可以
使用引用的示例here中的方法,其中编辑器侦听相应渲染器使用的JCheckBox
。
添加CellEditorListener
,提及here。