TableModelListener defines the interface for an object that listens to changes in a 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?
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?
What's a better way for the JTable to update itself? Perhaps tableChanged?
I don't understand, if both the reference in News and the reference in MessagesController point to different objects, with the same values, why it's necessary to invoke setModel(). After all, News.defaultTableModel now has been updated. Why re-invoke 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.