2011-02-08 25 views
6

Tôi có một JFrame với một JSplitPane đó là OneTouchExpandable. Tôi muốn nhớ vị trí Divider cuối cùng của JSplitPane trên JFrame vứt bỏ và khôi phục Vị trí nếu JFrame được mở lại.Làm thế nào để thiết lập JSplitPane-Divider sụp đổ/mở rộng Nhà nước?

Nó hoạt động tốt, nhưng nếu người dùng mở rộng một bên thông qua giao diện người dùng tiện ích mộtTouchExpandable thì tôi chỉ lưu trữ 'int'-Position khi vứt bỏ và đặt' int'-Position 'trở lại với hậu quả trên JFrame- thay đổi kích thước JSplitPane-Divider nhảy tới thành phần đã thu gọn được ưa thíchSize.

Làm cách nào tôi có thể nhận/đặt trạng thái thu gọn/mở rộng?

EDIT

Bây giờ là: thay đổi kích thước-Hành vi là OK, nhưng nó không phải là chính xác hành vi tương tự như lần đầu mở - nguyên nhân bây giờ tôi không có MinimumDividerLocation. Tôi muốn SnapIn nhưng tiếp tục là collapsedState.

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

Trả lời

11

tôi thấy rằng nó có thể sụp đổ một bên của splitpane bằng cách thiết lập kích thước tối thiểu của các thành phần để new Dimension() và sau đó thiết lập vị trí dải phân cách:

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

Bạn có thể chơi với các thiết lập để lưu trữ và khôi phục trạng thái thu gọn/mở rộng.

+0

yeah, thay đổi kích cỡ-Hành vi là OK, nhưng nó không phải là chính xác hành vi tương tự như lần đầu tiên mở - nguyên nhân bây giờ tôi không có MinimumDividerLocation. Tôi muốn SnapIn nhưng tiếp tục là collapsedState. – oliholz

+0

Sau khi thử các giải pháp đề xuất khác nhau, tôi tìm thấy giải pháp sau đây để làm việc: '' pane.getRightComponent(). SetMinimumSize (new Dimension()); pane.setResizeWeight (1.0d); '' –

+0

Điều đó làm việc cho tôi (cảm ơn! :)) nhưng vị trí chia không dính khi thay đổi kích thước, đặc biệt là khi bạn không thể ghi đè kích thước tối thiểu thành phần. Xem câu trả lời của tôi để hack nó nếu bạn sử dụng 'BasicSplitPaneUI'. – Matthieu

0

JSplitPane có phương thức setDividerLocation (double), đặt vị trí chia làm phần trăm kích thước của JSplitPane. Tôi đã cố tạo chức năng tương tự một thời gian trước đây. Tôi đã từng gặp vấn đề tương tự. Nhưng ngay cả khi tôi sử dụng phương thức setDividerLocation (double), nó không hoạt động đúng cách. Tôi tin rằng đó chỉ là lỗi JSplitPane.

0

Ẩn tùy chọn hộp thoại/khung hình của bạn?

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

vui lòng cung cấp giải thích ngắn gọn cho câu trả lời của bạn. –

1

tôi phiên bản cải tiến của chức năng chuyển đổi:

/** 
* 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

trống javax.swing.JSplitPane.setDividerLocation (proportionalLocation kép)

Thiết lập chia vị trí dưới dạng phần trăm tuổi của kích thước của JSplitPane là . Phương pháp này được thực hiện theo điều khoản của setDividerLocation (int). Phương pháp này ngay lập tức thay đổi kích thước của ngăn chia dựa trên kích thước hiện tại của nó. Nếu ngăn chia tách không phải là được nhận biết chính xác và trên màn hình, phương pháp này sẽ không có hiệu lực (mới vị trí chia sẽ trở thành (kích thước hiện tại * tỷ lệ thuận) là 0).

Vì vậy, về cơ bản bạn cần phải đã tạo ra toàn bộ giao diện người dùng của bạn, được gọi là .pack() trên JFrame chính VÀ sau đó bạn có thể sử dụng JSplitPane.setDividerLocation (kép). Nếu bạn làm điều đó trước khi bố cục giao diện người dùng và tất cả những thứ đó được thực hiện, phương pháp sẽ không làm gì cả vì nó nêu trong tài liệu và bạn đã trải qua.

1

Bắt buộc vị trí dải phân cách thành giá trị rất nhỏ/lớn để ẩn thành phần trên cùng/dưới cùng, nhưng bị đánh bại khi ngăn chia được thay đổi kích thước do kích thước tối thiểu của thành phần. Đặt kích thước đó thành 0 (như được đề xuất trong câu trả lời được chấp nhận) hoạt động, nhưng có những trường hợp khi bạn không thể/không muốn ghi đè điều đó.

Sau khi xem xét BasicSplitPaneUI và các lớp liên quan, nó chỉ ra các nút "một chạm mở rộng" đang gọi BasicSPlitPaneUI.setKeepHidden(true), vì vậy dải phân cách sẽ dính vào một trong hai đầu khi được thay đổi kích thước.

Thật không may, phương pháp đó là gói tin nhưng thiết lập các liên keepHidden lĩnh vực có thể được thực hiện bằng mẫn, 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 
Các vấn đề liên quan