在JSplitPane
,你有setOneTouchExpandable
方法,它提供了2个按钮,以快速完全隐藏或完整显示JSplitPane
。
我的问题是你怎么能以编程方式“点击”JSplitPane
上的隐藏按钮?
我可能错误地解释了自己。我希望splitpane在开始时只显示2个组件中的一个(这就是我点击的意思)。
这有效:
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);
}
});
}
}
但用0.0
取代1.0
并不能隐藏正确的组件。这是我的问题!
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);
}
});
}
}
用1.0替换0.0,你就得到了我的问题
阅读精细手册并解决问题。
此方法会立即根据其当前大小更改拆分窗格的大小。如果未正确实现拆分窗格并且在屏幕上,此方法将无效...
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);
}
});
}
}
你可以简单地使用这个:
public void setDividerLocation(double proportionalLocation)
splitPane.setDividerLocation(0.0d);
要么。
splitPane.setDividerLocation(1.0d);
取决于您是要隐藏左侧组件的第一个还是右侧组件。
这是另一个解决方案,可能有点脏,但它的工作原理;)我希望代码说明一切。
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();
}
}
以及如何使用它的示例:
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> <br>Left Component<br> </body></html>");
JButton jBRight = new JButton("<html><body> <br>Right Component<br> </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> <br>Up Component<br> </body></html>");
JButton jBDown = new JButton("<html><body> <br>Down Component<br> </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();
}
}
解决setDividerLocation(1.0)
在框架变得可显示之前无法工作的问题,可以使用AncestorListener
:
sp.addAncestorListener(new AncestorListener {
def ancestorAdded (event: AncestorEvent): Unit = sp.setDividerLocation(1.0)
def ancestorRemoved(event: AncestorEvent): Unit = ()
def ancestorMoved (event: AncestorEvent): Unit = ()
})
@0__'s answer暗示您应该使用AncestorListener
来设置分频器位置,并将其考虑在内(ComponentListener
是不够的,我不知道为什么)。
但是,这还不够:如果分割平面以某种方式调整大小(例如,因为它的布局管理器决定它应该,当框架已经调整大小时),您想要隐藏的组件的一小部分仍将显示。这是由于组件最小尺寸不为零。它可以通过使用setMinimumSize(new Dimension())
对其进行归零来解决(如that other answer中所述),但如果这不是一个选项,则可以入侵分割窗格UI:
如果你使用标准的BasicSplitPaneUI
,你可以破解它的keepHidden
布尔字段并强制它到true
,所以分隔符将坚持到任何一方:
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) { }
});