使BorderLayout中的项目占用正确的大小

时间:2018-10-25 03:13:23

标签: java swing layout-manager border-layout

我正在尝试制作一个简单的交通信号灯框架。这是由主框架TrafficBox完成的:

public class TrafficBox extends JFrame {

public TrafficBox() {
    setLayout(new BorderLayout(100,100));
    add(new TrafficLight(Color.GREEN), BorderLayout.NORTH);
    add(new TrafficLight(Color.ORANGE), BorderLayout.CENTER);
    add(new TrafficLight(Color.RED), BorderLayout.SOUTH);
    setBounds(100, 100, 800, 600);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setVisible(true);
}

public static void main(String[] args) {
    // TODO Auto-generated method stub
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            new TrafficBox();
        }
    });

}

然后可以看到,它添加了三个基于TrafficLight的{​​{1}}组件,并具有以下代码:

JPanel

这确实符合我的要求,尽管大部分的北(绿)灯和南(红)灯都被遮挡了,但它按预期绘制了所有3个圆。我认为这是因为北/南点比中心小得多。

enter image description here

我尝试使用public class TrafficLight extends JPanel { private final int BALL_DIAMETER = 100; private Color color; public TrafficLight(Color color) { //setSize(BALL_DIAMETER, BALL_DIAMETER); this.color = color; new Timer(1000, new ActionListener() { public void actionPerformed(ActionEvent e) { repaint(); } }).start(); } public void paintComponent(Graphics g) { g.setColor(color); g.fillOval(0, 0, BALL_DIAMETER, BALL_DIAMETER); } 将面板的大小设置为圆圈的大小,但是这不起作用。有什么办法可以使整个圆圈可见?

2 个答案:

答案 0 :(得分:3)

因此,大多数布局管理器将需要组件提供一些“提示”,以了解他们希望如何布局。

您将需要覆盖getPreferredSize并返回最能满足您需求的尺寸,例如...

public class TrafficLight extends JPanel {

    private final int BALL_DIAMETER = 100;

    //...

    public Dimension getPreferredSize() {
        return new Dimension(BALL_DIAMETER, BALL_DIAMETER);
    }    

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent();
        g.setColor(color);
        g.fillOval(0, 0, BALL_DIAMETER, BALL_DIAMETER);
    }

此外,paintComponent永远不需要成为public,没有其他人可以调用它,并且您应该在执行任何自定义绘画之前调用super.paintComponent()

我也建议为此使用GridLayout

我还认为TrafficLight不需要自己拥有,Timer应该从外部控制,但这就是我

setBounds(100, 100, 800, 600);

最好避免使用pack()将窗口的大小调整为内容的首选大小,然后使用setLocation对其进行定位

答案 1 :(得分:0)

简单修复,需要使用setPreferredSize()而不是setSize。