2012-01-06 73 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 2012-01-06 07:55:20

+0

因为我想让我的手脏:) – 2012-01-06 08:08:37

+1

请学习java的命名约定并坚持给他们 – kleopatra 2012-01-06 09:27:00

回答

2

让我们考虑图是卵形的名单和行列表。在Graph的paintComponent()方法中,我们必须绘制所有列表的成员。

添加g.getClipBounds矩形与Oval(或Line)矩形相交的检查。如果它们相交,我们绘制椭圆形或线。

当顶点移动到某个位置时,我们有新旧位置,并且可以重新绘制矩形。

使用矩形的位置和大小,并通过图形面板的重绘()。

这样,您只会重新绘制已更改的区域,并且只能绘制矩形中可见的椭圆和线条。

+0

我不确定,但我认为代码写入atm的方式正如你所描述的,注意重绘只重绘改变的矩形......也许如果你在实际工作中添加你的实现,它肯定会令人满意。 – 2012-01-06 08:12:04

+0

椭圆形和线是形状。使用getBounds()来获取矩形。 Shape还具有公共布尔相交(double x,double y,double w,double h)方法。图形具有公共抽象Rectangle getClipBounds() – StanislavL 2012-01-06 09:36:29