java 适合 JTable 以填充 JPanel
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12701680/
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
Fit JTable to fill the JPanel
提问by Chris
Hi here are my codes for my table settings:
嗨,这是我的表格设置代码:
String [] column = {"MacAddress","PcName","OperatingSystem","IpAddress","Port","Status"};
model = new DefaultTableModel(0,column.length);
model.setColumnIdentifiers(column);
mainTable = new JTable(model);
mainTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
for(int i=0;i<=column.length-1;i++){
mainTable.getColumnModel().getColumn(i).setPreferredWidth(300);
}
pane = new JScrollPane(mainTable);
pnlTabel = new JPanel();
pnlTabel.setBorder(BorderFactory.createTitledBorder(""));
pnlTabel.setPreferredSize(new Dimension(dim.width*70/100, dim.height*60/100));
pnlTabel.add(pane);
addMainPanel(pnlTabel);
Here is my addMainPanel() function:
这是我的 addMainPanel() 函数:
public void addMainPanel(Component pnl){
mainPanel.add(pnl);
mainPanel.revalidate();
}
And here is my code for my mainPanel:
这是我的 mainPanel 代码:
mainPanel = new JPanel();
mainPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
add(mainPanel,"Center");
and I'm using border layout for my frame:
我正在为我的框架使用边框布局:
setLayout(new BorderLayout(0,0));
My problem is that, even i use this set of code to set my JTable to fit but it seems to fail all the this, this code:
我的问题是,即使我使用这组代码来设置我的 JTable 以适应但它似乎失败了所有这些,这段代码:
mainTable.setAutoResizeMode(JTa![enter image description here][1]ble.AUTO_RESIZE_OFF);
for(int i=0;i<=column.length-1;i++){
mainTable.getColumnModel().getColumn(i).setPreferredWidth(300);
}
When is use that code, my jtable does not resize but only add on a horizontal scroll bar at the bottom.
何时使用该代码,我的 jtable 不会调整大小,而只会在底部添加水平滚动条。
回答by kleopatra
No offense meant but .. your code and consequently your question is a mess ;-) Plus you don't explain what exactly you want to achieve.
没有冒犯的意思,但是 .. 你的代码和因此你的问题是一团糟;-) 另外你没有解释你到底想要实现什么。
Trying to detangle, taking the nested layouts/resizing characteristics (as seen in the snippets, might not be complete):
尝试梳理,采用嵌套布局/调整大小特征(如片段所示,可能不完整):
frame // BorderLayout
mainPanel // FlowLayout
pnlTabel // FlowLayout, hard-coded prefSize
pane // scrollPane
mainTable // auto-resize-off
Aside: intentionally kept untelling names to demonstrate how mixing naming schemes tend to contribute to overall confusion :-) Doesn't really matter whether you decide for pre or postFixing some type-related marker, but if you do be consistent.
旁白:故意保留令人费解的名称以展示混合命名方案如何导致整体混乱:-) 无论您决定使用 pre 还是 postFixing 某些与类型相关的标记,都没有关系,但如果您确实保持一致。
In that hierarchy, there are two levels of FlowLayout which basicallywill layout their children at their respective prefs and adjusting their own pref accordingly, lestthe pref were hard-coded on the level of the pnlTable: however the table's pref will be changed (by changing the column prefs) it cannotbubble further up because ... hard-coding the pref leads notcalculating its size (neither by layoutManager and nor uiDelegate, both never get a chance to do it)
在该层次结构中,FlowLayout 有两个级别,它们基本上会将他们的孩子布局在各自的首选项并相应地调整他们自己的首选项,以免首选项在 pnlTable 的级别上进行硬编码:但是表的首选项将被更改(通过更改列首选项)它不能进一步冒泡,因为......硬编码首选项导致不计算其大小(既不是由 layoutManager 也不是 uiDelegate,两者都没有机会这样做)
Another issue - the more interesting one :-) - is that the JScrollPane is somewhat special in
另一个问题 - 更有趣的一个 :-) - JScrollPane 在
- calculating its own prefSize from its view's pref/scrollablePrefViewportSize depending on whether or not the view implements Scrollable (JTable does so, though in a crappy way)
- being a validationRoot: invalidating the view (or any children) doesn't bubble further up the hierarchy
- 根据视图是否实现 Scrollable 从其视图的 pref/scrollablePrefViewportSize 计算它自己的 prefSize(JTable 这样做,虽然方式很糟糕)
- 作为validationRoot:使视图(或任何子项)无效不会在层次结构中进一步冒泡
Assuming that you want the table's scrollPane to grow if the prefWidts of the columns change, there are two thingies to tweak:
假设您希望表格的 scrollPane 在列的 prefWidts 发生变化时增长,则有两件事需要调整:
- implement table's getPreferredScrollableWidth to return a value calculated based on the prefWidth of the columns
- revalidate a container higher up in the hierarchy
- 实现表的 getPreferredScrollableWidth 以返回基于列的 prefWidth 计算的值
- 重新验证层次结构中更高的容器
Some code to play with:
一些代码可以玩:
final JTable table = new JTable(50, 10) {
// properties to base a reasonable prefScrollable size
int visibleColumns = 3;
int visibleRows = 10;
// hard-coded default in super
Dimension dummySuper = new Dimension(450, 400);
@Override
public Dimension getPreferredScrollableViewportSize() {
Dimension dim = super.getPreferredScrollableViewportSize();
if (!dummySuper.equals(dim)) return dim;
dim = new Dimension();
for (int column = 0; column < Math.min(visibleColumns, getColumnCount()); column++) {
dim.width += getColumnModel().getColumn(column).getPreferredWidth();
}
dim.height = visibleRows * getRowHeight();
return dim;
}
};
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
for (int i = 0; i < table.getRowCount(); i++) {
table.setValueAt("row: " + i, i, 0);
}
JComponent tablePanel = new JPanel();
tablePanel.add(new JScrollPane(table));
Action sizeColumns = new AbstractAction("size columns") {
int prefWidth = 75;
@Override
public void actionPerformed(ActionEvent e) {
int newWidth = prefWidth + 15;
for (int i = 0; i < table.getColumnCount(); i++) {
if (table.getColumnModel().getColumn(i).getPreferredWidth() == prefWidth)
table.getColumnModel().getColumn(i).setPreferredWidth(newWidth);
}
prefWidth = newWidth;
// revalidate "higher up" than the table itself
frame.revalidate();
}
};
frame.add(new JButton(sizeColumns), BorderLayout.SOUTH);
回答by icza
If you want a JTable
to fill the available space, you should put it inside a JPanel
which has a BorderLayout
layout manager. Also don't forget about the JScrollPane
which ensures that if the table doesn't fit into the view (e.g. too many rows), scrollbars will appear:
如果要JTable
填充可用空间,则应将其放在JPanel
具有BorderLayout
布局管理器的 a 中。也不要忘记JScrollPane
确保如果表不适合视图(例如行太多),滚动条将出现:
JFrame frame = new JFrame();
// set up frame
JTable table = new JTable();
// Set up table, add data
// Frame has a content pane with BorderLayout by default
frame.getContentPane().add( new JScrollPane( table ), BorderLayout.CENTER );
If you have other content you wish to display besides the table, you can add those to the NORTH, SOUTH, EAST, WEST parts of the content panel (which can be wrapped into other panels if more components are to be placed there).
如果您希望在表格之外显示其他内容,您可以将这些内容添加到内容面板的 NORTH、SOUTH、EAST、WEST 部分(如果要放置更多组件,可以将其包装到其他面板中)。