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メソッドまたはその類似物が常にゼロからすべてを描画することになっていることです。

これにはいくつかの理由があります。1つは、ウィンドウのサイズが変更された場合、またはその他の種類のレイアウト変更が発生した場合、または描画されているデータセットが複雑な方法で変更された場合、とにかく再描画できる必要があるということです. また、一部のウィンドウ システムでは、ウィンドウに描画されたものを永続的に保存することさえできないため、ウィンドウが覆われてから覆われなくなった場合に再描画できるようにする必要があります。描画できる恒久的なイメージを持つコンポーネントを作成することは可能ですが、それは通常の方法ではなく、たとえばペイント プログラムを作成する場合を除き、効率が低下します。

すべての情報を保持するようにデータ構造を変更し、呼び出されるたびに画面に必要なものすべてを描画paintComponentするように記述します。

(複雑なグラフィックスの部分的な更新でこれを効率的にするための改良がありますが、これは非常に単純なケースであるため、まだ心配する必要はありません。これを行う必要がある場合、Swing に再描画を依頼します。コンポーネントの小さな領域 ( with など) 。メソッドJComponent.repaint(Rectangle r)を呼び出す間、その領域外の領域への描画が自動的に禁止されますpaintComponent。これは、ちらつきを防ぎ、塗りつぶし作業を節約するためにうまく機能します。効率が本当に重要な場合は、paintComponent 内でそのクリップ領域 ( Graphics.getClip()) を描画中のものと比較し、交差しないものはすべてスキップします. しかし、この単純なケースでは、まだそれについて心配する必要はありません. まず、コードを動作させ、Swing を正しく使用してください.必要に応じて最適化してください。)

あなたの特定の例では、首謀者のゲームを意図しており(コードを読むのに役立つように前もって言及する必要があります)、 DataPaintのフィールドにcolsandを入れ、内部でループを使用してすべてのサブを読み取ります-その配列に配列し、それらすべてをペイントします。cols2int[][]paintComponent

于 2012-04-24T11:22:01.410 に答える