2012-09-29 25 views
-1

我正在做一個家庭作業,以繪製一個java小程序中的房子。房子在一個大的矩形內有三個矩形,代表一扇門和兩個窗戶。點擊時我需要改變窗口的顏色,我已經達到了繪製房屋的地方,並且也繪製了門窗,但是我不能通過點擊鼠標來改變它們的顏色。我在確定爲什麼會出現這種情況時遇到了一些麻煩。java作業繪製房子小程序

總而言之,房子是繪製的;門和窗口矩形被繪製並填充黑色。當點擊任何窗口或門矩形時,不會出現任何錯誤和顏色變化。

代碼如下:提前

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

public class DrawHouse extends JApplet implements MouseListener 
{ 
    private int mX; //variable to hold x position of the mouse cursor when clicked 
    private int mY; //variable to hold y position of the mouse cursor when clicked 
    private int rect1x; 
    private int rect1y; 
    private int rect1w; 
    private int rect1h; 
    private int rect2x; 
    private int rect2y; 
    private int rect2w; 
    private int rect2h; 
    private int rect3x; 
    private int rect3y; 
    private int rect3w; 
    private int rect3h; 
    boolean rect1Clicked; 
    boolean rect2Clicked; 
    boolean rect3Clicked; 

    public void init() 
    { 
     super.init(); 
    } 

    public void paint(Graphics g) 
    { 
     super.paint(g); 

     Polygon pg = new Polygon(); 

     pg.addPoint(280, 200); 
     pg.addPoint(470, 100); 
     pg.addPoint(670, 200); 

     g.drawPolygon(pg); 

     g.setColor(Color.BLACK); 
     g.drawRect(300, 200, 350, 300); 
     g.fillRect(350, 300, 50, 100); 
     g.fillRect(550, 300, 50, 100); 
     g.fillRect(440, 300, 75, 200); 

     addMouseListener(this); 

     if(rect1Clicked || rect2Clicked || rect3Clicked) 
     { 
      g.setColor(Color.GRAY); 
      g.clearRect(rect1x, rect1y, rect1w, rect1h); 
      g.fillRect(rect1x, rect1y, rect1w, rect1h); 
      g.setColor(Color.GRAY); 
      g.clearRect(rect2x, rect2y, rect2w, rect2h); 
      g.fillRect(rect2x, rect2y, rect2w, rect2h); 
      g.setColor(Color.GRAY); 
      g.clearRect(rect3x, rect3y, rect3w, rect3h); 
      g.fillRect(rect3x, rect3y, rect3w, rect3h); 
     } 
    } 

    @Override 
    public void mouseClicked(MouseEvent e) 
    { 
     rect1x = 350; 
     rect1y = 300; 
     rect1w = 350; 
     rect1h = 300; 
     rect2x = 550; 
     rect2y = 300; 
     rect2w = 50; 
     rect2h = 100; 
     rect3x = 440; 
     rect3y = 300; 
     rect3w = 75; 
     rect3h = 200; 
     mX = e.getX(); 
     mY = e.getY(); 

     if(mX > rect1x && mX < rect1x + rect1w && mY > rect1y && mY < rect1y + rect1h) 
     { 
      rect1Clicked = true; 
     } 
     else 
     { 
      rect1Clicked = false; 
     } 
     if(mX > rect2x && mX < rect2x + rect2w && mY > rect2y && mY < rect2y+rect2h) 
     { 
      rect2Clicked = true; 
     } 
     else 
     { 
      rect2Clicked = false; 
     } 
     if(mX > rect3x && mX < rect3x + rect3w && mY > rect3y && mY < rect3y + rect3h) 
     { 
      rect3Clicked = true; 
     } 
     else 
     { 
      rect3Clicked = false; 
     } 
    } 

} 

感謝您的任何建議。

+1

對於所有神聖的事物的愛,不要在paint中添加MouseListener。這是要求災難。這種方法應該做繪畫,而不是繪畫。你無法控制何時甚至是否會被調用,或者調用了多少次。相反,將MouseListener添加到構造函數或init()方法中的圖形JPanel中,在JPanel的'paintComonent(...)'方法覆蓋中執行您的圖形。 –

+2

我會看看java.awt.Rectangle對象,以及如何使用它和它的.contains(Point p)方法。這可能會讓你的生活變得更容易。 –

+0

@Matt:很棒的評論。考慮下面的* *答案。 –

回答

0

你真的讓生活變得非常困難。 Java Graphics API有許多專門用於解決此問題的類。

作爲一般的經驗法則。切勿忽略頂級容器的任何paint方法。使用適當的組件,例如JPanelJComponent

如有可能,請改爲使用paintComponent方法。

正如HoverCraft指出的那樣,請勿在paint方法中修改UI,這包括添加偵聽器。該paint方法將被調用很多次,每次它被稱爲時間的意思,你要註冊另一個監聽器...

你會希望通過具有通過2D Graphics線索讀取和Performing Custom Painting線索

啓動儘管以下示例使用JFrame,但基本原則適用。

public static void main(String[] args) { 

    EventQueue.invokeLater(new Runnable() { 

     @Override 
     public void run() { 

      try { 
       UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
      } catch (ClassNotFoundException ex) { 
      } catch (InstantiationException ex) { 
      } catch (IllegalAccessException ex) { 
      } catch (UnsupportedLookAndFeelException ex) { 
      } 

      JFrame frame = new JFrame(); 
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
      frame.setLayout(new BorderLayout()); 
      frame.setSize(200, 200); 
      frame.add(new HousePane()); 
      frame.setVisible(true); 
      frame.setLocationRelativeTo(null); 

     } 
    }); 

} 

public static class HousePane extends JPanel { 

    private List<Rectangle2D> parts = new ArrayList<Rectangle2D>(25); 
    private List<Rectangle2D> selected = new ArrayList<Rectangle2D>(25); 

    public HousePane() { 

     parts.add(new Rectangle2D.Float(10, 10, 50, 50)); 
     parts.add(new Rectangle2D.Float(60, 10, 50, 50)); 
     parts.add(new Rectangle2D.Float(10, 60, 50, 50)); 
     parts.add(new Rectangle2D.Float(60, 60, 50, 50)); 

     addMouseListener(new MouseAdapter() { 

      @Override 
      public void mouseClicked(MouseEvent e) { 
       selected.clear(); 
       for (Rectangle2D rect : parts) { 
        if (rect.contains(e.getPoint())) { 
         selected.add(rect); 
        } 
       } 

       // You could require the user to click the shape again 
       // to deselect by doing something like... 
       //for (Rectangle2D rect : parts) { 
       // if (rect.contains(e.getPoint())) { 
       //  if (selected.contains(rect)) { 
       //   selected.remove(rect); 
       //  } else { 
       //   selected.add(rect); 
       //  } 
       // } 
       //} 
       repaint(); 
      } 

     }); 

    } 

    @Override 
    protected void paintComponent(Graphics g) { 

     super.paintComponent(g); 

     Graphics2D g2d = (Graphics2D) g; 
     g2d.setColor(Color.BLUE); 
     for (Rectangle2D rect : selected) { 

      g2d.fill(rect); 

     } 
     g2d.setColor(Color.BLACK); 
     for (Rectangle2D rect : parts) { 

      g2d.draw(rect); 

     } 

    } 

} 
+0

只是爲了讓一個概念更加具體:多次添加偵聽器,尤其是在未被刪除時,是Java中內存泄漏的常見來源。 –