在Java Swing中,有人能告诉我在JTable实例中将JTable放入JScrollPane并调用setFillsViewportHeight(true)后使用setPreferredScrollableViewportSize()之间的区别吗?我想知道哪一个是好习惯。 Herbert Schildt建议使用setPreferredScrollableViewportSize(),而Horstmann和Cornell建议使用setFillsViewportHeight()。 以下是我所愚弄的简短样本。
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", "Wendy@HerbSchildt.com",
"Hello Herb", new Integer(287) },
{ "Alex", "Alex@HerbSchildt.com",
"Check this out!", new Integer(308) },
{ "Hale", "Hale@HerbSchildt.com",
"Found a bug", new Integer(887) },
{ "Todd", "Todd@HerbSchildt.com",
"Did you see this?", new Integer(223) },
{ "Steve", "Steve@HerbSchildt.com",
"I'm back", new Integer(357) },
{ "Ken", "Ken@HerbSchildt.com",
"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();
}
});
}
}
答案 0 :(得分:4)
这只是关于如何避免使用setPreferredSize,setSize,setBounds的理论,我很熟悉
JTable无法从API中实现的方法返回合理的PreferredSize,例如JTextArea(10,20); JList #setPrototypeDisplayValue和可见Ites的数量
只有setPreferredScrollableViewportSize,setPreferredSize和setSize(ev setBounds)可以为LayoutManager返回关于Dimension原型的通知,否则从API使用默认的PreferredSize for JScrollPane
setPreferredScrollableViewportSize,setPreferredSize和setSize with pack()或witout for JFrame.setSize / setBounds
JTable.setFillsViewportHeight(true)和正确的JFrame.pack()
setPreferredScrollableViewportSize是关于良好的实践,
table.setPreferredScrollableViewportSize(table.getPreferredSize());
是错误的用法,并且可以将JViewport for JTables放大到极限尺寸,正确的尺寸可以从假定的行数计算,注意并非所有行都可以具有相同的高度
使用可调整大小的LayoutManager for JScrollPane而不是FlowLayout
不要使用Jframe.setSize,覆盖PreferredScrollableViewportSize的正确Dimension(这里有几次讨论)
来自代码
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", "Wendy@HerbSchildt.com", "Hello Herb", new Integer(287)},
{"Alex", "Alex@HerbSchildt.com", "Check this out!", new Integer(308)},
{"Hale", "Hale@HerbSchildt.com", "Found a bug", new Integer(887)},
{"Todd", "Todd@HerbSchildt.com", "Did you see this?", new Integer(223)},
{"Steve", "Steve@HerbSchildt.com", "I'm back", new Integer(357)},
{"Ken", "Ken@HerbSchildt.com", "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();
}
});
}
}
答案 1 :(得分:1)
这取决于你想做什么。
您可以同时使用它们,但JScrollPane
不会(至少在通常情况下)创建大于表格首选大小的视口。
这可能取决于LayoutManagers以及滚动窗格旁边可能的其他组件。