2010-09-06 24 views
7

Tôi gặp vấn đề khó chịu với người quản lý bố cục của Java. Tôi có tình huống sau: Trong bảng điều khiển A là hai bảng khác B với bố cục tuyệt đối và C bằng FlowLayout. B được tùy chỉnh cao và có kích thước cố định được đặt qua setPreferredSize. C phải có cùng một chiều rộng B nhưng nếu không có chiều cao thay đổi, tùy thuộc vào số lượng thành phần được thêm vào luồng. Kết quả A sau đó sẽ có chiều rộng cố định và A.height + B.height làm chiều cao - ít nhất đó là những gì tôi muốn.Chiều rộng cố định, chiều cao thay đổi trong JPanel với luồng

Tuy nhiên những gì tôi nhận được là chiều rộng của bảng điều khiển Một không được cố định ở tất cả (ngay cả khi tôi đặt kích thước ưa thích của nó), và các nội dung trong bảng C không tự động gói mà thay vào đó được hiển thị trong một đường dài. Tất nhiên điều này cũng làm cho B có chiều rộng lớn hơn mức cần thiết.

Tôi có thể làm gì để khắc phục điều đó? Có bố cục nào tốt hơn hay tôi phải mô phỏng tất cả bằng cách sử dụng bố cục tuyệt đối?

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.FlowLayout; 

import javax.swing.BoxLayout; 
import javax.swing.JButton; 
import javax.swing.JPanel; 

public class Test extends JPanel 
{ 
    public Test() 
    { 
     this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); 

     JPanel top = new JPanel(null); 
     top.setBackground(Color.GREEN); 
     top.setPreferredSize(new Dimension(200, 20)); 
     JPanel flowPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 2, 2)); 

     this.add(top); 
     this.add(flowPanel); 

     flowPanel.add(new JButton("x")); 
     flowPanel.add(new JButton("x")); 
     flowPanel.add(new JButton("x")); 
     flowPanel.add(new JButton("x")); 
     flowPanel.add(new JButton("x")); 
     flowPanel.add(new JButton("x")); 
     flowPanel.add(new JButton("x")); 
     flowPanel.add(new JButton("x")); 
     flowPanel.add(new JButton("x")); 
     flowPanel.add(new JButton("x")); 
     flowPanel.add(new JButton("x")); 
     flowPanel.add(new JButton("x")); 
    } 
} 

Trả lời

9

Wrap Layout sẽ giúp ích.

+0

Điều đó thực sự hoạt động khá tốt! Nếu không ai đến với một giải pháp bản địa, đây là những gì tôi sẽ đi với. Cảm ơn bạn! Rất tệ khi các trình quản lý bố cục chuẩn tiếp tục thất bại trong các tình huống chung (ít nhất là với tôi) và bạn luôn kết thúc bằng một tùy chỉnh mới ..:/ – poke

+0

@poke: Đối với tôi, điều này thể hiện một loại thiên vị lựa chọn— Tôi có xu hướng quên rằng bố cục chuẩn thường chỉ hoạt động! 'WrapLayout' cũng là một ví dụ tốt về cách viết trình quản lý của riêng mình. – trashgod

0

Cách tốt nhất để cung cấp các loại cấu hình xem tiên tiến mà bạn mong muốn là bằng cách thay thế bạn FlowLayout bởi mạnh GridBagLayoutManager. Cần lưu ý rằng các ràng buộc, thường được biểu thị bằng GridBagConstraints, dễ hiểu hơn nhiều khi sử dụng các lớp con thông thạo, như GBC.

Cuối cùng, như mọi khi, bạn nên xem xét xem Swing tutorial.

+0

Hmm, cảm ơn các liên kết (đặc biệt là GBC ^^), tuy nhiên tôi không chắc chắn cách tạo lại hiệu ứng FlowLayout đã cho tôi với GridBagLayout. Tôi thực sự muốn bọc các thành phần (ở đây: các nút) vào dòng tiếp theo, không có đủ chỗ vì chiều rộng cố định của JPanel mẹ. – poke

0
  1. Bạn không nên thêm trẻ em vào khung trực tiếp. Luôn thêm vào contentPane ->this.getContentPage().add(...)

  2. Để bố cục của bạn hoạt động, hãy đặt JPanel với GridBagLayout trong trang nội dung và làm cho bảng điều khiển đó lấp đầy trang nội dung.

  3. Cung cấp các cột GridBagLayout 2.

Bây giờ bạn không thể tắt kích thước ngang của cửa sổ, vì vậy bạn phải tìm cách khác để xử lý thêm không gian. Tôi đề nghị cung cấp cho cột đầu tiên một chiều rộng cố định (đặt fill=NONE) và để bảng điều khiển C lấp đầy khoảng trống còn lại.

Nếu bạn đặt tất cả các kích thước (tối thiểu, tối đa, ưa thích) của bảng điều khiển B thành kích thước ưa thích, nó sẽ không thay đổi kích thước của nó nữa.

Mẹo: Nếu bố cục Swing không hoạt động, hãy lồng nó trong bố cục khác.

+1

Về điểm 1: "Để thuận tiện,' add' và các biến thể của nó, 'remove' và' setLayout' đã bị ghi đè để chuyển tiếp tới 'contentPane' nếu cần." http://download.oracle.com/javase/6/docs/api/javax/swing/JFrame.html – trashgod

+0

Lưu ý rằng tôi không làm việc bên trong Khung/Cửa sổ, nhưng lớp thực tế của tôi ở trên là bản thân JPanel . Đó là bảng điều khiển * A * từ mô tả của tôi và được sử dụng trong một bố cục khác mà bố cục sẽ không thay đổi kích thước của nó. – poke

+0

@trashgod: Đó là từ Java 6. –

0

Tất cả những gì bạn đặt trong một LINE_END hoặc LINE_START một phần của một BorderLayout sẽ giữ cố định chiều rộng của nó: Chỉ có chiều cao sẽ được thay đổi kích cỡ nếu container được thay đổi kích cỡ

Bắc và Nam là chiều rộng biến

CENTER là chiều rộng & chiều cao biến

LINE_START & LINE_END chỉ biến chiều cao

Vì vậy, tôi đề nghị bạn đặt 'C' container của bạn trong loại BorderL ayout area

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