How to set JSplitPane-Divider collapse/expand Stat

2020-02-26 09:56发布

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 );
    }
}

7条回答
我想做一个坏孩纸
2楼-- · 2020-02-26 10:45

I improved version of toggle function:

/**
 * 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();
    }
}
查看更多
登录 后发表回答