Reputation: 251
In Java Swing, could someone tell me the difference between using setPreferredScrollableViewportSize() after putting my JTable in JScrollPane vs. calling setFillsViewportHeight(true) on the JTable instance? I want to know which one is the good practice. Herbert Schildt suggests using setPreferredScrollableViewportSize() while Horstmann and Cornell suggest setFillsViewportHeight(). Here is a short sample of what I am fooling around with.
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
public class TableDemo {
JTable jtabEmail;
String[] headings = {"From", "Address", "Subject", "Size"};
Object[][] data = {
{ "Wendy", "[email protected]",
"Hello Herb", new Integer(287) },
{ "Alex", "[email protected]",
"Check this out!", new Integer(308) },
{ "Hale", "[email protected]",
"Found a bug", new Integer(887) },
{ "Todd", "[email protected]",
"Did you see this?", new Integer(223) },
{ "Steve", "[email protected]",
"I'm back", new Integer(357) },
{ "Ken", "[email protected]",
"Arrival time change", new Integer(512) }
};
JLabel jl;
public TableDemo() {
JFrame jfrm = new JFrame("Table Demo");
jfrm.setSize(500, 160);
jfrm.getContentPane().setLayout(new FlowLayout());
jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jl = new JLabel("");
jtabEmail = new JTable(data, headings);
jtabEmail.setFillsViewportHeight(true);
JScrollPane jsp = new JScrollPane(jtabEmail);
//jtabEmail.setPreferredScrollableViewportSize(new Dimension(450, 80));
jtabEmail.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
StringBuilder sb = new StringBuilder("Selected Rows: ");
int[] rowsArray = jtabEmail.getSelectedRows();
for (int i = 0; i < rowsArray.length; i++) {
sb.append((rowsArray[i]+1) + " ");
}
jl.setText(sb.toString());
}
});
jfrm.getContentPane().add(jsp);
jfrm.getContentPane().add(jl);
//jfrm.pack();
jfrm.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new TableDemo();
}
});
}
}
Upvotes: 3
Views: 9381
Reputation: 109823
this is only theory about how to avoiding setPreferredSize, setSize, setBounds, I'm quite familair with
JTable can't returns reasonable PreferredSize from methods implemented in API, e.g JTextArea(10, 20); JList#setPrototypeDisplayValue and number of visible Ites
only setPreferredScrollableViewportSize, setPreferredSize and setSize (ev setBounds) can returns notifier for LayoutManager about prototype for Dimension, otherwise is used default PreferredSize for JScrollPane from API
setPreferredScrollableViewportSize, setPreferredSize and setSize with pack() or witout for JFrame.setSize/setBounds
there isn't difference betweens JTable.setFillsViewportHeight(true) and with proper JFrame.pack()
setPreferredScrollableViewportSize is about good practicies,
table.setPreferredScrollableViewportSize(table.getPreferredSize());
is wrong usage of and can to enlarge JViewport for JTables to extreme sizes, proper Dimension could be calculated from assummed number of rows, note not all rows can have got the same height
use resizable LayoutManager for JScrollPane not FlowLayout
don't to use Jframe.setSize, override proper Dimension for PreferredScrollableViewportSize (a few times discused here)
from code
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
public class TableDemo {
private JFrame jfrm = new JFrame("Table Demo");
private String[] headings = {"From", "Address", "Subject", "Size"};
private Object[][] data = {
{"Wendy", "[email protected]", "Hello Herb", new Integer(287)},
{"Alex", "[email protected]", "Check this out!", new Integer(308)},
{"Hale", "[email protected]", "Found a bug", new Integer(887)},
{"Todd", "[email protected]", "Did you see this?", new Integer(223)},
{"Steve", "[email protected]", "I'm back", new Integer(357)},
{"Ken", "[email protected]", "Arrival time change", new Integer(512)}
};
private JTable table = new JTable(data, headings);
private JScrollPane jsp = new JScrollPane(table);
private JLabel jl;
public TableDemo() {
jl = new JLabel("whatever but not empty JLabel");
jsp.getViewport().setBackground(Color.ORANGE);
table.setOpaque(false); //
table.setFillsViewportHeight(true);
table.setPreferredScrollableViewportSize(table.getPreferredSize());
jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jfrm.add(jsp);
jfrm.add(jl, BorderLayout.NORTH);
jfrm.pack();
jfrm.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new TableDemo();
}
});
}
}
Upvotes: 4
Reputation: 73568
It depends what you want to do.
You can use them both, but JScrollPane
will not (at least in usual situations) create a viewport larger than the preferred size of the table.
This may depend on LayoutManagers and possible other components next to the scrollpane.
Upvotes: 1