2010-04-06 43 views
0

我遇到的問題是問題是我想讓paintComponent只有當鼠標被點擊,拖動,然後鬆開才能繪製圓。然而,在我的paintPanel類中,我必須初始化我創建的對象(例如movedCircle myCircle = new movedCircle(0,0,0,0);)只是創建對象movedCircle myCircle;直到我實際上用一個值完全初始化對象時纔給出錯誤。java/Swing問題與paintComponent

我在尋找什麼: 什麼被認爲是這個問題的最佳實踐。我不想在需要之前畫出任何不必要的東西。

我知道如何解決這個問題的方法: paintComponent內部的布爾值,這樣它就不會畫到實際存在的東西。

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.*; 

public class drawCircle extends JFrame{ 
    private JPanel myPanel = new paintPanel(); 

    public drawCircle(){ 
     add(myPanel); 
    } 

    private class paintPanel extends JPanel{ 
     private int x1, y1, x2, y2; 
     movedText myText = new movedText(0,0,0,0); 
     movedCircle myCircle = new movedCircle(0,0,0,0); 

     public paintPanel(){ 
      addMouseListener(new MouseAdapter(){ 
       public void mousePressed(MouseEvent e){ 
        x1 = e.getX(); 
        y1 = e.getY(); 
        myCircle = new movedCircle(x1, y1, 0, 0); 
        repaint(); 
       } 
       public void mouseReleased(MouseEvent e){ 
        x2 = e.getX(); 
        y2 = e.getY(); 
        myCircle = new movedCircle(x1, y1, x2, y2); 
        repaint(); 
       } 
      }); 

      addMouseMotionListener(new MouseMotionAdapter(){ 
       public void mouseDragged(MouseEvent e){ 
        x2 = e.getX(); 
        y2 = e.getY(); 
        myText = new movedText(x1, y1, x2, y2); 
        myCircle = new movedCircle(x1, y1, x2, y2); 
        repaint(); 
       } 
       public void mouseMoved(MouseEvent e){ 
        x1 = e.getX(); 
        y1 = e.getY(); 
        x2 = 0; 
        y2 = 0; 

        myText = new movedText(x1, y1, x2, y2); 
        repaint(); 
       } 
      }); 
     } 

     protected void paintComponent(Graphics g){ 
      super.paintComponent(g); 
      //draw oval after mouse released 
      myText.paintText(g); 
      myCircle.paintCircle(g); 
     } 
    } 

    class movedCircle{ 
     private int x1, y1, x2, y2; 

     public movedCircle(int x1, int y1, int x2, int y2){ 
      this.x1 = x1; 
      this.y1 = y1; 
      this.x2 = x2; 
      this.y2 = y2; 
     } 

     public void paintCircle(Graphics g){ 
      g.drawOval(x1, y1, x2 - x1, y2 - y1); 
     } 
    } 
    class movedText{ 
     private int x1, y1, x2, y2; 

     public movedText(int x1, int y1, int x2, int y2){ 
      this.x1 = x1; 
      this.y1 = y1; 
      this.x2 = x2; 
      this.y2 = y2; 
     } 

     public void paintText(Graphics g){ 
      g.drawString("x1: "+x1+" y1: "+y1+" x2: "+x2+" y2: "+y2, x1, y1); 
     } 
    } 

    class RedSquare{ 
     private int xPos = 50; 
     private int yPos = 50; 
     private int width = 20; 
     private int height = 20; 

     public void setX(int xPos){ 
      this.xPos = xPos; 
     } 

     public int getX(){ 
      return xPos; 
     } 

     public void setY(int yPos){ 
      this.yPos = yPos; 
     } 

     public int getY(){ 
      return yPos; 
     } 

     public int getWidth(){ 
      return width; 
     } 

     public int getHeight(){ 
      return height; 
     } 

     public void paintSquare(Graphics g){ 
      g.setColor(Color.RED); 
      g.fillRect(xPos,yPos,width,height); 
      g.setColor(Color.BLACK); 
      g.drawRect(xPos,yPos,width,height); 
     } 
    } 

    public static void main(String[] args){ 
     JFrame frame = new drawCircle(); 

     frame.setTitle("Is in ellipse? Demo"); 
     frame.setSize(400, 400); 
     frame.setLocationRelativeTo(null); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setVisible(true); 
    } 
} 

回答

0

我會去與if s,但問題是在哪裏。

  1. 你可以將它們添加到paintPanel.paintComponent()
  2. 你可以將它們添加到movedCircle.paint()和不畫任何東西,如果它的座標是假的(例如< 0)。與movedText相同

或者,將您的數字放在合理的起始位置。

(還有一個解決辦法:子類movedCirclenullMovedCircle不畫任何東西,創造,起初在paintPanel然而,對於行爲的這樣一個小的改變創造新的類對我來說似乎矯枉過正。)

+0

對於您提供的最後一個解決方案: 這與moveCircle myCircle沒有區別;即使它被設置爲移動循環myCircle = new nullMovedCircle();問題是paintComponent將總是想要做什麼,因爲這行不存在「myCircle.paintCircle(g);」這會導致一個足夠奇怪的錯誤,允許我運行該程序,但不會繪製任何東西,直到我執行所需的鼠標事件來繪製所需的圓。實際上,我正在計劃放置bool值檢查並創建一個從嵌套的movedCircle類返回bool值的getDraw()方法。 – mjrevel 2010-04-06 18:14:18

+0

嗯,我錯了......並且很高興。我不想用if語句來提升我的paintComponent ...並且他們真的似乎不屬於那裏imo。 這裏的修復: \t類nullMovedCircle擴展movedCircle { \t \t公共nullMovedCircle(INT X1,Y1 INT,INT X2,Y2 INT){ \t \t \t超(X1,Y1,X2,Y2); \t \t} \t \t公共無效paintCircle(圖形克){} \t} 簡而言之: 謝謝! – mjrevel 2010-04-06 18:47:19

+0

你可以這樣做,但正如pajton所暗示的那樣,它是一種過度的殺傷,一個額外的課程來開發,測試和維護。最佳實踐應該努力保持代碼的可讀性,我認爲if!null傳達的意圖要多得多。 – vickirk 2010-04-06 21:53:11

0

不知道我是否錯過了這個觀點,但如果你不想畫出一些東西,直到它被初始化,那麼不要!你能不能僅僅檢查它是否已經被創建,而不是在構造器完成之後創建一個不處於可用狀態的新實例?例如

super.paintComponent(g); 
myText.paintText(g); 
if (myCircle != null) { 
    myCircle.paintCircle(g); 
} 
+0

這個解決方案是在詢問問題時給出的。我只是在尋找替代品,或者看看有人知道什麼被認爲是「最佳做法」。 – mjrevel 2010-04-06 19:23:34