2010-09-11 25 views
17

Tôi đang cố gắng để có được Giao diện của một JDialog của tôi để phù hợp với một giao diện cụ thể mà tôi đang chuyển sang Java, tôi đã sử dụng một vài LayoutManager trước đây với thành công lớn. để làm việc này. Mục tiêu của tôi là có mặt bên phải (Đông) của JDialog chứa nút "Tìm tiếp theo" và "Hủy" trong thứ tự từ trên xuống và sau đó thêm bất kỳ khoảng trống nào bên dưới sao cho hai nút luôn ở trên cùng của JDialog nhưng vì lý do nào đó, BoxLayout liên tục bỏ qua bất kỳ nỗ lực nào đang thay đổi (đây là nơi tôi bị mất) chiều rộng của JButton. Mã sau.Tại sao BoxLayout không cho phép tôi thay đổi chiều rộng của JButton nhưng hãy để tôi thay đổi chiều cao?

JButton findNext = new JButton("Find Next"); 
JButton cancel = new JButton("Cancel"); 
cancel.setPreferredSize(new Dimension((int)findNext.getPreferredSize().getWidth(), 
    (int)cancel.getPreferredSize().getHeight())); 

JPanel example = new JPanel(); 
example.setLayout(new BoxLayout(example, BoxLayout.Y_AXIS)); 
example.add(findNext); 
example.add(cancel); 
example.add(Box.createGlue()); 

Bất kể tôi cố gắng gì, cancel luôn giữ nguyên kích thước bình thường. Tôi đã thử setMinimumSize()setMaximumSize() với các thông số giống như setPreferredSize không có may mắn. Tôi thậm chí đã thử cancel.setPreferredSize(new Dimension(500, 500)); và chiều cao nút là điều duy nhất được điều chỉnh, nó vẫn giữ lại chiều rộng mặc định nó đã được đưa ra.

Để xóa mọi câu hỏi, dưới đây là hình thức của nó (bây giờ tôi đã hoàn thành nó) và bạn sẽ thấy các nút "Tìm tiếp theo" và "Hủy" không có cùng kích thước.

example image

+0

Tôi đã thêm một liên kết đến câu hỏi chính của JDialog đã hoàn thành để bạn có thể hiểu rõ hơn về vấn đề của mình. –

+0

@Tim Cảm ơn bạn, tôi đã sửa đổi mã để đặt phần thích hợp ở đây, xin lỗi tôi đã bỏ lỡ dấu ngoặc đơn. –

+0

@izuriel - Không sao, tôi chỉ sao chép nó qua Eclipse để chơi với nó một chút và nhận thấy nó bị thiếu, vì vậy muốn sửa nó cho người khác. :) –

Trả lời

40

Tôi biết đây là một câu hỏi cũ nhưng tôi không thực sự thấy một lời giải thích tốt. Vì vậy, vì lợi ích của những người tìm kiếm vấp phải điều này, tôi sẽ cộng thêm hai xu của tôi.

Có ba phương pháp được liên kết với các thành phần định cỡ trong Swing: setPreferredSize(), setMinimumSize() và setMaximumSize(). Tuy nhiên, điểm quan trọng là tùy thuộc vào trình quản lý bố cục cụ thể đang được sử dụng để có hay không nó tôn trọng bất kỳ phương pháp nào trong số này.

Đối BoxLayout (cách bố trí các poster ban đầu được sử dụng):

  • setMinimumSize() - BoxLayout danh dự
  • setMaximumSize này() - BoxLayout danh dự này
  • phương thức setPreferredSize() - nếu X_AXIS đang được sử dụng chiều rộng được vinh danh, nếu Y_AXIS đang được sử dụng chiều cao được vinh danh

OP đang sử dụng một Y_AXIS BoxLayout đó là lý do tại sao chỉ chiều cao của ông là ch tức giận.

