2016-10-14 5 views
2

私は現在、私の学士論文のためのテスト駆動型のインタラクティブな2D流体力学シミュレーションに取り組んでいます。基本的な考え方は、ユーザーが画面上に図形を描くことができ、プログラムは流体がこれらの図形の周りをどのように流れるかをシミュレートすることです。 これまでのところ私は絵画のプロセスだけを始めましたが、私はすでに少し問題にぶつかっています。Swingの別のクラスのJPanelでのペイント

First, here is a little UML diagram that shows my project structure so far

あなたが見ることができるように、私はいくつかの形状を訪問することができ、形状の種類に応じて、抽象ペイントの方法のいずれかを呼び出しますペインタークラスを作成しました。次に、Painterクラスから継承し、クリアメソッドと同様に3つのペイントメソッドを実装するSwingPainterクラスがあります。ここ は私SwingPainterのコードです:

public class SwingPainter extends Painter { 

    private final GraphicPanel graphicPanel; 

    public SwingPainter(GraphicPanel graphicPanel) { 
     this.graphicPanel = graphicPanel; 
    } 

    private Graphics getGraphics() { 
     return graphicPanel.getGraphics(); 
    } 

    @Override 
    protected void paintLine(Point start, Point end) { 
     getGraphics().drawLine(start.getX(), start.getY(), end.getX(), end.getY()); 
    } 

    @Override 
    protected void paintRectangle(Point start, Point end) { 
     int minX = start.getX() < end.getX() ? start.getX() : end.getX(); 
     int minY = start.getY() < end.getY() ? start.getY() : end.getY(); 
     int width = Math.abs(start.getX() - end.getX()); 
     int height = Math.abs(start.getY() - end.getY()); 
     getGraphics().drawRect(minX, minY, width, height); 
    } 

    @Override 
    protected void paintCircle(Point center, double radius) { 
     int minX = center.getX() - (int) radius; 
     int minY = center.getY() - (int) radius; 
     int diameter = (int) radius * 2; 
     getGraphics().drawOval(minX, minY, diameter, diameter); 
    } 

    @Override 
    public void clear() { 
     graphicPanel.paintComponent(getGraphics()); 
    } 
} 

だから私の問題はGraphicPanelPresenterは(UMLの図を参照)、ユーザーがクリックを左またはマウスを移動したときの形状にペインター/ビジターを渡すために責任があるということです(行の2番目の点がカーソルの後に続きます)。つまり、実際のペインティングはSwingのペイント方法の外で行われます。その結果、私はペインティング中にちらつきが発生しましたが、誰かがペインタ/ビジターの全体的な機能をウィンドウの外に投げ出すことなくそれを修正する方法を知っていたのか疑問に思っていました。別のタイプのビジターを渡すだけで処理できます)。

これはかなり小さな問題ではかなり長い説明でしたが、テキストの壁には申し訳ありませんが、私はどんなヒントでもうれしいでしょう!

+0

私は、必要なコンポーネントをパブリック/ゲッターを追加し、それらにアクセスすると思うでしょう – ItamarG3

+1

すべてのペイントは、ペイントメソッドで行う必要があります。ペイントメソッドの所有者(つまりコンテナ)に必要な情報を渡すことを検討してください。 – ItamarG3

+1

あなたは間違ったトラックにいます。すべてのペイントとComponentのGraphicsオブジェクトの使用は、JComponentのpaintComponentメソッドで行う必要があります。このようにして、Componentがresized/reshown/etcにサイズ変更された場合は、再描画することができます。 paintComponentメソッドで(Buffered)Imageを使用し、他のクラスから描画することができます。しかし、このImageで行われたすべてのGraphics操作がUIスレッド上で行われていることを確認して、Imageがスクリーン上で再描画されたときに常に一貫した状態になるようにしてください – ControlAltDel

答えて

1

カスタムペイントをオーバーライドするように設計されたさまざまなSwingペイントメソッド(たとえば、paintComponent)では、すべてのペイントを行う必要があります。 Swingだけが描画が完了したとき、または新しいフレームを描画する必要があるときを知ることができます。

実際に行う必要があるのは、GraphicsPanelに図形の状態を保持するオブジェクトへの参照を持たせてから、その状態を表す図形をpaintComponentに描画することです。

GraphicsPanelの中では、リスナーから状態を変更するために状態オブジェクトのメソッドを呼び出すことができるため、クラス関係図も簡素化する必要があります(状態オブジェクトが変更の基になることを認識しないようにUIのインタラクションでは、右クリックが回転する場合、handleRightClickの代わりにrotateというメソッドを作成します)。

関連する問題