0

私は、JToggleButtons と、描画したいものを描画する方法を知っているサブクラス化された JPanels を備えた非常に基本的な小さな JFrame を持っています。ボタンを選択すると、対応するパネルに楕円が表示されます。ボタンの選択を解除すると、描画が消えます。

ボタンを押すと形が現れる

残念ながら、最小化 (アイコン化) してから元に戻す (非アイコン化) と、描画された図形が消えてしまいます。したがって、再描画を手動でトリガーする必要があります。問題は、最初にメッセージ ボックスを表示した場合にのみ、再描画を完了できる (つまり、再描画しか表示されない) ことです。

JFrame の deiconify イベントは次のとおりです。

private void formWindowDeiconified(java.awt.event.WindowEvent evt)
{                                       
    //having this message makes everything work
    JOptionPane.showMessageDialog(null, "Useless message this is.");
    //but if I skip it, I'm SOL
    //what's going on?
    drawAll();
}

このメソッドはすべてのボタンを調べ、必要に応じて再描画を要求します。

public void drawAll()
{
    for (int i=0; i<channels; i++)
    {
        if (buttons[i].isSelected())
        {
            lightboxes[i].drawMe();            
        }
    }
}

これが私のサブクラス化された JPanel です。

class MyJPanel extends JPanel {

    public void drawMe()
    {
        Graphics myGraphics = this.getGraphics();
        myGraphics.fillOval(0, 0, this.getWidth(), this.getHeight());    
    }

    public void unDraw()
    {
        this.invalidate();
        this.repaint();
    }
}
4

3 に答える 3

4

によって復元されると、ウィンドウは自動的に再描画されますRepaintManager。問題は、カスタム ペインティングを適切に実行していないことです...

これはカスタムペイントのやり方ではありません...

public void drawMe()
{
    Graphics myGraphics = this.getGraphics();
    myGraphics.fillOval(0, 0, this.getWidth(), this.getHeight());    
}

getGraphics戻ることができnull、せいぜいグラフィックス状態のスナップショットです。

Swing でのペイントは、さまざまな理由でいつでも発生する可能性があり、そのほとんどは制御できません (気にする必要もありません)。

あなたの仕事は、これらの再描画要求に応答し、コンポーネントの状態を更新することだけです。

Swing には、自動的に呼び出されて使用できる詳細なペイント チェーンがあります。

paintComponentこのメソッド内ですべての描画をオーバーライドして実行する必要があります

詳細については、Performing Custom PaintingおよびPaint in AWT and Swingを参照してください。

于 2013-06-26T23:47:41.077 に答える
1

まず、速度を上げるために、ダブル バッファリングを使用します。グラフィックスを画面外にペイントし、描画が完了したときに画面に表示することをお勧めします。以下はあなたを整理するはずです。

public class MyPanel extends JPanel {
    private BufferedImage buffer;
    private Graphics2D canvas;

    @Override
    public void paintComponent(Graphics g) {
        if(buffer == null) {
            buffer = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
            canvas = buffer.createGraphics();
        }
        canvas.fillOval(0, 0, this.getWidth(), this.getHeight());
        g.drawImage(buffer, 0, 0, this);
    }
}
于 2013-06-27T01:26:33.417 に答える