Cập nhật: Tôi đặt cùng một trang với cùng thông tin này cho tất cả người quản lý bố cục. Hy vọng rằng nó có thể giúp một số người tìm kiếm ra: http://thebadprogrammer.com/swing-layout-manager-sizing/

+1

Vâng đây là một câu hỏi cũ, và có vấn đề của tôi đã được giải quyết với các câu trả lời trước đó được đưa ra nhưng tôi phải cảm ơn bạn rất nhiều vì đã giải thích chính xác những gì đã gây ra vấn đề này. Tôi không biết nhiều về hoạt động nội bộ của Java như tôi muốn và đang học khá chậm nên tôi thực sự đánh giá cao phản ứng này! Cảm ơn bạn! –

+0

+1 cho bản tóm tắt hay. Nitpicking: nó không phải là _setXX_ trong đó các danh hiệu LayoutManager (hay không), đó là _property_ XX: các thành phần nên thực hiện một cái gì đó hợp lý, đặc biệt là cho maximumSize. Một số thành phần cốt lõi không (như fi một lớp như textField, comboBox ... nên tối đa chiều cao của chúng) – kleopatra

6

Bạn không thể muốn Box.createGlue(), mà "grows as necessary để hấp thụ bất kỳ không gian thêm vào bình chứa của nó." Thay vào đó, hãy sử dụng Box.createVerticalStrut()giữa các nút, như được hiển thị bên dưới và trong số ControlPanel của số simulation này.

example.setLayout(new BoxLayout(example, BoxLayout.Y_AXIS)); 
example.add(findNext); 
Box.createVerticalStrut(10); 
example.add(cancel); 

Phụ Lục:

thêm trong setMaximumSize() làm cho nó hoạt động.

Đây là hành vi mong đợi cho các thành phần có chiều rộng tối đa giống hệt nhau theo chiều dọc BoxLayout, như được mô tả trong Box Layout Features. Chiều rộng ưa thích của vùng chứa trở thành chiều rộng của trẻ em (rộng bằng nhau) và căn chỉnh X trở nên không liên quan.

example.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); 
JButton findNext = new JButton("Find Next"); 
JButton cancel = new JButton("Cancel"); 
Dimension d = findNext.getMaximumSize(); 
cancel.setMaximumSize(new Dimension(d)); 
example.add(findNext); 
example.add(cancel); 
+0

Tôi đánh giá cao phản ứng rác rưởi nhưng tôi nghĩ bạn có thể đã hiểu sai câu hỏi. Vấn đề duy nhất tôi gặp phải là BoxLayout (ít nhất là tôi giả định đây là những gì đang làm) không cho phép hoặc hiển thị bất kỳ thay đổi nào với chiều rộng của hủy JButton mà tôi muốn thực hiện cùng kích thước với JButton findNext . Cái hộp.createGlue(); là có cho mục đích nó đã được dự định, để mất tất cả các không gian dưới hai nút đó sẽ giữ cho các nút ở đầu JDialog. –

+0

@izuriel: Khá đúng, tôi đã đọc sai; lấy làm tiếc. Tôi đã thêm sự hiểu biết của tôi về lý do tại sao 'setMaximumSize()' hoạt động. – trashgod

+0

Một lần nữa, cảm ơn phản hồi, mô tả của bạn cùng với Tim đã giúp tôi hiểu được vấn đề mà tôi đang gặp phải và tôi đánh giá cao tất cả. –

3

Như đã đề cập trong nhận xét về câu hỏi, bạn có thể khắc phục bằng cách chuyển sang setMaximumSize(). Tuy nhiên, như bạn đã lưu ý, setPreferredSize() không hoạt động. Có chuyện gì vậy?

Với nhiều thứ Swing, các thuộc tính được sử dụng để xác định kích thước thành phần thực tế khi sử dụng BoxLayout có phần ngẫu nhiên (theo ý kiến ​​của tôi). Khi xác định cách hiển thị các thành phần, Swing gọi layoutComponent() trên trình quản lý bố cục, đây là số liệu xác định vị trí đặt mọi thứ.

