我在JPanel上的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必须做为final,并且这两行代码可能会添加到主要代码中,以使我疯狂地了解该方法。
JTable table = new JTable( 1, 2 );
left_panel.add( table, BorderLayout.EAST );
还有另一件事:我们被告知不要使用setPreferredSize ...也许可以完全通过使用布局来实现上述行为...?
编辑2
最后得出的结论是,我的目标有些偏斜:确实,我需要在左侧组件上有一个滚动窗格,在右侧组件上需要一个单独的滚动窗格。之后,似乎不需要在JSplitPane(或包含它的JPanel)上使用滚动窗格:在容器层次结构中将滚动窗格保持在较低位置的滚动窗格无疑有时是必须存在的……但是我意识到这是非常重要的设计这种情况...
我发现BorderLayout确实在实现我想要的功能时遇到了问题……BoxLayout和GridLayout的组合确实有所帮助(这全是在尝试完全避免setXXXSize的情况下)。毫无疑问,答案还在于尝试掌握GridBagLayout ...
最佳答案
摆脱面板。只需将JTree添加到JScrollPane中:
// JPanel left_panel = new JPanel();
// left_panel.setLayout( new BorderLayout() );
// left_panel.add( jt, BorderLayout.WEST );
// JScrollPane tree_jsp = new JScrollPane( left_panel );
JScrollPane tree_jsp = new JScrollPane( jt );
编辑:您应该始终将树添加到滚动窗格中,因为这是您在没有足够空间时要滚动的内容。但是您可以将滚动窗格添加到面板中,并将面板添加到拆分窗格中:
JScrollPane tree_jsp = new JScrollPane( jt );
JPanel left_panel = new JPanel();
left_panel.setLayout( new BorderLayout() );
left_panel.add( tree_jsp, BorderLayout.WEST );
JSplitPane split_pane = new JSplitPane();
split_pane.setDividerLocation( 0.5d );
// split_pane.setLeftComponent( tree_jsp );
split_pane.setLeftComponent( left_panel );
Edit2:如果只想在lef_panel上使用滚动窗格,则只需要一个滚动窗格。拆分窗格不需要滚动窗格。只需将拆分窗格直接添加到框架中即可:
//frame.getContentPane().add( split_jsp );
frame.add( split_pane );
这种方法可能会导致JTable出现问题,因为总是希望将表添加到滚动窗格中,因为这是显示表头的最简单方法。
同样,由于JDK5,您不需要getContentPane()方法,该框架将为您添加组件到内容窗格。
编辑3:您可以使用
Scollable interface
告诉滚动窗格将添加到滚动窗格的组件的高度固定为滚动窗格的高度。有关帮助程序类,请参见Scrollable Panel。使用此类,您的代码将是://JScrollPane split_jsp = new JScrollPane( split_pane );
//split_jsp.setVerticalScrollBarPolicy( ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER );
ScrollablePanel scrollable = new ScrollablePanel( new BorderLayout() );
scrollable.setScrollableHeight( ScrollablePanel.ScrollableSizeHint.FIT );
scrollable.setScrollableWidth( ScrollablePanel.ScrollableSizeHint.STRETCH );
scrollable.add(split_pane);
JScrollPane split_jsp = new JScrollPane( scrollable );
关于java - 当JFrame执行时,使JScrollPane的层次结构调整大小降低,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18747310/