How can you programmatically install JSplitPane to hide the right / bottom component when OneTouchExpandable is set to true?

In JSplitPane , you have the setOneTouchExpandable method, which provides you with two buttons to quickly completely hide or show JSplitPane .

My question is, how can you programmatically "click" hide a button on JSplitPane ?

Perhaps I misunderstood. I want splitpane to display only one of the two components at startup (this is what I mean by clicking).

It works:

 import javax.swing.*; class SplitPaneDefault { public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { JSplitPane sp = new JSplitPane( JSplitPane.HORIZONTAL_SPLIT, new JTree(), new JTree()); sp.setOneTouchExpandable(true); sp.setDividerLocation(0.0); JOptionPane.showMessageDialog(null, sp); } }); } } 

, but replacing 0.0 with 1.0 does not hide the correct component. It is my problem!

+4
java swing jsplitpane
source share
5 answers
 import javax.swing.*; class SplitPaneDefault { public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { JSplitPane sp = new JSplitPane( JSplitPane.HORIZONTAL_SPLIT, new JTree(), new JTree()); sp.setOneTouchExpandable(true); sp.setDividerLocation(0.0); JOptionPane.showMessageDialog(null, sp); } }); } } 

replace 0.0 with 1.0 and you will get my problem

Read the exact manual and solve the problem.

This method immediately resizes the shared panel based on its current size. If the separation panel is not implemented correctly and on the screen, this method will have no effect ...

SplitPaneDefault

 import javax.swing.*; class SplitPaneDefault { public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { JSplitPane sp = new JSplitPane( JSplitPane.HORIZONTAL_SPLIT, new JTree(), new JTree()); sp.setOneTouchExpandable(true); JFrame f = new JFrame("Split Pane To Right"); f.add(sp); f.pack(); // sp now has a non-zero size! sp.setDividerLocation(1.0); f.setLocationByPlatform(true); f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); f.setVisible(true); } }); } } 
+5
source share

You can simply use this:

 public void setDividerLocation(double proportionalLocation) splitPane.setDividerLocation(0.0d); 

or.

 splitPane.setDividerLocation(1.0d); 

depending on whether you want to hide the left component first or the right component.

+2
source share

Working on a problem that setDividerLocation(1.0) does not work until the frame is displayed, you can use AncestorListener :

 sp.addAncestorListener(new AncestorListener { def ancestorAdded (event: AncestorEvent): Unit = sp.setDividerLocation(1.0) def ancestorRemoved(event: AncestorEvent): Unit = () def ancestorMoved (event: AncestorEvent): Unit = () }) 
+1
source share

@ 0__ answer is a hint that you should use AncestorListener to set the location of the separator and take it into account ( ComponentListener is not enough, I'm not sure why).

However, this is not enough : if the plane split somehow changes (for example, because its layout manager decided that when the frame size was changed), the tiny part of the component that you wanted to hide will show. This is because the minimum component size is not equal to zero. It can be fixed by zeroing it out with setMinimumSize(new Dimension()) (as described in another answer ), but if this is not an option, you can hack the user interface of the split panel:

If you use the standard BasicSplitPaneUI , you can crack its keepHidden boolean field and make it true , so the divider will adhere to either side:

 sp.addAncestorListener(new AncestorListener() { @Override public void ancestorAdded(AncestorEvent event) { sp.setDividerLocation(1.0); // Divider is positioned Field m = BasicSplitPaneUI.class.getDeclaredField("keepHidden"); m.setAccessible(true); m.set(sp.getUI(), true); // Divider position will stick //sp.removeAncestorListener(this); // Uncomment for a one-shot event } @Override public void ancestorRemoved(AncestorEvent event) { } @Override public void ancestorMoved(AncestorEvent event) { } }); 
+1
source share

Here is another solution, maybe a little dirty, but it works;) I hope the code speaks for itself.

 public class ExtOneTouchJSplitPane extends JSplitPane { private static final long serialVersionUID = -2320161961382260438L; JButton jBLeftUp; JButton jBRightDown; public ExtOneTouchJSplitPane() { super(); setOneTouchExpandable(true); extractDividerButtons(); } public ExtOneTouchJSplitPane(int newOrientation) { super(newOrientation); setOneTouchExpandable(true); extractDividerButtons(); } public ExtOneTouchJSplitPane(int newOrientation, boolean newContinuousLayout) { super(newOrientation, newContinuousLayout); setOneTouchExpandable(true); extractDividerButtons(); } public ExtOneTouchJSplitPane(int newOrientation, boolean newContinuousLayout, Component newLeftComponent, Component newRightComponent) { super(newOrientation, newContinuousLayout, newLeftComponent, newRightComponent); setOneTouchExpandable(true); extractDividerButtons(); } public ExtOneTouchJSplitPane(int newOrientation, Component newLeftComponent, Component newRightComponent) { super(newOrientation, newLeftComponent, newRightComponent); setOneTouchExpandable(true); extractDividerButtons(); } private void extractDividerButtons() { BasicSplitPaneUI ui = (BasicSplitPaneUI) getUI(); jBLeftUp = (JButton) ui.getDivider().getComponent(0); jBRightDown = (JButton) ui.getDivider().getComponent(1); } public void oneTouchClickLeft() { jBLeftUp.doClick(); } public void oneTouchClickRight() { jBRightDown.doClick(); } public void oneTouchClickUp() { jBLeftUp.doClick(); } public void oneTouchClickDown() { jBRightDown.doClick(); } } 

And an example of how to use it:

 public class SplitPaneDemo extends JFrame implements Runnable { public static void main(String[] args) { SwingUtilities.invokeLater(new SplitPaneDemo()); } ExtOneTouchJSplitPane hSplitPane; ExtOneTouchJSplitPane vSplitPane; public SplitPaneDemo() { createView(); } public void createView() { setTitle("SplitPane-Demo"); setLayout(new BorderLayout(0, 0)); hSplitPane = new ExtOneTouchJSplitPane(); JButton jBLeft = new JButton("<html><body> &nbsp;<br>Left Component<br> &nbsp;</body></html>"); JButton jBRight = new JButton("<html><body> &nbsp;<br>Right Component<br> &nbsp;</body></html>"); jBLeft.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { hSplitPane.oneTouchClickLeft(); } }); jBRight.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { hSplitPane.oneTouchClickRight(); } }); hSplitPane.setLeftComponent(jBLeft); hSplitPane.setRightComponent(jBRight); add(hSplitPane, BorderLayout.CENTER); vSplitPane = new ExtOneTouchJSplitPane(JSplitPane.VERTICAL_SPLIT); JButton jBUp = new JButton("<html><body> &nbsp;<br>Up Component<br> &nbsp;</body></html>"); JButton jBDown = new JButton("<html><body> &nbsp;<br>Down Component<br> &nbsp;</body></html>"); jBUp.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { vSplitPane.oneTouchClickUp(); } }); jBDown.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { vSplitPane.oneTouchClickDown(); } }); vSplitPane.setTopComponent(jBUp); vSplitPane.setBottomComponent(jBDown); add(vSplitPane, BorderLayout.SOUTH); } @Override public void run() { setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); setSize(400, 400); setVisible(true); hSplitPane.oneTouchClickLeft(); } } 
+1
source share

All Articles