3

ListSelectionListener を使用してJTextField、選択した行から (countryTxt) を更新しています。

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;

public class App {

    JFrame frame = new JFrame();
    JTable table = new JTable();
    DefaultTableModel model = new DefaultTableModel(new Object[][] {},
            new String[] { "Country", "City", "Street" });
    JButton button = new JButton("Remove");
    JTextField countryTxt = new JTextField();

    int row;

    public App() {
        table.setModel(model);
        data();
        table.getSelectionModel().addListSelectionListener(
                new ListSelectionListener() {
                    @Override
                    public void valueChanged(ListSelectionEvent e) {
                        if (!e.getValueIsAdjusting()) {
                            row = table.getSelectedRow();
                            countryTxt.setText((String) model
                                    .getValueAt(row, 0));
                        }
                    }
                });
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
                model.removeRow(row);
            }
        });
        frame.add(countryTxt,BorderLayout.NORTH);
        frame.add(new JScrollPane(table), BorderLayout.CENTER);
        frame.add(button, BorderLayout.SOUTH);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
        frame.setLocationRelativeTo(null);
    }

    public void data() {
        model.addRow(new String[] { "USA", "New York", "First street" });
        model.addRow(new String[] { "Russia", "Moscow", "Second street" });
        model.addRow(new String[] { "Japan", "Osaka", "Osaka street" });
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new App();
            }
        });
    }
}

しかし、行を選択してクリックするbuttonと、ArrayIndexOutOfBounds例外が発生します。テーブルの行を選択せず​​にクリックすると、buttonすべて正常に動作します。valueChangedイベントがトリガーされていない場合は、明らかに行を削除できます。私の質問は、valueChangedイベントがトリガーされた後に行を削除する方法です。前もって感謝します。

4

3 に答える 3

3

getLeadSelectionIndex()メソッドのjavadocを見てください

setSelectionInterval()、addSelectionInterval()、または removeSelectionInterval() への最新の呼び出しから 2 番目のインデックス引数を返します。

これはあなたが期待するものではありません。JTable#getSelectedRow()もちろん、 which が -1 と異なるかどうかを確認する必要がある場合は、 which を使用することをお勧めします。

于 2012-07-25T06:07:49.140 に答える
3

いくつかの観察:

  • キーボードまたはマウスで行を選択すると、countryTxtフィールドが正しく更新されます。

  • Control>-を使用Tabして、テーブルからタブで移動し、 に戻ることができますpanel

  • 使用しないでくださいsetBounds()。使用してくださいpack()

  • なしであなたの例をテストしましMigLayoutたが、それはあなたの発見に関連しているとは思いません。

于 2012-07-25T02:53:36.930 に答える
2

少し前に、リストの削除に関連する同様の問題を突き止めなければなりませんでした。ここでの主な問題は、ボタン リスナーの への呼び出しがモデルの選択リスナーにイベントをmodel.removeRow(row)送信valueChangedし、存在しない選択 (つまり のリスト インデックス) を使用してテキスト フィールドを更新しようとしたこと-1です。コードにこれらの修正を加えました。関連するセクションにはコメントが付いています。このコードにより、例外をスローせずにアイテムを選択/削除できます。

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;

public class App {
    JFrame frame = new JFrame();
    DefaultTableModel model = new DefaultTableModel(new Object[][] {},
            new String[] { "Country", "City", "Street" });
    JTable table = new JTable(model);
    JButton button = new JButton("Remove");
    JTextField countryTxt = new JTextField();

    public App() {
        data();
        table.getSelectionModel().addListSelectionListener(
                new ListSelectionListener() {
                    @Override
                    public void valueChanged(ListSelectionEvent e) {
                        if (!e.getValueIsAdjusting()) {
                            // get the current selected row
                            int i = table.getSelectedRow();
                            // if there is a selected row, update the text field
                            if(i >= 0) {
                               countryTxt.setText((String) model
                                    .getValueAt(i, 0));
                            }
                        }
                    }
                });
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
                // get the current selected row
                int i = table.getSelectedRow();
                // if there's no selection, but there are some rows,
                // we'll just delete the first row
                if(i < 0 && model.getRowCount() > 0) {
                   i = 0;
                }

                // if we have a valid row to delete, do the deletion
                if(i >= 0) {
                    countryTxt.setText("");
                    model.removeRow(i);
                    table.revalidate();
                }
            }
        });
        frame.add(countryTxt,BorderLayout.NORTH);
        frame.add(new JScrollPane(table), BorderLayout.CENTER);
        frame.add(button, BorderLayout.SOUTH);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
        frame.setLocationRelativeTo(null);
    }

    public void data() {
        model.addRow(new String[] { "USA", "New York", "First street" });
        model.addRow(new String[] { "Russia", "Moscow", "Second street" });
        model.addRow(new String[] { "Japan", "Osaka", "Osaka street" });
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new App();
            }
        });
    }
}
于 2013-02-18T08:32:57.183 に答える