我有一个带有JSplitPane的JFrame,它是OneTouchExpandable。 我想记住JFlitPane在JFrame上的最后一个Divider位置处理并在重新打开JFrame时恢复Position。
它运行良好,但如果用户通过oneTouchExpandable UI-Widget扩展一侧,那么 我在dispose上只存储'int'-Position并再次设置'int'-Position,结果是JFrame - 调整JSplitPane-Divider的大小,跳转到折叠的Component preferredSize。
如何获取/设置崩溃/展开状态?
修改
现在:调整大小行为是正常的,但它与第一次打开的行为不完全相同 - 因为现在我没有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 );
}
}
答案 0 :(得分:12)
我发现可以通过将组件的最小大小设置为new Dimension()
来折叠拆分窗格的一侧,然后设置分隔符位置:
// Hide left or top
pane.getLeftComponent().setMinimumSize(new Dimension());
pane.setDividerLocation(0.0d);
// Hide right or bottom
pane.getRightComponent().setMinimumSize(new Dimension());
pane.setDividerLocation(1.0d);
您可以使用这些设置来存储和恢复崩溃/展开状态。
答案 1 :(得分:1)
我改进了切换功能的版本:
/**
* toggle JSplitPane
* @param sp - splitpane to toggle
* @param upLeft - is it left or top component to collapse? or button or right
* @param collapse - true component should be collapsed
*/
public void toggle(JSplitPane sp, boolean upLeft, boolean collapse) {
try {
//get divider object
BasicSplitPaneDivider bspd = ((BasicSplitPaneUI) sp.getUI()).getDivider();
Field buttonField;
//get field button from divider
if (upLeft) {
if (collapse != (sp.getDividerLocation() < sp.getMinimumDividerLocation())) {
return;
}
buttonField = BasicSplitPaneDivider.class.getDeclaredField(collapse ? "rightButton" : "leftButton");
} else {
if (collapse != (sp.getDividerLocation() > sp.getMaximumDividerLocation())) {
return;
}
buttonField = BasicSplitPaneDivider.class.getDeclaredField(collapse ? "leftButton" : "rightButton");
}
//allow access
buttonField.setAccessible(true);
//get instance of button to click at
JButton button = (JButton) buttonField.get(((BasicSplitPaneUI) sp.getUI()).getDivider());
//click it
button.doClick();
//if you manage more dividers at same time before returning from event,
//you should update layout and ui, otherwise nothing happens on some dividers:
sp.updateUI();
sp.doLayout();
} catch (Exception e) {
e.printStackTrace();
}
}
答案 2 :(得分:1)
将分隔符位置强制为非常小/较大的值以隐藏顶部/底部组件,但由于组件的最小大小,在分割窗格调整大小时会失败。将该大小设置为0(在接受的答案中建议)有效,但有些情况下您不能/不想覆盖它。
在查看BasicSplitPaneUI
及相关课程后,结果显示&#34;触摸扩展&#34;按钮正在调用BasicSPlitPaneUI.setKeepHidden(true)
,因此分配器将在调整大小时粘在任一端。
不幸的是,该方法是包私有的,但可以使用内省as shown in another answer来设置关联的keepHidden
字段:
sp.setDividerLocation(<0 or 999999>); // Divider is positioned at the top/bottom
Field m = BasicSplitPaneUI.class.getDeclaredField("keepHidden");
m.setAccessible(true);
m.set(sp.getUI(), true); // Divider position will stick
答案 3 :(得分:0)
隐藏对话框/框架是一个选项吗?
// Create the dialog/frame which contains the JSplitPane
final JFrame frame = new JFrame("JSplitPane Problem");
frame.setCloseOperation(JFrame.HIDE_ON_CLOSE);
// ...
myButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
if (!frame.isVisible())
frame.setVisible(true);
}
});
答案 4 :(得分:0)
http://docs.oracle.com/javase/7/docs/api/javax/swing/JSplitPane.html
void javax.swing.JSplitPane.setDividerLocation(double proportionalLocation)
将分隔符位置设置为的百分比 JSplitPane的大小。该方法是根据实现的 setDividerLocation(INT)。这种方法立即改变了大小 拆分窗格基于其当前大小。如果拆分窗格不是 正确实现并在屏幕上,此方法将无效(新的 分隔符位置将变为(当前大小* proportionalLocation) 这是0)。
所以基本上你需要创建你的整个UI,在主JFrame上调用.pack() 之后,您可以使用JSplitPane.setDividerLocation(double)。如果你在UI布局之前完成并完成所有这些工作,那么该方法将不会像文档中所说的那样做任何事情而你已经经历过。
答案 5 :(得分:-1)
JSplitPane有一个方法setDividerLocation(double),它将分隔符位置设置为JSplitPane大小的百分比。 我不久前尝试创建类似的功能。我有同样的问题。但即使我使用setDividerLocation(double)方法,它也无法正常工作。我相信这只是JSplitPane的错误。
答案 6 :(得分:-1)
public static void toggle(JSplitPane sp, boolean collapse) {
try {
BasicSplitPaneDivider bspd = ((BasicSplitPaneUI) sp.getUI()).getDivider();
Field buttonField = BasicSplitPaneDivider.class.
getDeclaredField(collapse ? "rightButton" : "leftButton");
buttonField.setAccessible(true);
JButton button = (JButton) buttonField.get(((BasicSplitPaneUI) sp.getUI()).getDivider());
button.getActionListeners()[0].actionPerformed(new ActionEvent(bspd, MouseEvent.MOUSE_CLICKED,
"bum"));
} catch (Exception e) {
e.printStackTrace();
}
}