Рисование графики на панели - PullRequest
0 голосов
/ 21 февраля 2019

Я пытаюсь рисовать графику на панелях, но я не уверен, как бы я поступил так.

Я попытался создать класс, который расширяет JPanel и переопределенный paintComponent и некоторые другие методы, но ничего не отображается вообще.

Вот мой код:

edit:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class Lesson1 extends JFrame {

    private static final long serialVersionUID = -198253288329146091L;
    private JPanel contentPane;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    Lesson1 frame = new Lesson1();
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public Lesson1() {

        contentPane = new JPanel();
        setContentPane(contentPane);

        JPanel panel = new JPanel() {

            private static final long serialVersionUID = -5974584127539186578L;

            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                g.setColor(Color.GREEN);
                g.fillRect(0, 0, 500, 500);
            }

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

        };

        contentPane.add(panel);

        JPanel panel_1 = new JPanel() {

            private static final long serialVersionUID = 123456789L;

            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                g.setColor(Color.PINK);
                g.fillRect(0, 0, 200, 200);
            }

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

        };

        panel.setLayout(new BorderLayout());
        panel_1.setLayout(new BorderLayout());
        panel.add(panel_1);

    }

}

Я не уверен, что я делаю здесь неправильно, но я перепробовал все, что мог.Спасибо!

1 Ответ

0 голосов
/ 21 февраля 2019

Ошибка # 1

contentPane.setLayout(null);

и

panel.setLayout(null);

Прежде чем делать что-либо еще, вам необходимо узнать и понять, что на самом деле делают менеджеры макета и почему макеты nullнаивно и не рекомендуется (особенно когда вы только учитесь).

Начните с того, что потратите время на Размещение компонентов в контейнере

Удалите contentPane.setLayout(null);и измените panel.setLayout(null); на panel.setLayout(new BorderLayout());, и вы увидите немедленное изменение.

На самом деле вам действительно не нужен panel, так как contentPane по умолчанию JFrame уже настроениспользовать BorderLayout.

Это означает, что вы можете избавиться от panel.setBounds(73, 52, 231, 143);

Ошибка # 2

Хорошо, это скорее упущение, но когда выЧтобы приступить к настройке компонентов, вам необходимо предоставить подсказки по размерам, которые позволяют менеджерам компоновки принимать решения о том, как наилучшим образом расположить ваш компонент по отношению к другим компонентам и на основе его собственных внутренних правил.

С этой целью выдолжен, по крайней мере, переопределить getPreferredSize метод (избегайте методов setXxxSize, так как они могут привести к неожиданным результатам при неправильном использовании)

Добавить ...

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

к panel_1

Теперь это означает, что вы можете сделать что-то более похожее на ...

Lesson1 frame = new Lesson1();
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);

, и окно будет упаковано вокруг компонента (и будет центрировано на экране), и вы сможете избавиться от setBounds(100, 100, 450, 300);

Ладно, в любом случае я пытался, но безуспешно пытался сделать так, чтобы я мог устанавливать панели в определенном положении: /

Управление компоновкой в ​​среде графического интерфейса является частью науки, частично voodoo, часть черной магии

Идеальное позиционирование в пикселях - иллюзия в современной разработке пользовательского интерфейса.Существует так много факторов, которые влияют на определение того, «как» компонент должен быть расположен на одной платформе, пусть на разных платформах, вы потратите остаток своей жизни, постоянно добавляя «хаки», чтобы учесть бесконечное число возможныхкрайний случай.

Именно поэтому любая приличная инфраструктура пользовательского интерфейса абстрагирует эту концепцию, Swing использует API диспетчера макетов для этой цели, iOS (и MacOS) используют автоматическое макетирование и т. Д. *

Example

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Lesson1 {

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        new Lesson1();
    }

    public Lesson1() {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    JFrame frame = new JFrame();
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            setLayout(new GridBagLayout());

            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.anchor = GridBagConstraints.NORTHWEST;

            add(new RectPane(), gbc);

            gbc.gridx = 2;
            gbc.anchor = GridBagConstraints.NORTHEAST;
            add(new RectPane(), gbc);

            gbc.gridx = 1;
            gbc.gridy = 1;
            gbc.anchor = GridBagConstraints.CENTER;
            gbc.weightx = 1;
            gbc.weighty = 1;
            add(new RectPane(), gbc);

            gbc.weightx = 0;
            gbc.weighty = 0;
            gbc.gridx = 0;
            gbc.gridy = 2;
            gbc.anchor = GridBagConstraints.SOUTHWEST;
            add(new RectPane(), gbc);

            gbc.gridx = 2;
            gbc.anchor = GridBagConstraints.SOUTHEAST;
            add(new RectPane(), gbc);
        }

        // This is just to demonstrate how the layout works when the avaliable
        // space is larger then the desired space, you don't need this
        // and should get rid of it and just let the layout manager calculate
        // it's desired size based on it's content
        @Override
        public Dimension getPreferredSize() {
            return new Dimension(500, 500);
        }

    }

    public class RectPane extends JPanel {

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(Color.GREEN);
            g.fillRect(0, 0, 100, 100);
        }

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

    }

}

Поймите, GridBagLayout - самый сложный менеджер компоновки в стандартном API, но он наиболее гибкий.Вы также не ограничены одним менеджером макетов, вы можете использовать сложные макеты для создания очень продвинутых интерфейсов

...