java 当 DefaultTableModel 已更改时,在 JTable 上设置模型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10331949/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
setModel on a JTable when the DefaultTableModel has changed
提问by Thufir
TableModelListener defines the interface for an object that listens to changes in a TableModel.
TableModelListener 为侦听 TableModel 更改的对象定义了接口。
How to apply this to the JTable, so that it will listen for changes in a DefaultTableModel? Furthermore, after setModel is invoked, shouldn't that functionality be built-in? Why would you not want the JTable to reflect changes to the model?
如何将此应用于 JTable,以便它侦听 DefaultTableModel 中的更改?此外,在调用 setModel 之后,该功能不应该是内置的吗?为什么不希望 JTable 反映对模型的更改?
The reference for defaultTableModel in News points to the same instance as in MessagesController (is this correct?), so why do I have to explicitly invoke setModel on the JTable if the underlying object has been updated?
News 中 defaultTableModel 的引用指向与 MessagesController 中相同的实例(这是正确的吗?),那么如果底层对象已更新,为什么我必须显式调用 JTable 上的 setModel 呢?
What's a better way for the JTable to update itself? Perhaps tableChanged?
JTable 更新自身的更好方法是什么?也许tableChanged?
I don't understand, if both the reference in News and the reference in MessagesController point to differentobjects, with the same values, why it's necessary to invoke setModel(). After all, News.defaultTableModel now has been updated. Why re-invoke setModel()?
我不明白,如果 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();
}
});
}
}
Possibly I misunderstand pass-by-value, although I have read that these terms have different meanings depending upon the context.
可能我误解了pass-by-value,尽管我已经读过这些术语根据上下文具有不同的含义。
回答by mKorbel
1) row = Math.abs(row); //how can this be negative?
1) row = Math.abs(row); //how can this be negative?
if isn't there any selected row then code line
如果没有任何选定的行,则代码行
int row = table.convertRowIndexToModel(table.getSelectedRow());
returns -1
value, better would be to test if(table.getSelectedRow() > -1)
before anything
返回-1
值,最好if(table.getSelectedRow() > -1)
在任何事情之前进行测试
2) there no reason replace TableModel, nor DefaultTableModel, JTable can returns its TableModel, JTable#getModel
2)没有理由替换TableModel,也没有替换DefaultTableModel,JTable可以返回它的TableModel,JTable#getModel
3) not sure from context, but maybe you have look at JTable Sorting and Filtering
3) 从上下文不确定,但也许你看过JTable Sorting and Filtering
回答by trashgod
Why do I have to explicitly invoke
setModel()
on theJTable
, if the underlying object has been updated?
为什么我必须显式调用
setModel()
的JTable
,如果底层对象已更新?
You should not.
你不应该。
What's a better way for the
JTable
to update itself?
JTable
更新自身的更好方法是什么?
Updating the model, TableModel
, should fire the events required to notify the view, JTable
, to update itself. DefaultTableModel
does this for you; AbstractTableModel
provides convenient fireXxx()
methods for your model to invoke. There's an example of the latter here. See also How to Use Tables: Creating a Table Model.
更新模型 ,TableModel
应触发通知视图 ,JTable
更新自身所需的事件。DefaultTableModel
为你做这件事;为您的模型AbstractTableModel
提供方便的fireXxx()
调用方法。有后者的例子在这里。另请参见如何使用表:创建表模型。
The creation of a new, empty DefaultTableModel
in News
appears spurious, as the (unseen) MessagesController
model promptly replaces it.
创建一个新的、空的DefaultTableModel
inNews
似乎是虚假的,因为(看不见的)MessagesController
模型迅速取代了它。
It's also unclear why you use invokeLater()
in the ListSelectionListener
and the ChangeListener
. These methods should already be running on the event dispatch thread. If not, you'll need to synchronize access to any shared data.
也不清楚你为什么invokeLater()
在ListSelectionListener
和 中使用ChangeListener
。这些方法应该已经在事件调度线程上运行了。如果没有,您将需要同步对任何共享数据的访问。