2

私はを自分のJButtonとして使用しようTableCellRendererとしています。私のテスト シナリオでは、それぞれがレンダラーとエディター (エディターとレンダラーの異なるボタン インスタンス) として表示される 5 つの行があります。1 つのボタンを初めてクリックすると、エディター ボタンが呼び出され、マウス ボタンを離すと、別の行の別のボタンをクリックすると、マウスボタンを押したときにエディターボタンの -Event が既に呼び出されています ( )。この動作は正しくないようです。通常、イベントは、マウス ボタンを押したときではなく、離したときに呼び出されます。後で別の行の別のボタンを押すと、マウス ボタンを離したときに再び正しく呼び出され、次のボタンで別の行をクリックします。TableCellEditorJTableJButtonactionPerformedactionPerformedMOUSE_PRESSEDactionPerformedactionPerformedactionPerformed再び (誤って) 呼び出されMOUSE_DOWNます。

フォーカスをテーブルの外に移動してからボタンをクリックするとactionPerformed、マウス ボタンを離したときに が正しく呼び出されます。また、クリックするボタンがある行のテーブル行エディターが最初にフォーカス (アクティブ化) されてからボタンがクリックされた場合の動作も正しいです。それが機能しない唯一の状況は、テーブル セル エディタがアクティブで、別のテーブル行のボタンがクリックされた場合です。

両方のケースで呼び出されたときのスタックトレースを比較すると、間違ったケースでactionPerformed呼び出されていることがわかりました。どちらも疑わしいように見えます。DefaultKeyboardFocusManager(KeyboardFocusManager).redispatchEventBasicButtonListener.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 を使用すると、イベントがさらに悪化しました。2 番目のボタンをクリックすると、actionPerformed が呼び出されず、「bb」ボタンのみが表示されました。3 回目のクリックは再び正しく機能し、4 回目は機能しませんでした。したがって、Java 1.6 との違いは、1.6 では 2 回目 (および 4 回目) のクリックで actionPerformed が呼び出され、1.5 ではまったく呼び出されないことです。

しかし、私は 1.5 を気にしません。1.6 で動作するようにしたいだけです。

これを機能させるにはどうすればよいですか?

ありがとう。

4

1 に答える 1

3

Table Button Columnは、ボタンをレンダラー/エディターとして使用するための私のソリューションを示しています。

于 2011-10-18T16:03:00.167 に答える