2012-01-06 93 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