代码改变世界

个人MVC程序及心得

2012-11-22 19:52  youxin  阅读(348)  评论(0编辑  收藏  举报

用MVC写了一个简单的图片浏览程序。程序界面如下:

 

整个程序的编写采用了MVC的架构,总算对MVC有了一定的认识。

首先编写Model。

ModelInterface如下;

public interface ModelInterface {
    
    void registerObserver(NextObserver o);
    void removeObserver(NextObserver o);
    
    //oid init();
    String getImageStr();
    int getImageIndex();
    void setImageStr(int i);

}

Model:

public class Model implements ModelInterface{

 
    String dir="../images/";
    private String[] imageFileNames = { "sunw01.jpg", "sunw02.jpg",
                "sunw03.jpg", "sunw04.jpg", "sunw05.jpg"};
    
    private String  imgStr;
       
    private int index;
    public ArrayList observers=new ArrayList();
    
    public Model()
    {
        index=0;
             
    }
    public String getImageStr()
    {
        return dir+imageFileNames[index];
    }
    
    public int getImageIndex()
    {
     
        return index;
    
    }
    
    public void setImageStr(int i)
    {
        index=i;
        notifyObservers();
    }
    
    @Override
    public void registerObserver(NextObserver o) {
        observers.add(o);
        
    }

    @Override
    public void removeObserver(NextObserver o) {
        int i=observers.indexOf(o);
        if(i>=0)
        {
            observers.remove(i);
        }
        
    }
 
    public void notifyObservers()
    {
        for(int i=0;i<observers.size();i++)
        {
            NextObserver observer=(NextObserver)observers.get(i);
            observer.updateView();
        }
    }
    
  
}

注意:凡是要用model类型的接口调用的方法,都要写在model接口中

视图类:视图是model的观察者,实现了NextObserver接口,接口如下:

public interface NextObserver {
    void updateView();

}

可以看到,接口中只有一个方法,就是更新方法。

View:

public class View extends JFrame implements NextObserver,ActionListener{

    ModelInterface model;
    ControllerInterface controller;
    private JButton prevButton,nextButton;
    private JButton  captionButton;
    private JLabel photoLabel;
    ImageIcon icon;
    
    public View(ControllerInterface controller,ModelInterface model)
    {
        super("ImageViewer");

        this.controller=controller;
        this.model=model;
        
        model.registerObserver(this);
       
        
        setSize(700,500);
        
        setLayout(new FlowLayout());
        Container container=getContentPane();
        
        setLocationRelativeTo(null);
        prevButton=new JButton("Prev");
        nextButton=new JButton("Next");
        captionButton=new JButton("图片标题");
        
        icon=createImageIcon(model.getImageStr(),"description");
        photoLabel=new JLabel(icon);
        
        
        container.add(prevButton);
        container.add(nextButton);
        container.add(captionButton);
        container.add(photoLabel);
        
        //一定要注册事件监听器
        prevButton.addActionListener(this);
        nextButton.addActionListener(this);
         
         
        setVisible(true);
        
    
    }
    
    
    @Override
    public void actionPerformed(ActionEvent e) {
         
        if(e.getSource()==prevButton)
        {
    
            controller.displayPrev();视图将接收到的事件委派给控制器。
        }
        else if(e.getSource()==nextButton)
        {
             
            controller.displayNext();
        }
         
    }


    @Override
    public void updateView() { //这个方法到底如何调用。
       captionButton.setText(model.getImageStr());
       icon=createImageIcon(model.getImageStr(),"description");
       photoLabel.setIcon(icon);
      captionButton.setToolTipText(model.getImageStr());
        
    }

    
    /**
     * Creates an ImageIcon if the path is valid.
     * @param String - resource path
     * @param String - description of the file
     */
    protected ImageIcon createImageIcon(String path,
            String description) {
        java.net.URL imgURL = getClass().getResource(path);
        if (imgURL != null) {
            return new ImageIcon(imgURL, description);
        } else {
            System.err.println("Couldn't find file: " + path);
            return null;
        }
    }
    
    public void enablePrevButton()
    {
        prevButton.setEnabled(true);
    }
    public void disablePrevButton()
    {
        prevButton.setEnabled(false);
    }

    public void enableNextButton()
    {
        nextButton.setEnabled(true);
    }
    public void disableNextButton()
    {
        nextButton.setEnabled(false);
    }

    
}

 

ControllerInterface如下:

public interface ControllerInterface {
    void displayPrev();
    void displayNext();
    
}

为什么有这2个方法在接口中,因为在View中调用了ControllerInterface的这两个方法,所以一定要在接口中

Controller:

public class Controller implements ControllerInterface{

    ModelInterface model;
    View view;
    
    public Controller(ModelInterface model)
    {
        this.model=model;
        view=new View(this,model);
         
        //model.init();
        view.disablePrevButton();
        
    }
    @Override
    public void displayPrev() {
        // TODO Auto-generated method stub
        int i=model.getImageIndex();
        if(i==1)
        {
            view.disablePrevButton();
            view.enableNextButton();
            
        }
        else
        {
            view.enablePrevButton();
            view.enableNextButton();
        }
        model.setImageStr(i-1);
        
    }

    public void displayNext() {
        // TODO Auto-generated method stub
         
        
        int i=model.getImageIndex();
        if(i==3)
        {
           view.disableNextButton();
           view.enablePrevButton();
         
        }
        else  
        {
            view.enableNextButton();
            view.enablePrevButton();
        }
        model.setImageStr(i+1);;
    }
 
}

测试代码:

public class TestMain {
public static void main(String[] args)
{
ModelInterface model=new Model();
ControllerInterface controller=new Controller(model);

}

}

现在来看看updateView到底是怎么调用的。

花了很久才掌握mvc。