2012-01-06 5 views
2

動的グラフとは、ユーザーが画面上でVerticesをドラッグして後で削除することができるということです。動的グラフを描画する。

グラフの変更時にJVMペイント全体をもう一度塗り潰すことを避けようとしているところです。

私はそれをグラフ全体にペイントさせる必要がありますか、それを行う別の方法がありますか?

class GraphPanel extends JPanel { 

    private static final long serialVersionUID = 1L; 
    private Vector<Vertex> V=new Vector<Vertex>(); 
    private Vertex v; 
    private int R = 20; 

    public GraphPanel() { 
     V.add(new Vertex(70,70)); 
     V.add(new Vertex(10,50)); 
     paintGraph(); 
     addMouseListener(new MouseAdapter() { 
      public void mousePressed(MouseEvent e) { 
       for (int i=0;i<V.size();i++) { 
        if ((V.get(i).getX()<=e.getX() && V.get(i).getX()+R>=e.getX()) && (V.get(i).getY()<=e.getY() && V.get(i).getY()+R>=e.getY())) { 
         v=V.get(i); 
         moveVertex(e.getX(),e.getY()); 
         v.changeState(); 
        } 
       } 
      } 
      public void mouseReleased(MouseEvent e) { 
       v.changeState(); 
      } 
     }); 

     addMouseMotionListener(new MouseAdapter() { 
      public void mouseDragged(MouseEvent e) { 
       if (v.isPressed()) moveVertex(e.getX(),e.getY()); 
      } 
     }); 
    } 

    private void paintGraph() { 
     int OFFSET = 1; 
     for (int i=0;i<V.size();i++) { 
      v=V.get(i); 
      repaint(v.getX(),v.getY(),R+OFFSET,R+OFFSET); 
     } 

    } 

    private void moveVertex(int x, int y) { 
     int OFFSET = 1; 
     if ((v.getX()!=x) || (v.getY()!=y)) { 
      repaint(v.getX(),v.getY(),R+OFFSET,R+OFFSET); 
      v.setLocation(x-10, y-10); 
      repaint(v.getX(),v.getY(),R+OFFSET,R+OFFSET); 
     } 
    } 

    public Dimension getPreferredSize() { 
     return new Dimension(250,200); 
    } 

    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     if (v!=null) { 
      g.setColor(Color.RED); 
      g.fillOval(v.getX(),v.getY(),R,R); 
      g.setColor(Color.BLACK); 
      g.drawOval(v.getX(),v.getY(),R,R); 
     } 
    } 
} 

public class Vertex { 
    private int x,y; 
    boolean isPressed; 
    Vertex(int x0,int y0) {x=x0;y=y0;isPressed=false;} 
    public void setLocation(int x0,int y0) {x=x0;y=y0;} 
    public int getX() {return x;} 
    public int getY() {return y;} 
    public boolean isPressed() {return isPressed;} 
    public boolean changeState() {return isPressed=!isPressed;} 

} 

public class Tester { 
    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       createAndShowGUI(); 
      } 
     }); 
    } 

    private static void createAndShowGUI() { 
     JFrame f = new JFrame("Swing Paint Demo"); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.add(new GraphPanel()); 
     f.pack(); 
     f.setVisible(true); 
    } 
}  
+0

グラフを描画する理由JFreeChartのようなサードパーティのライブラリに頼らないのはなぜですか? – Acn

+0

原因私は私の手を汚したいと思う原因:) –

+1

Javaの命名規則を学び、それらに固執してください – kleopatra

答えて

2

はのグラフは、楕円形のリストと行のリストで考えてみましょう:

は、ここに私のコードです。 GraphのpaintComponent()メソッドでは、すべてのリストのメンバーを描画する必要があります。

g.getClipBounds矩形が楕円(または直線)矩形と交差することをチェックします。交差する場合は、楕円または線を描きます。

頂点がどこかに移動すると、古い位置と新しい位置があり、矩形を再描画することができます。

矩形の位置とサイズを使用して、グラフパネルのrepaint()を渡します。

このようにして、変更された領域のみを再ペイントし、長方形に表示される楕円と線のみを再ペイントします。

+0

私はよく分かりませんが、コードが書かれている方法は、再描画は変更された矩形のみを再描画します...もしあなたが実装されている実装を追加すると、それは間違いなく満足できるでしょう。 –

+0

楕円と線は形です。長方形を取得するには、getBounds()を使用します。 Shapeにはpublic boolean intersects(double x、double y、double w、double h)メソッドもあります。グラフィックスはpublic abstract Rectangle getClipBounds() – StanislavL

2

このexampleは、数千の頂点を簡単に処理できます。レンダリングにはflyweight patternを使用すると数値が大きくなる場合があります。 1つのアプローチがhereと示されています。