5

ブラシツールを使用していくつかの異なる色をペイントして消去できる簡単なペイントプログラムを作成しました(単に白でペイントするだけです)。

それは正常に動作しますが、ツールパネルと最後にマウスオーバーされた色/ツールアイコンが描画パネルの上に描画されるという非常に奇妙なグラフィカルなバグがあります。

実装: フレームには、JPanel の 2 つの拡張 (ToolPanel と DrawPanel) が保持されます。ToolPanel は、カラー ボタンとツール ボタンを保持する 2 つの JPanel を保持します。ボタンは JComponent の拡張機能です。

スクリーンショットへのリンク(画像を投稿することは許可されていません):

ここに画像の説明を入力

注: 2 番目の「偽の」ツールパネルのボタンは、クリックできる実際のボタンではなく、その上にペイントできます。左隅にある「偽の」色のボタンをペイントすると、マウスを新しい色の上に置き、マウスで描画パネルに入ると、再び再描画されます。

注2:以前は、ドローパネルにも描画されたJMenuBarがありました。ウィンドウ(パネルだけでなく)が一度フォーカスを失った後、ドローパネルがマウスオーバーされるたびに再描画されました。

いくつかのコード: (ツール選択の実装が最適ではないことはわかっています:P)

DrawPanel の paintComponent メソッド:

    public void paintComponent(Graphics g) { 
    if(isMousePressed) {
        if(tool == "BRUSH") {
            g.setColor(color);
            g.fillOval(currentEvent.getX(), currentEvent.getY(), 30, 30);
        } else if(tool == "ERASER") {
            g.setColor(getBackground());
            g.fillOval(currentEvent.getX(), currentEvent.getY(), 30, 30);

        }
    }
}

関連する情報や省略したコードがあれば教えてください。

仮説: DrawPanels の paintComponent メソッドで super.paintComponent を呼び出さなかったので、問題が発生したのではないでしょうか? そうしなかった理由は、そうすると背景が常に再描画され、最後にペイントしたドットだけが表示されるようになるためです。スーパーコールが実際に問題を解決するのか、それとも偽のパネルも背景で覆われているだけなのかは不明です。多分私はそれを別の方法で回避する必要がありますか?それとも別のものですか?

ありがとう!

4

2 に答える 2

3

おそらく新しいものを作成する代わりに Graphics オブジェクトを変更しているようです ( g.create())。したがって、ペイント位置を変更する可能性のある境界やクリップ領域の設定などを行っています。

もう少し詳細(ペイントするすべての場所など)または完全なSSCCEを投稿できる場合は、この回答をより具体的に更新します。それまでは無理です。

Graphics操作する新しいオブジェクトを常に作成することをお勧めします。

public void paintComponent(Graphics g) {
    super.paintComponent(g);
    if (isMousePressed) {
        // create the new Graphics context which
        // we can work with/modify independently
        g2 = g.create();
        // use "str".equals() for String comparisons
        if ("BRUSH".equals(tool)) {
            g2.setColor(color);
            g2.fillOval(currentEvent.getX(), currentEvent.getY(), 30, 30);
        } else if ("ERASER".equals(tool)) {
            g2.setColor(getBackground());
            g2.fillOval(currentEvent.getX(), currentEvent.getY(), 30, 30);
        }
        // you should always dispose() of a Graphics
        g2.dispose();
    }
}
于 2011-08-01T17:00:10.600 に答える
3

Swing を使用してから長い時間が経ちましたが、基本的な問題は、背景が再描画されていないことです。これは、適切に機能するコンポーネントが毎回領域全体をペイントする必要があることを意味するため、以前の描画を保存して再ペイントする必要があります。

コンポーネントを透明に設定してみてください (setTransparent または setOpaque メソッドを確認してください) が、数年が経過しているため、正確な結果がどうなるかわかりません。

于 2011-08-01T17:00:53.293 に答える