Java Swing - 绘制JPanel而不覆盖

时间:2014-04-03 10:50:29

标签: java swing graphics jpanel

我知道绘制JPanel的正确方法是创建一个扩展JPanel并覆盖paintComponent方法的类。这很好,但在制作JPanels之前我不知道我想要绘制什么。

我在JPanel中有一个主GridLayout。网格中充满了其他JPanels。这些JPanels也在2D数组中被跟踪。基于按钮事件或其他事件,我希望能够简单地遍历此数组,获取图形并重新绘制。然而,这不是很好。我想做的一个例子是:

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]);
    }
}

稍后在代码中,或许我希望能够循环并重新绘制面板的另一个事件:

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()

    }
}

我从来没有写过第二个块,因为第一个块总是抱怨图形没有被初始化。

1 个答案:

答案 0 :(得分:2)

你可以做的是有一个原型面板,它使用任何实现接口的类,比如Drawable,它有一个需要被覆盖的draw(Graphics g)方法。

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

您的原型面板调用看起来像这样。

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);
        }
    }
}

仅当Drawable对象不为null时,它才会绘制任何内容。您可以在实例化时将Drawable对象传递给它,可以稍后设置Drawable对象。

因此,您可以创建DrawablePanel数组,并随时设置Drawable预言。

Drawable实施的一个例子可能就像

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

<强>更新

以下是您可以使用

的示例
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);
}