[英]setModel on a JTable when the DefaultTableModel has changed
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();
}
});
}
}
可能我误解了值传递 ,尽管我已经读到这些术语根据上下文具有不同的含义。
1) row = Math.abs(row); //how can this be negative?
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排序和过滤
如果基础对象已更新,为什么我必须在
JTable
上显式调用setModel()
?
你不应该。
JTable
更新自身的更好方法是什么?
更新模型TableModel
触发通知视图JTable
进行更新所需的事件。 DefaultTableModel
为您完成此操作; AbstractTableModel
提供了方便的fireXxx()
方法供您的模型调用。 有后者的例子在这里 。 另请参见如何使用表:创建表模型 。
在News
中创建一个新的空的DefaultTableModel
似乎是虚假的,因为(看不见的) MessagesController
模型会立即替换它。
还不清楚为什么在ListSelectionListener
和ChangeListener
使用invokeLater()
。 这些方法应该已经在事件分发线程上运行。 如果没有,则需要同步对任何共享数据的访问。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.