Java Swing GUI BorderLayout: расположение компонентов - PullRequest
1 голос
/ 27 апреля 2020

Я новичок в Java и играю с простым примером GUI:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;

public class DrawTest {

    class DrawingPanel extends JPanel {

        private Rectangle2D shape;

        public DrawingPanel(Rectangle2D shape) {
            this.shape = shape;
        }

        public void paintComponent(Graphics g) {

            Graphics2D g2D = (Graphics2D) g;            
            super.paintComponent(g2D);  
            g2D.setColor(new Color(31, 21, 1));
            g2D.fill(shape);

        }

    }


    public void draw() {
        JFrame frame = new JFrame();
        Rectangle2D shape = new Rectangle2D.Float();
        final DrawingPanel drawing = new DrawingPanel(shape);

        shape.setRect(0, 0, 400, 400);
        frame.getContentPane().add(BorderLayout.NORTH, new JButton("TestN"));
        frame.getContentPane().add(BorderLayout.SOUTH, new JButton("TestS"));
        frame.getContentPane().add(BorderLayout.EAST, new JButton("TestE"));
        frame.getContentPane().add(BorderLayout.WEST, new JButton("TestW"));
        frame.getContentPane().add(BorderLayout.CENTER, drawing);
        frame.pack();
        frame.setSize(500,500);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setVisible(true);  
    }
}

public class DrawMain {
    public static void main(String[] args) {
        DrawTest test = new DrawTest();
        test.draw();

    }
}

Как и ожидалось, этот код создает рамку с прямоугольником в центре и кнопками вокруг него. Однако, если я изменю код следующим образом:

        frame.getContentPane().add(BorderLayout.NORTH, drawing);
        frame.getContentPane().add(BorderLayout.SOUTH, new JButton("TestS"));
        frame.getContentPane().add(BorderLayout.EAST, new JButton("TestE"));
        frame.getContentPane().add(BorderLayout.WEST, new JButton("TestW"));
        frame.getContentPane().add(BorderLayout.CENTER, new JButton("TestC"));

, кнопка «Test C» получит огромную область посередине, в то время как у прямоугольника недостаточно места. Это даже верно, если я удаляю другие кнопки (TestS, TestE, TestW): я получаю огромную кнопку Test C и крошечную часть прямоугольника (даже не масштабированный прямоугольник) сверху.

Почему прямоугольник не получает достаточно места, когда он рисуется сверху (СЕВЕР), но получает его, когда он рисуется в ЦЕНТРЕ?

1 Ответ

1 голос
/ 30 апреля 2020

DrawingPanel должен @Override getPreferredSize(), чтобы вернуть соответствующий размер.

Менеджер макета примет этот предпочтительный размер как подсказка . Некоторые менеджеры компоновки увеличивают высоту или ширину компонента в соответствии с логикой c компоновки и ограничения. Например, BorderLayout будет растягивать компоненты в PAGE_START / PAGE_END на ширину панели содержимого, а LINE_START / LINE_END - на высоту самого высокого из них или CENTER. GridBagLayout OTOH полностью скрывает / удаляет компонент, для которого недостаточно места, чтобы отобразить его в нужном размере, и вот тут появляется «pack».

Так что измените frame.setSize(500,500); (что не лучше, чем предположение) до frame.pack();, что сделает фрейм минимальным размером, который должен быть , для отображения компонентов, которые он содержит.

...