actionPerformed для JButton, поскольку TableCellEditor неправильно вызван на MouseDown - PullRequest
2 голосов
/ 18 октября 2011

Я пытаюсь использовать 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.

Что я могу сделать, чтобы сделать эту работу?

Спасибо.

1 Ответ

3 голосов
/ 18 октября 2011

Столбец Столбец Столбец показывает мое решение для использования кнопки в качестве средства визуализации / редактирования.

...