如何设置 JSplitPane-Divider 折叠/展开状态?
我有一个带有 JSplitPane 的 JFrame,它是 OneTouchExpandable。 我想记住 JFrame 上 JSplitPane 的最后一个分隔符位置,并在重新打开 JFrame 时恢复位置。
它工作得很好,但如果用户通过 oneTouchExpandable UI-Widget 展开一侧,那么 我在处理时仅存储“int”位置,并再次将“int”位置设置回来,结果是在 JFrame 调整大小时,JSplitPane-Divider 跳转到折叠的组件首选大小。
如何获取/设置折叠/展开状态?
编辑
现在:调整大小行为正常,但它与第一次打开的行为不完全相同 - 因为现在我没有MinimumDividerLocation。我想要 SnapIn,但更想要折叠状态。
public class SplitPaneState {
public static void main( String[] args ) {
SwingUtilities.invokeLater( new Runnable() {
@Override
public void run() {
new SplitPaneState().createAndSowGUI();
}
});
}
private int position = -1;
private Dimension size = new Dimension( 500, 300 );
private void createAndSowGUI() {
final JFrame frame = new JFrame("frame");
frame.setSize( 200, 100 );
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.setLocationRelativeTo( null );
frame.getContentPane().add( new JButton( new AbstractAction(){
{
putValue( Action.NAME, "Open Dialog" );
}
@Override
public void actionPerformed( ActionEvent e ) {
final JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, new JLabel( "left Component" ), new JLabel( "right Component" ));
splitPane.setContinuousLayout( true );
splitPane.setOneTouchExpandable( true );
if(position != -1) {
boolean LeftIsCollapsed = position < splitPane.getMinimumDividerLocation();
if(LeftIsCollapsed) {
splitPane.getLeftComponent().setMinimumSize(new Dimension()); // fix by Martijn Courteaux
splitPane.setDividerLocation(0.0d); // fix by Martijn Courteaux
}else {
splitPane.setDividerLocation(position);
}
}
JDialog dialog = new JDialog(frame,"dialog"){
@Override
public void dispose() {
position = splitPane.getDividerLocation();
size = this.getSize();
super.dispose();
}
};
dialog.setSize( size );
dialog.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
dialog.setLocationRelativeTo( frame );
dialog.getContentPane().add( splitPane );
dialog.setVisible( true );
}
}
));
frame.setVisible( true );
}
}
I have a JFrame with a JSplitPane that is OneTouchExpandable.
I want to remember the last Divider position of the JSplitPane on JFrame dispose and restore the Position if the JFrame is reopened.
It works well, but if the User expand one Side via the oneTouchExpandable UI-Widget then
I store only the 'int'-Position on dispose and set the 'int'-Position back again with the consequence on JFrame-resizing the JSplitPane-Divider jumps to the collapsed Component preferredSize.
How can I get/set the collapse/expand State?
EDIT
Now: the resize-Behavior is OK, but it is not exactly the same behavior like the first-time-open - cause now I have no MinimumDividerLocation. I wanted the SnapIn but further the collapsedState.
public class SplitPaneState {
public static void main( String[] args ) {
SwingUtilities.invokeLater( new Runnable() {
@Override
public void run() {
new SplitPaneState().createAndSowGUI();
}
});
}
private int position = -1;
private Dimension size = new Dimension( 500, 300 );
private void createAndSowGUI() {
final JFrame frame = new JFrame("frame");
frame.setSize( 200, 100 );
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.setLocationRelativeTo( null );
frame.getContentPane().add( new JButton( new AbstractAction(){
{
putValue( Action.NAME, "Open Dialog" );
}
@Override
public void actionPerformed( ActionEvent e ) {
final JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, new JLabel( "left Component" ), new JLabel( "right Component" ));
splitPane.setContinuousLayout( true );
splitPane.setOneTouchExpandable( true );
if(position != -1) {
boolean LeftIsCollapsed = position < splitPane.getMinimumDividerLocation();
if(LeftIsCollapsed) {
splitPane.getLeftComponent().setMinimumSize(new Dimension()); // fix by Martijn Courteaux
splitPane.setDividerLocation(0.0d); // fix by Martijn Courteaux
}else {
splitPane.setDividerLocation(position);
}
}
JDialog dialog = new JDialog(frame,"dialog"){
@Override
public void dispose() {
position = splitPane.getDividerLocation();
size = this.getSize();
super.dispose();
}
};
dialog.setSize( size );
dialog.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
dialog.setLocationRelativeTo( frame );
dialog.getContentPane().add( splitPane );
dialog.setVisible( true );
}
}
));
frame.setVisible( true );
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
我发现可以通过将组件的最小尺寸设置为 new Dimension() 来折叠分割面板的一侧,然后设置分隔线位置:
您可以使用这些设置来存储和恢复折叠/展开状态。
I found that it is possible to collapse one side of the splitpane by setting the minimum size of the component to
new Dimension()
and then set the divider location:You can play with these settings to store and restore the collapse/expand state.
强制分隔线位置为非常小/很大的值以隐藏顶部/底部组件是可行的,但由于组件最小尺寸,当调整分割窗格大小时会失败。将该大小设置为 0(如接受的答案中建议的那样)是可行的,但在某些情况下您不能/不想覆盖它。
查看
BasicSplitPaneUI
和关联的类后,发现“一键展开”按钮正在调用BasicSPlitPaneUI.setKeepHidden(true)
,因此分隔线将粘在任一端调整大小时。不幸的是,该方法是包私有的,但可以使用内省来设置关联的keepHidden字段,如所示另一个答案:
Forcing the divider position to a very small/large value to hide the top/bottom component works, but is defeated when the split pane gets resized, because of the component minimum size. Setting that size to 0 (as proposed in the accepted answer) works, but there are cases when you cannot/don't want to override that.
After looking into the
BasicSplitPaneUI
and associated classes, it turns out the "one touch expanding" buttons are callingBasicSPlitPaneUI.setKeepHidden(true)
, so the divider will stick to either end when resized.Unfortunately, that method is package-private but setting the associated
keepHidden
field can be done using introspection, as shown in another answer:我改进了切换功能的版本:
I improved version of toggle function:
隐藏对话框/框架是一个选项吗?
Is hiding your dialog/frame an option?
http://docs.oracle.com/javase/ 7/docs/api/javax/swing/JSplitPane.html
所以基本上你需要创建整个 UI,在主 JFrame 上调用 .pack()
之后您可以使用 JSplitPane.setDividerLocation(double)。如果您在 UI 布局之前执行此操作并且完成所有这些操作,则该方法将不会执行任何操作,正如文档中所述并且您已经经历过的那样。
http://docs.oracle.com/javase/7/docs/api/javax/swing/JSplitPane.html
So basically you need to have created your whole UI, called .pack() on the main JFrame
AND after that you can use JSplitPane.setDividerLocation(double). If you do it before UI layouting and all that stuff is done, the method will just do nothing as it states in the documentation and you already experienced.
JSplitPane 有一个方法 setDividerLocation(double),它将分隔线位置设置为 JSplitPane 大小的百分比。
我前段时间尝试创建类似的功能。我也有同样的问题。但即使我使用 setDividerLocation(double) 方法,它也无法正常工作。我相信这只是 JSplitPane 错误。
JSplitPane has a method setDividerLocation(double), which sets the divider location as a percentage of the JSplitPane's size.
I tried to create similar functionality some time ago. I had the same problem. But even when I use the setDividerLocation(double) method, it didn't work properly. I believe that it's just JSplitPane bug.