1

我创建了一个带有自定义面板类的面板的窗口,并根据数组数据在其上绘制圆圈。如何让两组圆圈都留在屏幕上?

import java.awt.Color;
import java.awt.*;
import javax.swing.*;

class DataPaint extends JPanel {
    static int offsetY = 0;
    int leftX = 20;
    int[] guessColours;
    Color purple = new Color(155, 10, 255);
    Color pink = new Color(255, 125, 255);
    Color[] Colours = { Color.blue, Color.cyan, Color.green, Color.orange,
            pink, purple, Color.red, Color.yellow };

    public DataPaint() {
        setBackground(Color.WHITE);
    }

    public void paintClues(int[] guessColours) {
        this.guessColours = guessColours;
        offsetY += 30;
    }

    // naive attempt to make it work !!!!
    // what is diff between paintComponent and paint?
    public void update(Graphics g) {
        paintComponent(g);
    }

    // paint circles based on array data
    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        Graphics2D g2 = (Graphics2D) g;

        for (int i = 0; i < guessColours.length; i++) {
            g2.setPaint(Colours[guessColours[i]]);
            g2.fillOval(leftX + (i * 30), offsetY, 20, 20);
        }
    }

    // create window with panel and paint circles on it based on array data
    public static void main(String args[]) {
        JFrame frame = new JFrame("data paint");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(300, 300);

        DataPaint panel = new DataPaint();
        frame.add(panel);
        frame.setVisible(true);

        int[] cols = { 2, 4, 5, 3, 6 };
        int[] cols2 = { 1, 3, 7, 3, 4 };
        // the second call replaces the first call on the panel?
        panel.paintClues(cols);
        panel.paintClues(cols2);

    }
}
4

1 回答 1

3

你不阻止它。Swing 和大多数 GUI 框架的工作方式是该paintComponent方法或其类似物总是应该从头开始绘制所有内容

有几个原因。一个是如果调整了窗口大小,或者发生了任何其他类型的布局更改,或者如果正在绘制的数据集以复杂的方式更改,则无论如何您都需要能够重绘。此外,一些窗口系统甚至不会永久存储在窗口中绘制的内容,因此如果您的窗口被覆盖然后未被覆盖,您需要能够重绘。可以有一个具有永久图像的组件,您可以在其中绘制,但这不是通常的处理方式,并且效率较低,除非您正在编写,例如,绘画程序。

更改您的数据结构,以便保留所有信息,并编写您的数据结构,以便paintComponent每次调用时都会在屏幕上绘制您想要的所有内容

(有一些改进可以使复杂图形的部分更新变得高效,但您不必担心这些,因为这是一个非常简单的情况。如果您确实需要这样做,您会要求 Swing 重新绘制一个组件的小区域(例如 with JComponent.repaint(Rectangle r); 然后它会在调用您的paintComponent方法时自动禁止绘制到该区域之外的区域。这可以很好地防止闪烁并节省一些填充工作;然后如果它对效率真的很重要,请在 paintComponent 内部将该剪辑区域(Graphics.getClip()_ _然后在重要时进行优化。)

在您的特定示例中,我认为它旨在成为 Mastermind 游戏(您应该提前提及以帮助我们阅读您的代码),将colscols2放入int[][]DataPaint 的字段中,然后使用其中的循环paintComponent来读取每个子-array 在该数组中并绘制所有这些。

于 2012-04-24T11:22:01.410 回答