Графика не отображается на CardLayout - PullRequest
0 голосов
/ 16 марта 2019

Я создаю графический интерфейс, который использует CardLayout для переключения между экранами. Я хочу, чтобы на одном из экранов было изображение. Я успешно смог поместить прямоугольник на панель с помощью GridLayout и поместить эту панель на основную панель, и прямоугольник хорошо виден. Однако, когда я помещаю эту панель на панель CardLayout, прямоугольник нигде не видно. Есть ли что-то другое, что нужно сделать при добавлении графики на панель CardLayout?

Основной класс

import java.awt.CardLayout;
import java.awt.Container;
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import javax.swing.JLabel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.Dimension;

public class Window extends JFrame {
    public Window() {
        // Main Panel Configuration
        Container panel = this.getContentPane();
        panel.setLayout(new GridBagLayout());
        panel.setSize(1000,1000);
        GridBagConstraints gbc = new GridBagConstraints();

        // GridBag Constraints
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridheight = 1;
        gbc.weightx = 1;
        gbc.weighty = 1;
        gbc.gridx = 0;
        gbc.gridy = 0;

        // Button Tabs
        JButton button1 = new JButton("button 1");
        panel.add(button1, gbc);

        JButton button2 = new JButton("button 2");
        gbc.gridx = 1;
        panel.add(button2, gbc);

        // Panels for CardLayout
        JPanel panel1 = new JPanel();
        JPanel panel2 = new JPanel();

        // Set Layout of Panels
        panel1.setLayout(new GridBagLayout());
        panel2.setLayout(new GridBagLayout());

        // Set Dimensions of Panels
        panel1.setSize(new Dimension(900, 500));
        panel2.setSize(new Dimension(900, 500));

        // Labels for panels
        JLabel label1 = new JLabel("label 1");
        gbc.gridx = 1;
        gbc.gridy = 2;
        panel1.add(label1, gbc);

        JLabel label2 = new JLabel("label 2");
        gbc.gridy = 2;
        panel2.add(label2, gbc);

        // TextFields for Panels
        JTextField textField1 = new JTextField();
        gbc.gridx = 2;
        gbc.gridy = 2;
        panel1.add(textField1, gbc);

        JTextField textField2 = new JTextField();
        gbc.gridy = 2;
        panel2.add(textField2, gbc);


        // Add Graphic to panel1
        JPanel drawingPanel = new JPanel();
        DrawingComponent dc = new DrawingComponent();
        dc.setPreferredSize(new Dimension(100, 100));
        drawingPanel.add(dc);
        gbc.gridx = 0;
        gbc.gridy = 3;
        panel1.add(drawingPanel,gbc);


        // Set TextField Dimensions
        textField1.setPreferredSize(new Dimension(400, 20));
        textField2.setPreferredSize(new Dimension(400, 20));

        // CardLayout Panel for Entry Fields and Labels
        JPanel cardLayoutPanel = new JPanel();
        CardLayout c1 = new CardLayout();
        cardLayoutPanel.setLayout(c1);
        cardLayoutPanel.setSize(new Dimension(900, 600));

        // Add Panels to CardLayout Panel
        cardLayoutPanel.add("panel1",panel1);
        cardLayoutPanel.add("panel2", panel2);

        // Which panel to show First
        c1.show(cardLayoutPanel, "panel1");

        // Add CardLayout Panel to Main Panel
        gbc.gridy = 1;
        gbc.gridx = 0;
        panel.add(cardLayoutPanel, gbc);


        // Action Listeners Changing Between Tabs
        button1.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent arg0) {
                c1.show(cardLayoutPanel, "panel1");
            }
        });


        button2.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent arg0) {
                c1.show(cardLayoutPanel, "panel2");
            }
        });

        setSize(800,600);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);

    }


    public static void main(String[] args){
        Window window = new Window();

    }
}

Класс компонентов чертежа

import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JComponent;
import java.awt.Rectangle;

public class DrawingComponent extends JComponent {
    public void paintComponent(Graphics g){
        Graphics2D g2 = (Graphics2D) g;

        Rectangle rect1 = new Rectangle(400, 400, 50, 50);
        g2.draw(rect1);
    }
}

Ответы [ 2 ]

2 голосов
/ 16 марта 2019

В этой части:

JPanel drawingPanel = new JPanel();
DrawingComponent dc = new DrawingComponent();
dc.setPreferredSize(new Dimension(100, 100));
drawingPanel.add(dc);

Вы устанавливаете предпочтительный размер вашего DrawingComponent в (100,100).Затем, когда вы рисуете компонент, вы рисуете прямоугольник в Rectangle(400, 400, 50, 50), используя конструктор Rectangle(int x, int y, int width, int height).

Сказав это, я думаю, это довольно очевидно.Ваш компонент имеет размер 100x100, но вы пытаетесь нарисовать 400x400-й пиксель, что приводит к тому, что прямоугольник рисуется вне границ вашего компонента.

Я не знаю, какими должны быть координаты прямоугольника, но если вы хотитеЧтобы ваш компонент отображался, измените прямоугольник на Rectangle rect1 = new Rectangle(0, 0, 50, 50);

Кроме того, VGR упоминается в комментариях (он получил меня: P), когда вы override paintComponent метод, убедитесь, что вы вызываете super.paintComponent().

Наконец, запустите ваше приложение, используя метод SwingUtilities#invokeLater.

Сумма того, что я имею в виду в коде:

public static class DrawingComponent extends JComponent {
        public void paintComponent(Graphics g) {
            super.paintComponent(g); // Should always start with super method.
            Graphics2D g2 = (Graphics2D) g;

            Rectangle rect1 = new Rectangle(0, 0, 50, 50);
            g2.draw(rect1);
        }
    }

    public static void main(String[] args) {
        // All swing applications must run on their own thread named EDT (Event dispatch thread)
        SwingUtilities.invokeLater(() -> {
            Window window = new Window();
        });
    }
1 голос
/ 16 марта 2019

Одной из проблем является то, что вы рисуете за пределами вашего компонента.Рисование прямоугольника в точке (400, 400) приведет к тому, что ничего не будет видно, если сам компонент будет иметь размер 100 × 100.

Другая проблема заключается в том, что вы пытаетесь явно установить размерываши компоненты и ваше окно.Но окно не достаточно большое для этих размеров.Когда GridBagLayout не может вместить предпочтительные размеры своих дочерних элементов, он «сдается» и устанавливает все на свой минимальный размер.Поскольку DrawingComponent не определяет минимальный размер, он возвращается к нулевой ширине и нулевой высоте.(Ваше использование fill = HORIZONTAL заставляет его быть равным его ширине, но высота все равно равна нулю.)

Неправильно устанавливать все эти размеры.Почти никогда не существует веских причин для вызова setSize или setPreferredSize.

Для JTextField вам необходимо установить его размер с помощью метода setColumns .

Класс DrawingComponent должензнать, какого размера он хочет быть, и он должен вернуть этот размер, переопределив свой собственный метод getPreferredSize.Очевидно, он должен быть достаточно большим, чтобы вместить свою собственную картину:

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

Для панелей и окон вообще не устанавливайте размер.Все они будут достаточно большими, чтобы вместить их дочерние компоненты, если вы построите все окно и затем вызовете для него pack () .

Опять должно быть no вызовы setSize или setPreferredSize в вашем коде.Вам они не нужны.

...