BoxLayout 's thực hiện layoutComponent() liên quan đến một cuộc gọi đến một phương pháp tạo ra SizeRequirements đối tượng cho chiều rộng và chiều cao của mỗi người trong số các thành phần bạn thêm vào JPanel, dựa trên getMinimum/Preferred/MaximumSize() phương pháp của họ.

Sau đó, nó gọi SizeRequirements.calculateAlignedPositions() để xác định giá trị độ rộng chính xác cho từng thành phần, vì hướng của bạn là BoxLayout.Y_AXIS (Chiều cao được tính bằng phương pháp khác).Lấy đoạn từ nguồn, việc thực hiện có liên quan của phương pháp này là như sau:

for (int i = 0; i < children.length; i++) { 
    SizeRequirements req = children[i]; 
    //... 
    int maxAscent = (int)(req.maximum * alignment); 
    int maxDescent = req.maximum - maxAscent; 
    //... 
    int descent = Math.min(totalDescent, maxDescent); 
    //... 
    spans[i] = (int)Math.min((long) ascent + (long)descent, Integer.MAX_VALUE); 
} 

Lưu ý rằng totalDescent là chiều rộng sẵn, do đó descent luôn thiết lập để maxDescent, mà là dựa trên SizeRequirements.maximum, được lấy từ JButton.getMaximumSize() . Giá trị của spans[i] sau đó được sử dụng sau đó trong một cuộc gọi đến JButton.setBounds() làm chiều rộng. Như bạn sẽ thấy, getPreferredSize() không bao giờ được tham gia ở đây, đó là lý do tại sao thiết lập nó không có tác động trong trường hợp này.

+0

Cảm ơn bạn rất nhiều vì sự hỗ trợ và giải thích, tôi sẽ thừa nhận nó ở trên tôi một chút vì đã hiểu nó hoàn toàn ngay bây giờ nhưng tôi có được khái niệm cơ bản về lý do tại sao nó hoạt động theo cách này và tôi đánh giá cao sự giúp đỡ thêm. –

0

Thông thường nếu muốn đảm bảo kích thước của thành phần trong Swing, bạn cần phải gọi setMinimumSize(), setMaximumSize()SetPrefferedSize() có cùng giá trị.

+0

Có, thông thường tôi làm điều này nhưng có vẻ như tôi đã tạo lỗi sao chép toàn bộ (ít nhất là trong trường hợp của tôi) khi tôi sao chép setPreferredSize(), tôi dán nó hai lần, thay đổi một thành setMinimumSize và còn lại vô tình, nghĩ rằng tôi đã thay đổi nó. Một lỗi đơn giản mà tôi đã bỏ qua. Cảm ơn sự hỗ trợ. –

+0

không, bạn không [muốn can thiệp vào thành phần cung cấp gợi ý định cỡ] (http://stackoverflow.com/a/7229519/203657), bao giờ ;-) – kleopatra

+0

@ kleopatra: Tôi biết bạn không nên gây rối với những nhưng khá thường xuyên đến phương pháp này trong tuyệt vọng cố gắng để làm cho công việc bố trí damned. –

-1
button.setMaximumSize(getMaximumSize()); 
0

Nếu bạn đặt các nút của bạn trong một bảng điều khiển GridLayout họ sẽ có cùng chiều rộng.

+0

Cùng với việc lấp đầy tất cả không gian xung quanh chúng, chúng có thể, giống như toàn bộ phía đông của bảng điều khiển giải pháp phi lý tưởng đáng buồn. Trong khi GridLayout phục vụ một mục đích, tôi không nghĩ rằng nó có thể áp dụng để giải quyết vấn đề này, và như đã được mô tả một cách thông tin trong câu trả lời được chấp nhận, giải pháp khá đơn giản. –

Các vấn đề liên quan