1

TableModelListener 为侦听 TableModel 更改的对象定义接口。

表模型监听器

如何将此应用于 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();
            }
        });
    }
}

可能我误解了pass-by-value,尽管我已经读过这些术语根据上下文具有不同的含义。

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的 inNews似乎是虚假的,因为(看不见的)MessagesController模型会迅速取代它。

也不清楚你为什么invokeLater()ListSelectionListener和 中使用ChangeListener。这些方法应该已经在事件调度线程上运行。如果没有,您将需要同步对任何共享数据的访问。

于 2012-04-26T13:05:46.770 回答