1

TableModelListenerは、TableModelの変更をリッスンするオブジェクトのインターフェイスを定義します。

TableModelListener

これをJTableに適用して、DefaultTableModelの変更をリッスンする方法は?さらに、setModelが呼び出された後、その機能を組み込むべきではありませんか?JTableにモデルへの変更を反映させたくないのはなぜですか?

NewsのdefaultTableModelの参照は、MessagesControllerと同じインスタンスを指しています(これは正しいですか?)。基になるオブジェクトが更新されている場合、なぜJTableでsetModelを明示的に呼び出す必要があるのですか?

JTableがそれ自体を更新するためのより良い方法は何ですか?おそらくtableChanged

Newsの参照とMessagesControllerの参照の両方が同じ値を持つ異なるオブジェクトを指している場合、なぜsetModel()を呼び出す必要があるのか​​わかりません。結局のところ、News.defaultTableModelが更新されました。なぜsetModel()を再起動するのですか?

package net.bounceme.dur.nntp;

import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.util.logging.Logger;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;

public class News {

    private static final Logger LOG = Logger.getLogger(News.class.getName());
    static JFrame frame = new JFrame();
    static JTextPane text = new JTextPane();
    static JSlider slider = new JSlider();
    static MessagesController messagesController = new MessagesController();
    static DefaultTableModel defaultTableModel = new DefaultTableModel();
    static JTable table = new JTable();

    private static void createAndShowGUI() {
        defaultTableModel = messagesController.getDefaultTableModel();
        table.setModel(defaultTableModel);
        table.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {

            public void valueChanged(ListSelectionEvent evt) {
                java.awt.EventQueue.invokeLater(new Runnable() {

                    public void run() {
                        int row = table.convertRowIndexToModel(table.getSelectedRow());
                        row = Math.abs(row);  //how can this be negative?
                        LOG.fine("row " + row);
                        MessageBean messageBean = messagesController.getMessageBean(row);
                        text.setText(messageBean.getContent());
                        text.setContentType("text/html");
                    }
                });
            }
        });

        slider.setMinimum(1);
        slider.setMaximum(messagesController.getMax());
        slider.setValue(messagesController.getMax());
        slider.addChangeListener(new javax.swing.event.ChangeListener() {

            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                java.awt.EventQueue.invokeLater(new Runnable() {

                    public void run() {
                        int index = slider.getValue();
                        LOG.fine("slider " + index);
                        messagesController.setIndex(index);
                        defaultTableModel = messagesController.getDefaultTableModel();
                        table.setModel(defaultTableModel);
                        table.getSelectionModel().setSelectionInterval(1, 1);
                    }
                });
            }
        });
        table.getSelectionModel().setSelectionInterval(1, 1);
        JPanel panel = new JPanel();
        panel.setLayout(new GridLayout(3, 1));
        panel.add(table);
        panel.add(text);
        panel.add(slider);
        frame.add(panel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        frame.pack();
        frame.setVisible(true);
        frame.setSize(screenSize);
    }

    public static void main(String args[]) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                createAndShowGUI();
            }
        });
    }
}

おそらく私は値渡しを誤解していますが、これらの用語は文脈によって異なる意味を持っていることを読みました。

4

2 に答える 2

3

1)row = Math.abs(row); //how can this be negative?

選択した行がない場合は、コード行

int row = table.convertRowIndexToModel(table.getSelectedRow());

値を返します。何よりも前-1にテストすることをお勧めしますif(table.getSelectedRow() > -1)

2)TableModelを置き換える理由はなく、DefaultTableModelもありません。JTableはTableModel、JTable#getModelを返すことができます。

3)コンテキストからはわかりませんが、JTableの並べ替えとフィルタリングを確認したことがあるかもしれません。

于 2012-04-26T11:01:43.167 に答える
3

基になるオブジェクトが更新されている場合、setModel()なぜ明示的に呼び出す必要があるのですか?JTable

貴方はするべきではない。

JTableを更新するためのより良い方法は何ですか?

モデルを更新TableModelすると、ビューに通知するために必要なイベントが発生し、JTableそれ自体が更新されます。DefaultTableModelあなたのためにこれを行います。モデルが呼び出すためのAbstractTableModel便利なメソッドを提供します。ここfireXxx()に後者の例があります。「テーブルの使用方法:テーブルモデルの作成」も参照してください。

(見えない)モデルがすぐにそれを置き換えるので、新しい空DefaultTableModelのinの作成は偽物のように見えます。NewsMessagesController

とで使用invokeLater()する理由も不明です。これらのメソッドは、イベントディスパッチスレッドですでに実行されている必要があります。そうでない場合は、共有データへのアクセスを同期する必要があります。ListSelectionListenerChangeListener

于 2012-04-26T13:05:46.770 に答える