Создание элемента в BorderLayout занимает правильный размер - PullRequest
0 голосов
/ 25 октября 2018

Я пытаюсь сделать простую рамку светофора.Это делается с помощью основного кадра 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();
        }
    });

}

, который затем, как видно, добавляет 3 TrafficLight компонентов, основанных на JPanel и имеющих следующий код:

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

Это действительно то, что я хочу, он рисует все 3 круга, как и ожидалось, хотя большинство северного (зеленого) и южного (красного) света отключено.Я предполагаю, что это потому, что север / юг намного меньше центра.

enter image description here

Я пытался использовать setSize();, чтобы установить размерпанелей до размера кругов, однако это не работает.Есть ли способ сделать так, чтобы полный круг был виден?

Ответы [ 2 ]

0 голосов
/ 25 октября 2018

Таким образом, большинству менеджеров компоновки потребуются некоторые «подсказки», которые должны быть предоставлены компонентами, чтобы знать, как они хотят быть размеченными.

Вам нужно будет переопределить 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 егоown и the должны контролироваться извне, но это я

setBounds(100, 100, 800, 600);

Лучше всего избегать, используйте pack(), чтобы изменить размер окна до желаемого размера содержимого, и setLocation, чтобы расположить его

.
0 голосов
/ 25 октября 2018

Простое исправление, необходимо использовать setPreferredSize (), а не setSize.

...