3

JTablesを使用してデータを表示するアプリケーションがあり、ユーザーがデータを変更できるようにセルを編集できます。ユーザーは、変更を元に戻したり、外部ソースからデータをロードしたりすることもできます。ただし、ユーザーがキーボードショートカットを使用してデータを元に戻す/ロードする場合、マウスフォーカスがテーブルから離れないようにすると、現在選択されているセルは元に戻されません。実際、更新後、セルは編集モードになります。次に、ユーザーがこのセルから離れると、変更イベントがトリガーされるため、古い値がデータストアにコミットされます。

この問題を示す短いサンプルプログラムがあります。これは、すべてのセルに値0が表示されているテーブルを示しています。「インクリメント」と呼ばれる単一のメニュー項目を持つファイルメニューもあり、Ctrl-Iのキーボードショートカットがあります。Incrementコマンドが呼び出されるたびに、すべてのセルに表示されている数が増加します。問題を確認するには、次の手順を実行します。

  1. プログラムをコンパイルして実行します
  2. Ctrl-Iを何度も押して、Incrementコマンドを呼び出します。セルの値は毎回増加することに注意してください。
  3. セルをクリックします。
  4. Ctrl-Iを何度も押して、Incrementコマンドを呼び出します。選択されたセル値を除いて、すべてのセル値が増加することに注意してください。

更新する前にテーブルから選択を削除するためのさまざまな方法を試しましたが、役に立ちませんでした。ない

table.editCellAt(-1, -1);

または

table.getSelectionModel().clearSelection();

たとえば、働いた。

サンプルプログラムは次のとおりです。

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;

public class TableBug extends JFrame {
    private static final int ROW_COUNT = 3;
    private static final int COL_COUNT = 3;

    private int mDataValue = 0;
    private DefaultTableModel mTableModel;

    // Constructor
    public TableBug() {
        setTitle("TableBug");
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);

        // Create table model and table
        mTableModel = new DefaultTableModel();        

        for (int col = 0; col < COL_COUNT; col++) {
            mTableModel.addColumn("Value");
        }

        JTable table = new JTable(mTableModel);
        setUpTable(table);
        refresh();

        // Create menu bar
        int keyMask = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();

        JMenu fileMenu = new JMenu("File");

        JMenuItem incrementMenuItem = new JMenuItem("Increment");
        incrementMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_I, keyMask));
        incrementMenuItem.addActionListener(new AbstractAction() {
            public void actionPerformed(ActionEvent e) {
                doIncrement();
            }
        });

        fileMenu.add(incrementMenuItem);

        JMenuBar mainMenuBar = new JMenuBar();
        mainMenuBar.add(fileMenu);

        // Populate GUI
        setJMenuBar(mainMenuBar);
        add(new JScrollPane(table), BorderLayout.CENTER);

        // Display window
        pack();
        setVisible(true);
    }

    // Configures the table
    private void setUpTable(JTable table) {
        table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

        table.getTableHeader().setReorderingAllowed(false);
        table.getTableHeader().setResizingAllowed(false);

        table.setRowSelectionAllowed(false);
    }

    // Populates the table
    private void refresh() {
        mTableModel.setRowCount(ROW_COUNT);

        for (int col = 0; col < COL_COUNT; col++) {
            for (int row = 0; row < ROW_COUNT; row++) {
                mTableModel.setValueAt(mDataValue, row, col);
            }
        }
    }

    // Handles the Increment menu item
    public void doIncrement() {
        mDataValue++;
        refresh();
    }

    // Main program
    public static void main(String[] args) {
        //Schedule a job for the event-dispatching thread:
        //creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new TableBug();
            }
        });
    }
}
4

1 に答える 1

3

更新機能で、テーブルが編集されているかどうかを確認します。そうである場合は、編集中の行と列を取得して、セルの編集を停止します。

private void refresh() {
    if (table.isEditing()) {
        int row = table.getEditingRow();
        int column = table.getEditingColumn();
        table.getCellEditor(row, column).stopCellEditing();
    }
 ...

これを行うには、テーブル変数をアクセス可能にする(クラス変数にする)必要があります。

于 2012-03-02T20:50:22.583 に答える