Java 如何设置JSplitPane分隔符折叠/展开状态?
我有一个JFrame和一个JSplitPane,它是一对一可扩展的。 我想记住JFrame dispose上JSplitPane的最后一个分隔符位置,并在JFrame重新打开时恢复该位置 它工作得很好,但是如果用户通过oneTouchExpandable UI小部件扩展一侧,那么 我只将“int”位置存储在dispose上,并再次将“int”位置设置回原来的位置,其结果是JFrame调整JSplitPane分隔符的大小时会跳转到折叠组件preferredSize 如何获取/设置折叠/展开状态 编辑 现在:调整大小的行为是可以的,但它与第一次打开时的行为不完全相同-因为现在我没有MinimumDividerLocation。我想要SnapIn,但更想要崩溃状态Java 如何设置JSplitPane分隔符折叠/展开状态?,java,swing,jsplitpane,Java,Swing,Jsplitpane,我有一个JFrame和一个JSplitPane,它是一对一可扩展的。 我想记住JFrame dispose上JSplitPane的最后一个分隔符位置,并在JFrame重新打开时恢复该位置 它工作得很好,但是如果用户通过oneTouchExpandable UI小部件扩展一侧,那么 我只将“int”位置存储在dispose上,并再次将“int”位置设置回原来的位置,其结果是JFrame调整JSplitPane分隔符的大小时会跳转到折叠组件preferredSize 如何获取/设置折叠/展开状态 编
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 );
}
}
公共类SplitPaneState{
公共静态void main(字符串[]args){
SwingUtilities.invokeLater(新的Runnable(){
@凌驾
公开募捐{
新建SplitPaneState().createAndSowGUI();
}
});
}
私有整数位置=-1;
私有维度大小=新维度(500300);
私有void createAndSowGUI(){
最终JFrame=新JFrame(“框架”);
框架设置尺寸(200100);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(空);
frame.getContentPane().add(新的JButton(新的AbstractAction()){
{
putValue(Action.NAME,“打开对话框”);
}
@凌驾
已执行的公共无效操作(操作事件e){
最终JSplitPane拆分窗格=新JSplitPane(JSplitPane.HORIZONTAL_SPLIT,新JLabel(“左组件”)、新JLabel(“右组件”);
splitPane.setContinuousLayout(true);
splitPane.setOneTouchExpandable(true);
如果(位置!=-1){
布尔值LeftIsCollapsed=position
JSplitPane有一个方法setDividerLocation(double),它将分隔器位置设置为JSplitPane大小的百分比。
不久前,我尝试创建类似的功能。我也有同样的问题。但即使我使用setDividerLocation(double)方法,它也不能正常工作。我相信这只是JSplitPane的bug。我发现可以通过将组件的最小尺寸设置为
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);
您可以使用这些设置来存储和恢复折叠/展开状态。隐藏对话框/框架是一个选项吗
// 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);
}
});
我改进了切换功能的版本:
/**
* 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();
}
}
/**
*切换JSplitPane
*@param sp-要切换的拆分窗格
*@param upLeft-它是左组件还是顶部组件要折叠?还是按钮还是右边
*@param collapse-应折叠true组件
*/
公共无效切换(JSplitPane sp、布尔upLeft、布尔折叠){
试一试{
//获取分隔器对象
BasicSplitPaneDivider bspd=((BasicSplitPaneUI)sp.getUI()).getDivider();
字段按钮字段;
//从分配器获取字段按钮
如果(英尺){
如果(折叠!=(sp.getDividerLocation()sp.getMaximumDividerLocation()){
返回;
}
buttonField=BasicSplitPaneVider.class.getDeclaredField(折叠?“leftButton”:“rightButton”);
}
//允许访问
按钮字段。设置可访问(true);
//获取要单击的按钮的实例
JButton button=(JButton)buttonField.get(((BasicSplitPaneUI)sp.getUI()).getDivider());
//点击它
button.doClick();
//如果您在从活动返回之前同时管理多个分隔符,
//您应该更新布局和ui,否则在某些分区上不会发生任何事情:
sp.updateUI();
p.doLayout();
}捕获(例外e){
e、 printStackTrace();
}
}
void javax.swing.JSplitPane.setDividerLocation(双比例分配)
将分割线位置设置为分割线的百分比
JSplitPane的尺寸。该方法是根据以下方面实现的:
setDividerLocation(int)。此方法会立即更改文件的大小
基于当前大小的拆分窗格。如果拆分窗格不可用
正确实现并在屏幕上显示,此方法将无效(新
分隔器位置将变为(当前大小*比例分配)
也就是0)
因此,基本上您需要在主JFrame上创建整个UI,称为.pack()
之后,您可以使用JSpl
/**
* 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();
}
}
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