我正在尝试使用JButton
asTableCellRenderer
和TableCellEditor
我的JTable
. 在我的测试场景中,我有 5 行,每行都显示JButton
为渲染器和编辑器(编辑器和渲染器的不同按钮实例)。当我第一次单击一个按钮时actionPerformed
,编辑器按钮被调用,当我释放鼠标按钮时。然后,当我单击另一行中的另一个按钮actionPerformed
时,当我按下鼠标按钮(MOUSE_PRESSED
)时,已经调用了编辑器按钮的 -Event。这种行为似乎不对。通常actionPerformed
在释放鼠标按钮时调用-event,而不是在按下它时。之后按下另一行中的另一个按钮actionPerformed
时,释放鼠标按钮时再次正确调用,在下一个按钮上单击另一行actionPerformed
再次(错误地)调用MOUSE_DOWN
等等。
当将焦点移出表格然后单击按钮actionPerformed
时,释放鼠标按钮时会正确调用。此外,当要单击的按钮所在的行中的表行编辑器首先聚焦(激活)然后单击该按钮时,该行为也是正确的。然后只有当它不起作用时,表格单元格编辑器处于活动状态,然后单击另一个表格行中的按钮。
比较actionPerformed
两种情况下调用时的堆栈跟踪,我发现在不正确的情况下DefaultKeyboardFocusManager(KeyboardFocusManager).redispatchEvent
并被BasicButtonListener.focusLost(FocusEvent)
调用,这对我来说都是可疑的。
这是我的问题的一些演示代码:
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.AbstractCellEditor;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
public class TableButtonTest extends JFrame
{
private JTable table;
public TableButtonTest()
{
super("TableButtonTest");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel contentPane = new JPanel(new GridLayout(1, 0));
contentPane.setOpaque(true);
setContentPane(contentPane);
table = new JTable(new MyTableModel());
table.setPreferredScrollableViewportSize(new Dimension(500, 70));
add(table);
setPreferredSize(new Dimension(600, 200));
TableCellRenderer defaultBtnRenderer = new TableCellRenderer()
{
private JButton btn = new JButton("aa");
public Component getTableCellRendererComponent(JTable _table, Object value,
boolean isSelected, boolean hasFocus, int row, int column)
{
return btn;
}
};
table.getColumnModel().getColumn(0).setCellRenderer(defaultBtnRenderer);
table.getColumnModel().getColumn(0).setCellEditor(new ButtonEditor());
pack();
setVisible(true);
}
public class ButtonEditor extends AbstractCellEditor implements TableCellEditor
{
private JButton btn = new JButton("bb");
{
btn.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
System.out.println("BUTTON EVENT");
}
});
}
public Component getTableCellEditorComponent(JTable _table, Object value, boolean isSelected,
int row, int column)
{
return btn;
}
public Object getCellEditorValue()
{
return null;
}
}
class MyTableModel extends AbstractTableModel
{
public int getColumnCount()
{
return 1;
}
public int getRowCount()
{
return 5;
}
public Object getValueAt(int row, int col)
{
return null;
}
@Override
public boolean isCellEditable(int row, int col)
{
return true;
}
}
public static void main(String[] args)
{
new TableButtonTest();
}
}
当您启动程序并点击任何“aa”按钮时,它会变成“bb”(表示显示编辑器而不是渲染器)并且当您释放鼠标按钮时,“BUTTON EVENT”会打印在 STDOUT 上。如果您单击另一行中的另一个按钮,它也会变成“bb”,但在您释放鼠标按钮之前,“BUTTON EVENT”已经打印到 STDOUT。而且按钮文本周围的焦点矩形也没有显示。
我用 Java 1.6.0_26 和 1.6.0_27 测试了这种行为。当我使用 1.5.0_17 时,情况变得更糟:单击第二个按钮时,没有调用 actionPerformed,只显示“bb”按钮。第三次点击再次正常工作,第四次没有,依此类推。所以与 Java 1.6 的区别在于,在 1.6 上,第二次(和第四次,...)单击 actionPerformed 在释放鼠标按钮时被调用,而在 1.5 上根本不被调用。
但我不在乎 1.5,我只希望它与 1.6 一起工作。
我能做些什么来完成这项工作?
谢谢。