2011-02-08 130 views
6

我有一個JSplitPane是OneTouchExpandable的JFrame。 我想記住JFrame上JSplitPane的最後一個分隔符位置,如果重新打開JFrame,則處理並恢復位置。如何設置JSplitPane-Divider摺疊/展開狀態?

它工作的很好,但是如果用戶通過oneTouchExpandable UI-Widget擴展一邊,那麼我只在'dispose'中存儲'int'-position,並將'int'-position再次設置爲JFrame-調整JSplitPane-Divider的大小以跳轉到摺疊的組件preferredSize。

如何獲取/設置摺疊/展開狀態?

編輯

現在:調整大小 - 行爲是確定的,但它不是完全一樣的第一次打開相同的行爲 - 因爲現在我沒有MinimumDividerLocation。我想要管理單元,但進一步崩潰狀態。

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

回答

11

我發現,可以通過組件的最小尺寸設置爲new Dimension()崩潰在將splitPane的一側,然後設置分隔條的位置:

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

您可以使用這些設置播放存儲和恢復崩潰/展開狀態。

+0

呀,調整大小,行爲是確定的,但它不是完全一樣的相同的行爲第一次開放的原因現在我沒有MinimumDividerLocation。我想要管理單元,但進一步崩潰狀態。 – oliholz 2011-02-28 15:43:18

+0

嘗試各種建議的解決方案後,我發現以下解決方案可以工作:''pane.getRightComponent()。setMinimumSize(new Dimension()); ';' – 2014-06-20 09:48:45

0

調整JSplitPane有一個方法setDividerLocation(雙),它設置分隔的位置爲JSplitPane的大小的百分比。 前段時間我試圖創建類似的功能。我有同樣的問題。但即使當我使用setDividerLocation(double)方法時,它也不能正常工作。我相信這只是JSplitPane的錯誤。

0

隱藏你的對話框/框架的選項?

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

}); 
0
public static void toggle(JSplitPane sp, boolean collapse) { 
     try { 
      BasicSplitPaneDivider bspd = ((BasicSplitPaneUI) sp.getUI()).getDivider(); 
      Field buttonField = BasicSplitPaneDivider.class. 
        getDeclaredField(collapse ? "rightButton" : "leftButton"); 
      buttonField.setAccessible(true); 
      JButton button = (JButton) buttonField.get(((BasicSplitPaneUI) sp.getUI()).getDivider()); 
      button.getActionListeners()[0].actionPerformed(new ActionEvent(bspd, MouseEvent.MOUSE_CLICKED, 
        "bum")); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
1

我改進切換功能的版本:

/** 
* 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(); 
    } 
} 
0

http://docs.oracle.com/javase/7/docs/api/javax/swing/JSplitPane.html

空隙javax.swing.JSplitPane.setDividerLocation(雙proportionalLocation)

設置分隔位置爲百分比JSplitPane大小的 的年齡。這個方法的實現依據 setDividerLocation(int)。此方法立即根據當前大小更改分割窗格的大小。如果拆分窗格不是 正確實現並在屏幕上,此方法將不起作用(新 分隔符位置將成爲(當前大小*比例位置) 這是0)。

所以基本上你需要有主的JFrame 創建你的整個UI,稱爲.pack()之後,你可以使用JSplitPane.setDividerLocation(雙)。如果你在UI佈局和所有的東西完成之前做了這個,那麼這個方法就不會做任何事情,因爲它在文檔中陳述並且你已經經歷過。

1

將divider位置強制爲非常小/大的值以隱藏頂部/底部組件工作,但由於組件最小大小而導致拆分窗格被重新調整大小時會失敗。將該大小設置爲0(如接受的答案中提出的那樣)可行,但有些情況下您不能/不想重寫該大小。

查看BasicSplitPaneUI和相關類後,發現「單觸式展開」按鈕正在調用BasicSPlitPaneUI.setKeepHidden(true),因此調整大小時,分隔線將固定在任一端。

不幸的是,這種方法是包私有,但將相關keepHidden場可以用內省,as shown in another answer做到:

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