JSplitPane: is there a way to show/hide one of the

2019-03-28 11:57发布

问题:

I have a JSplitPane with two components, A and B, but sometimes I want to be able to hide B, so that either of the following are true:

  • components A and B are visible in the JSplitPane
  • only component A is visible in the space occupied by the JSplitPane

Is there a way to do this?

回答1:

Heck, I'll throw in an attempt at a solution...

import java.awt.Dimension;
import java.awt.event.*;
import javax.swing.*;

public class Test {
   public static void main(String[] args) {
      JFrame frame = new JFrame();
      final JPanel contentPane = (JPanel)frame.getContentPane();

      final JButton leftBtn = new JButton("Left Button");
      final JButton rightBtn = new JButton("Right Button");
      final JSplitPane jsp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
            leftBtn, rightBtn);
      ActionListener actionListener = new ActionListener() {
         public void actionPerformed(ActionEvent e) {
            JButton source = (JButton)e.getSource();
            if (jsp.isVisible()) {
               jsp.remove(rightBtn);
               jsp.remove(leftBtn);
               jsp.setVisible(false);
               contentPane.removeAll();
               contentPane.add(source);
            } else {
               contentPane.removeAll();
               jsp.setLeftComponent(leftBtn);
               jsp.setRightComponent(rightBtn);
               jsp.setDividerLocation(0.5);
               jsp.setVisible(true);
               contentPane.add(jsp);
            }
            contentPane.revalidate();
            contentPane.repaint();
            source.requestFocusInWindow();
         }
      };
      rightBtn.addActionListener(actionListener);
      leftBtn.addActionListener(actionListener);
      contentPane.add(jsp);
      contentPane.setPreferredSize(new Dimension(800, 600));
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
      jsp.setDividerLocation(0.5);
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   }
}


回答2:

I found problems with Hovercraft Full Of Eels' version and made my own.

Hovercraft Full Of Eels' one works, nevertheless graphical bug appears if you click a button, resize the frame, then click again the button ; also like amol said, you may want the splitter position to remain during the process.

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.UIManager;

public class JSplitPaneShowHidePane {
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        JPanel contentPane = (JPanel)frame.getContentPane();

        final JButton leftBtn = new JButton("Left Button");
        final JButton rightBtn = new JButton("Right Button");
        final JSplitPane jsp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
                leftBtn, rightBtn);
        ActionListener actionListener = new ActionListener() {
            private int loc = 0;
            public void actionPerformed(ActionEvent e) {
                JButton source = (JButton)e.getSource();
                if(jsp.getLeftComponent().isVisible() && jsp.getRightComponent().isVisible()){
                    loc = jsp.getDividerLocation();
                    jsp.setDividerSize(0);
                    jsp.getLeftComponent().setVisible(source == leftBtn);
                    jsp.getRightComponent().setVisible(source == rightBtn);
                }else{
                    jsp.getLeftComponent().setVisible(true);
                    jsp.getRightComponent().setVisible(true);
                    jsp.setDividerLocation(loc);
                    jsp.setDividerSize((Integer) UIManager.get("SplitPane.dividerSize"));
                }
            }
        };
        rightBtn.addActionListener(actionListener);
        leftBtn.addActionListener(actionListener);
        contentPane.add(jsp);
        frame.pack();
        frame.setSize(800, 600);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        jsp.setDividerLocation(0.5);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}


回答3:

Assume HORIZONTAL_SPLIT split with two components (A on left and B on right)

Here is how you would hide A and let B take up all the splitpane's space


myButton.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        mySplitPane.setDividerSize(0);
        mySplitPane.setDividerLocation(mySplitPane.getLocation().x);
    }
});

To hide component B and show A -


...
  mySplitPane.setDividerLocation(pane.getLocation().x+pane.getSize().width);
...

If you have a vertical split, use similar approach and switch x with y and width with height

For a complete solution, you will have to listen to resize events (if applicable) and recalculate the divider location (which means you will have store the state of what is currently visible somewhere)



回答4:

If you have references to the component A and B you could user JSplitPane.remove() method or JComponent.setVisible(false) method of the component A or B.

Test code:

    final JFrame f = new JFrame();
    final JSplitPane jsp = new JSplitPane();
    final JButton leftB = new JButton("Left: Hide Self");
    final JButton rightB = new JButton("Right: Show Left");
    jsp.setOneTouchExpandable(true);
    leftB.addActionListener(new ActionListener() {
        @Override public void actionPerformed(ActionEvent e) {
            jsp.remove(leftB);
        }
    });
    rightB.addActionListener(new ActionListener() {
        @Override public void actionPerformed(ActionEvent e) {
            jsp.setLeftComponent(leftB);
        }
    });
    jsp.setLeftComponent(leftB);
    jsp.setRightComponent(rightB);
    f.add(jsp);
    f.setSize(800, 600);
    f.setVisible(true);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


回答5:

I use this to toggle a log panel at the bottom of a frame:

private void toggleLogPanel() 
{
  if(m_logPanel.isShowing())
  {
    m_logDimension = m_logPanel.getSize();
    m_splitpane.setBottomComponent(null);
    m_splitpane.setDividerSize(0);
  }
  else
  {
    m_logPanel.setPreferredSize(m_logDimension);
    m_splitpane.setBottomComponent(m_logPanel);
    m_splitpane.setDividerSize(new JSplitpane().getDividerSize());
  }

  m_splitpane.resetToPreferredSizes();
}

This remembers and restores the component size.