简体   繁体   English

Java Swing - 在不覆盖的情况下绘制 JPanels

[英]Java Swing - Painting JPanels without overriding

I know the proper way to paint a JPanel is to create a class that extends JPanel and override the paintComponent method.我知道绘制JPanel的正确方法是创建一个扩展JPanel并覆盖paintComponent方法的类。 That's nice, but I don't know what I want to draw before making the JPanels .这很好,但我不知道在制作JPanels之前我想画什么。

I have a main JPanel in a GridLayout .我在GridLayout有一个主JPanel The grids are filled with other JPanels .网格填充了其他JPanels These JPanels are also tracked in a 2D array.这些JPanels也在二维数组中进行跟踪。 Based on button events or other events I want to be able to simply loop through this array, get the graphics, and repaint.基于按钮事件或其他事件,我希望能够简单地遍历此数组,获取图形并重新绘制。 That is not working too nicely however.然而,这并不太好。 An example of what I wanted to do is:我想做的一个例子是:

for (int row = 0; row < GRID_ROWS; row++) {
    for (int col = 0; col < GRID_COLS; col++) {
        JPanel tmp_panel = new JPanel();
        Graphics g = panelGrid[row][col].getGraphics();
        Graphics2D g2d = (Graphics2D)g;
        //Do some drawing
        panelGrid[row][col] = tmp_panel;
        backingPanel.add(panelGrid[row][col]);
    }
}

Later in the code, perhaps another event I would like to simply be able to loop through and redraw the panels:在代码的后面,也许我希望能够简单地循环并重绘面板的另一个事件:

for (int row = 0; row < GRID_ROWS; row++) {
    for (int col = 0; col < GRID_COLS; col++) {
        Graphics g = panelGrid[row][col].getGraphics();
        Graphics2D g2d = (Graphics2D)g;
        //Do some drawing
        panelGrid[row][col].repaint()

    }
}

I never got to writing the second block because the first one always complains about graphics not being initialized.我从来没有写过第二个块,因为第一个块总是抱怨图形没有被初始化。

What you can do is have a prototype panel that uses any class that implements an interface, say Drawable , which has a draw(Graphics g) method that need to be overridden.你可以做的是有一个原型面板,它使用任何实现接口的类,比如Drawable ,它有一个需要覆盖的draw(Graphics g)方法。

public interface Drawable {
    public void draw(Graphics g);
}

Your prototype panel call can look something like this.您的原型面板通话可能看起来像这样。

public class DrawablePanel extends JPanel {
    private Drawable drawable;


    public DrawablePanel(Drawable drawable) {
        this.drawable = drawable;
    }

    public DrawablePanel() {

    }

    public void setDrawable(Drawable drawable) {
        this.drawable = drawable;
        repaint();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g;
        if (drawable != null) {
            drawable.draw(g2);
        }
    }
}

Only if the Drawable object is not null, will it paint anything.只有当Drawable对象不为空时,它才会绘制任何东西。 You can either pass a Drawable object to it on instantiation, or you can set the Drawable object later.您可以通过一个Drawable对象给它的实例,可以设置Drawable后面的对象。

So you can create an array of DrawablePanel and set the the Drawable proptery whenever you want.因此,您可以随时创建DrawablePanel数组并设置Drawable属性。

An example of a Drawable implementation could be something as simple as一个Drawable实现的例子可能很简单

public class Ball implements Drawable {
    @Override
    public void draw(Graphics g) {
        g.fillOval(0, 0, 50, 50);
    }
}

UPDATE更新

Here's an example you can play with这是一个你可以玩的例子

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

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

public class LoopPanelPaint {
    private static final int ROUND_SQR = 0;
    private static final int BALL = 1;

    private List<Color> colorList;

    public LoopPanelPaint() {
        JPanel matrixPanel = new JPanel();
        DrawablePanel[][] drawPanels = createPanelMatrix(matrixPanel);

        colorList = createColorList();

        JButton createImages = createButton(drawPanels);

        JFrame frame = new JFrame();
        frame.add(matrixPanel);
        frame.add(createImages, BorderLayout.SOUTH);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public JButton createButton(final DrawablePanel[][] panels) {
        JButton button = new JButton("Create Images");
        button.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                addShapesToPanels(panels);
            }
        });
        return button;
    }

    private DrawablePanel[][] createPanelMatrix(JPanel panel) {
        panel.setLayout(new GridLayout(10, 10));
        DrawablePanel[][] panels = new DrawablePanel[10][10];
        for (int i = 0; i < 10; i++) {
            for (int j = 0; j < 10; j++) {
                DrawablePanel drawPanel = new DrawablePanel();
                panels[i][j] = drawPanel;
                panel.add(drawPanel);
            }
        }
        return panels;
    }

    private void addShapesToPanels(DrawablePanel[][] panels) {
        Random random = new Random();
        for (int i = 0; i < 10; i++) {
            for (int j = 0; j < 10; j++) {
                int type = random.nextInt(2);
                Drawable drawable = getRandomDrawable(type);
                int colorIndex = random.nextInt(colorList.size());
                Color color = colorList.get(colorIndex);
                panels[i][j].setColor(color);
                panels[i][j].setDrawable(drawable);
            }
        }
    }

    private Drawable getRandomDrawable(int type) {
        switch (type) {
        case ROUND_SQR:
            return new RoundSquare();
        case BALL:
            return new Ball();
        default:
            return null;
        }
    }

    private List<Color> createColorList() {
        List<Color> colors = new ArrayList<>();
        colors.add(Color.blue);
        colors.add(Color.red);
        colors.add(Color.gray);
        colors.add(Color.green);
        colors.add(Color.orange);
        colors.add(Color.magenta);
        colors.add(Color.yellow);
        colors.add(Color.cyan);
        return colors;
    }

    public class DrawablePanel extends JPanel {

        private Drawable drawable;
        private Color color = Color.black;

        public DrawablePanel(Drawable drawable) {
            this.drawable = drawable;
        }

        public DrawablePanel() {

        }

        public void setDrawable(Drawable drawable) {
            this.drawable = drawable;
            repaint();
        }

        public void setColor(Color color) {
            this.color = color;
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2 = (Graphics2D) g;
            g2.setColor(color);
            if (drawable != null) {
                drawable.draw(g2);
            }
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(Drawable.SIZE, Drawable.SIZE);
        }
    }

    public class Ball implements Drawable {

        @Override
        public void draw(Graphics g) {
            g.fillOval(0, 0, Drawable.SIZE, Drawable.SIZE);
        }
    }

    public class RoundSquare implements Drawable {

        @Override
        public void draw(Graphics g) {
            g.fillRoundRect(0, 0, Drawable.SIZE, Drawable.SIZE, 10, 10);

        }

    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new LoopPanelPaint();
            }
        });

    }

}

interface Drawable {
    public static final int SIZE = 50;

    public void draw(Graphics g);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM