我在 JScrollPane 上的 JPanel 上有一个 JTree,它是 JSplitPane 的左侧组件。JSplitPane 在它自己的 JScrollPane 上。后者不允许显示其垂直滚动条...相反,每当调整 JFrame 的大小以使某些树看不见时,我希望树面板的垂直滚动条启动...
换句话说,我希望树的滚动窗格的视口始终与框架的内容窗格的高度相同......我已经尝试过各种实验
这是一个SSCCE:
import java.awt.*;
import java.awt.event.ComponentEvent;
import java.lang.reflect.InvocationTargetException;
import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
public class Packing {
public static void main( String[] args ) throws InterruptedException, InvocationTargetException{
EventQueue.invokeLater( new Runnable(){
@Override
public void run() {
JTree jt = new JTree();
DefaultTreeModel model = (DefaultTreeModel)jt.getModel();
for( int i = 0; i < 30; i++ ){
model.insertNodeInto( new DefaultMutableTreeNode( i ),
(DefaultMutableTreeNode)model.getRoot(), 0 );
}
JPanel left_panel = new JPanel();
left_panel.setLayout( new BorderLayout() );
left_panel.add( jt, BorderLayout.WEST );
JScrollPane tree_jsp = new JScrollPane( left_panel );
JSplitPane split_pane = new JSplitPane();
split_pane.setDividerLocation( 0.5d );
split_pane.setLeftComponent( tree_jsp );
JScrollPane split_jsp = new JScrollPane( split_pane );
split_jsp.setVerticalScrollBarPolicy( ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER );
JFrame frame = new JFrame( "Resizing prob" );
frame.getContentPane().add( split_jsp );
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.addComponentListener(new java.awt.event.ComponentAdapter() {
public void componentResized(ComponentEvent e) {
System.out.println( ">>> frame resized" );
}
});
frame.pack();
frame.setVisible( true );
}
});
}
}
编辑
可能已经破解了...将这些行添加到componentResized:
int vp_width = tree_jsp.getViewport().getSize().width;
tree_jsp.getViewport().setPreferredSize(
new Dimension( vp_width, frame.getContentPane().getSize().height - 40 ));
tree_jsp.getViewport().validate();
显然这是一个粗略的草稿...... 40 数字是一个奇怪的数字,我试图理解......在我的机器上,如果这个数字设置为 20 或更少,则调整大小不起作用......
注意,tree_jsp 也必须是最终的,显然,这两行可能会添加到代码的主要部分以理解我疯狂的方法
JTable table = new JTable( 1, 2 );
left_panel.add( table, BorderLayout.EAST );
还有一件事:我们被告知不要使用 setPreferredSize ......也许上述行为可以纯粹通过使用布局来实现......?
编辑 2
最后得出的结论是,我的目标有点偏差:真的,我需要左侧组件上的滚动窗格和右侧组件上的单独滚动窗格。之后,似乎不需要在 JSplitPane(或包含它的 JPanel)上使用滚动窗格:在容器层次结构中保持较低滚动窗格的滚动窗格无疑有时必须存在......但我意识到这是一个相当高的优先级设计这种情况......我发现 BorderLayout 确实在做我想做的事情...... BoxLayout 和 GridLayout 的组合确实有帮助(这都是在试图完全避免 setXXXSize 的背景下)。毫无疑问,答案还在于尝试掌握 GridBagLayout ......