2015-10-27 36 views
1

我不知道如果我正在做一個適當的MVC,但我不能執行Clear()從我的看法。MVC函數錯誤,當按鈕通過試圖從JComponent調用函數

主要

public class Main{ 
    public static void main(String[] args) { 
     Model model = new Model(); 
     final View view = new View(); 
     Controller controller = new Controller(view, model); 

     javax.swing.SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       view.showView(); 
      } 
     }); 
    } 
} 

型號

public class Model { 
    DrawPad drawPad = new DrawPad(); 
     Model() { 
    } 
    public void Clear() { 
     drawPad.clear(); 
     System.out.print("HELP"); 
    } 
} 

查看

public class View extends JFrame { 
    JButton clearButton = new JButton("Clear"); 
    DrawPad drawPad = new DrawPad(); 
    Model model; 

    public void showView() { 
     JFrame frame = new JFrame(); 
     drawPad.DrawPad(); 
     frame.add(drawPad, BorderLayout.CENTER); 
     frame.add(clearButton, BorderLayout.SOUTH); 
     frame.setSize(280, 300); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setVisible(true); 
    } 

    public void addButtonActionListener(ActionListener clr) { 
     clearButton.addActionListener(clr); 
    } 
} 

控制器

public class Controller implements ActionListener { 
    View view; 
    Model model; 

    Controller(View v, Model m) { 
     this.view = v; 
     this.model = m; 
     view.addButtonActionListener(this); 
    } 

    public void actionPerformed(ActionEvent e) { 
     model.Clear(); 
     System.out.print("H"); 
    } 
} 

JComponent的

class DrawPad extends JComponent { 
    Image image; 
    public Graphics2D graphics2D; 
    int currentX, currentY, oldX, oldY; 

    public void DrawPad() { 
     setDoubleBuffered(false); 
     addMouseListener(new MouseAdapter() { 
      public void mousePressed(MouseEvent e) { 
       oldX = e.getX(); 
       oldY = e.getY(); 
      } 
     }); 

     addMouseMotionListener(new MouseMotionAdapter() { 
      public void mouseDragged(MouseEvent e) { 

       currentX = e.getX(); 
       currentY = e.getY(); 
       if (graphics2D != null) 
        graphics2D.drawLine(oldX, oldY, currentX, currentY); 
       repaint(); 
       oldX = currentX; 
       oldY = currentY; 
      } 
     }); 
    } 

    public void paintComponent(Graphics g) { 
     if (image == null) { 
      image = createImage(getSize().width, getSize().height); 
      graphics2D = (Graphics2D) image.getGraphics(); 
      graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
      clear(); 
     } 
     g.drawImage(image, 0, 0, null); 
    } 

    public void clear() { 
     System.out.println("Test"); 
     graphics2D.setPaint(Color.white); 
     graphics2D.fillRect(0, 0, getSize().width, getSize().height); 
     graphics2D.setPaint(Color.black); 
     repaint(); 
    } 
} 

如果我使用我的看法事件偵聽器,並創建一個drawPad並直接調用clear(),我能夠執行。但是,當我調用清晰的模型和控制器時,會引發錯誤。

任何想法,如果我做錯了什麼?也許我錯過了什麼?

+1

的模型和視圖應該沒有概念控制器在兩者之​​間起到新娘的作用,這意味着模型將需要觸發某些事件,控制器將對此作出響應,這會導致控制器在視圖上調用「清除」... – MadProgrammer

+1

給予您的模型SwingPropertyChangeSupport o然後通過製作「綁定」屬性來使用它,通過改變時通知支持對象的屬性,可以幫助解決@MadProgrammer上面提到的問題。您還必須爲外部類提供一種機制,以在需要時將PropertyChangeListeners添加到此支持對象。 –

+1

還有一些問題:'paintComponent'應該被保護,而不是公共的,它應該有一個'@ Override'註釋,並且你應該在其中調用'super.paintComponent(...)'方法。 –

回答

4

圍繞試圖總結一個純粹的MVC模式ontop的非純MVC模式的問題和事實步進,你DrawPad實際上應該有它自己的MVC纏着,你需要提供一個Observer Pattern允許Controller以監視Model中可能發生的更改。

例如...

​​

然後,當您創建Controller,你會註冊一個ModelListener到模型...

public class Controller implements ActionListener { 

    View view; 
    Model model; 

    Controller(View v, Model m) { 
     this.view = v; 
     this.model = m; 
     model.addModelListener(new ModelListener() { 
      @Override 
      public void modelCleared(Model model) { 
       view.clear(); 
      } 
     }); 
     view.addButtonActionListener(this); 
    } 

    public void actionPerformed(ActionEvent e) { 
     model.Clear(); 
     System.out.print("H"); 
    } 
}