Я пытаюсь использовать JButton
как TableCellRenderer
и TableCellEditor
для моего JTable
. В моем тестовом сценарии у меня есть 5 строк, каждая из которых показывает JButton
как Renderer и Editor (разные экземпляры кнопок для редактора и Renderer). Когда я нажимаю на одну кнопку в первый раз, actionPerformed
кнопки редактора вызывается, когда я отпускаю кнопку мыши. Когда я нажимаю другую кнопку в другом ряду, actionPerformed
событие события кнопки редактирования уже вызывается, когда я нажимаю кнопку мыши (MOUSE_PRESSED
). Такое поведение не кажется правильным. Обычно событие actionPerformed
вызывается при отпускании кнопки мыши, а не при ее нажатии. При последующем нажатии другой кнопки в другом ряду 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», но «СОБЫТИЕ КНОПКИ» уже напечатано в 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.
Что я могу сделать, чтобы сделать эту работу?
Спасибо.