BoxLayout дает неожиданную ширину для пользовательского компонента - PullRequest
0 голосов
/ 25 апреля 2020

У меня есть пользовательский компонент, который очень прост. Он имеет предпочтительный и максимальный размер 100x100 и представляет собой просто красный прямоугольник. Я добавляю это к JPanel, который использует макет коробки. Я ожидаю, что размер пользовательского компонента будет 100x100, но вместо этого он равен 50x100 (всегда половина максимальной ширины).

Вот код:

public class Testing extends JFrame {

    class TestComponent extends JComponent {

        @Override
        public Dimension getMaximumSize() {
            return new Dimension(100, 100);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(100, 100);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.setPaint(Color.RED);
            g2d.fillRect(getX(), getY(), getWidth(), getHeight());
            System.out.println(getWidth());
        }

    }

    private JPanel panel;
    private TestComponent testComponent;

    public Testing() {
        super("Testing");
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        setSize(1280, 720);
        setLocationRelativeTo(null);

        panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
        panel.setBackground(Color.CYAN);
        testComponent = new TestComponent();
        panel.add(testComponent);
        add(panel);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(()->{
            new Testing().setVisible(true);
        });
    }

}

Это не так Это произойдет, если вместо моего пользовательского компонента я добавлю JPanel с установленными предпочтительными и максимальными размерами.

        panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
        panel.setBackground(Color.CYAN);
        // testComponent = new TestComponent();
        // panel.add(testComponent);
        JPanel test = new JPanel();
        test.setPreferredSize(new Dimension(100,100));
        test.setMaximumSize(new Dimension(100,100));
        test.setBackground(Color.RED);
        panel.add(test);
        add(panel);

Я не уверен, что мне не хватает. Спасибо!

Ответы [ 2 ]

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

У меня есть очень простой пользовательский компонент.

Пользовательский компонент отвечает за определение его:

  1. минимальный размер
  2. предпочтительный размер
  3. максимальный размер

Вы реализуете только предпочтительные и максимальные размеры.

Но все равно не имеет смысла, почему компонент не не в центре и составляет половину максимальной ширины.

BoxLayout пытается соблюдать минимальный и максимальный размеры компонента.

Минимальный размер по умолчанию - (0, 0), который, кажется, вызывает путаницу для BoxLayout. Я не уверен почему. Я бы сказал, что это ошибка / особенность BoxLayout.

Вам необходимо реализовать метод getMinimumSize(). Кажется, это работает:

@Override
public Dimension getMinimumSize() {
    return new Dimension(2, 2);
}

Примечание. Я попытался (1, 1), но это не сработало. Опять же, не знаю, почему.

Я хотел бы предложить, что для вашего случая вы можете использовать:

@Override
public Dimension getMinimumSize() {
    return getPreferredSize();
}

как для минимального, так и для максимального методов, так как кажется, что вы хотите размер должен быть постоянным.

0 голосов
/ 25 апреля 2020

Переопределяющие методы getAnyKindOfSize() в целом не очень хорошая практика. Попробуйте добавить компонент во вложенный JPanel, который использует FlowLayout, а затем этот JPanel на панель с BoxLayout. Примерно так:

testComponent = new TestComponent();
testComponent.setPreferredSize(new Dimension(100, 100));

JPanel flowPanel = new JPanel(new FlowLayout());
flowPanel.add(testComponent);
panel.add(flowPanel);

и:

class TestComponent extends JComponent {

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g.create();
        g2d.setPaint(Color.RED);
        g2d.fillRect(0, 0, getWidth(), getHeight()); //Notice x, y
    }

}
...