首先是创建一个模型(Model)。PropertyChangeSupport成员变量,是事件委托模型中的发布订阅机制。它允许试图注册给Model,并接收Model状态的变化通告。

import java.beans.PropertyChangeListener;

import java.beans.PropertyChangeSupport;


public class Model


...{

private PropertyChangeSupport changeSupport = new PropertyChangeSupport(this);

private boolean loginStatus;

private String login;

private String password;

public Model()


...{

loginStatus = false;

}

public void setLogin(String login)


...{

this.login = login;

}

public void setPassword(String password)


...{

this.password = password;

}

public boolean getLoginStatus()


...{

return loginStatus;

}

public boolean getAllowed()


...{

boolean allowed = false;

if (login == "abc" && password == "abc")

allowed = true;

else

allowed = false;

return allowed;

}

public void setLoginStatus(boolean status)


...{

boolean old = this.loginStatus;

this.loginStatus = status;

changeSupport.firePropertyChange("model.loginStatus", old, status);

}

public void login(String login,String password)


...{

setLogin(login);

setPassword(password);

if (getAllowed())


...{

if (getLoginStatus())


...{

setLoginStatus(false);

} else


...{

setLoginStatus(true);

}

}

else

setLoginStatus(false);

}

public void addPropertyChangeListener(PropertyChangeListener listener)


...{

changeSupport.addPropertyChangeListener(listener);

}

}
然后是创建视图。CenterPanel用来输入用户数据。WorkPanel实现了PropertyChangeListener接口,这就使得WorkPanel可以注册到应用程序Model,并且当Model变化时使修改通告被发布给它。WorkPanel被作为PropertyChangeListener被注册到Model。这将在界面和域逻辑之间提供了低耦合,允许视图在Model发生变化时被修改。

import java.awt.GridLayout;

import javax.swing.JLabel;

import javax.swing.JPanel;

import javax.swing.JTextField;

import javax.swing.JPasswordField;


public class CenterPanel extends JPanel


...{

static final long serialVersionUID = 1L;

private JTextField login = new JTextField(15);

private JPasswordField password = new JPasswordField(15);

public CenterPanel()


...{

setLayout(new GridLayout(2,2));

add(new JLabel("Login:"));

add(login);

add(new JLabel("Password:"));

add(password);

}

public String getLogin()


...{

return login.getText();

}

public String getPassword()


...{

return password.getText();

}

}

import java.awt.BorderLayout;

import java.beans.PropertyChangeEvent;

import java.beans.PropertyChangeListener;

import javax.swing.Action;

import javax.swing.JButton;

import javax.swing.JLabel;

import javax.swing.JPanel;


public class WorkPanel extends JPanel implements PropertyChangeListener


...{

static final long serialVersionUID = 1L;

private Model model;

private JPanel center;

private JPanel buttonPanel = new JPanel();

private JLabel loginStatusLabel = new JLabel(" ");

public WorkPanel(JPanel center, Model model)


...{

this.center = center;

this.model = model;

init();

}

private void init()


...{

setLayout(new BorderLayout());

add(center ,BorderLayout.CENTER);

add(buttonPanel, BorderLayout.SOUTH);

add(loginStatusLabel , BorderLayout.NORTH);

}

public void propertyChange(PropertyChangeEvent evt)


...{

if (evt.getPropertyName().equals("model.loginStatus"))


...{

Boolean status = (Boolean)evt.getNewValue();

if (status.booleanValue())


...{

loginStatusLabel.setText("Login is sucessful");

}

else


...{

loginStatusLabel.setText("Login Failed");

}

}

}

public void addButton (String name , Action action)


...{

JButton button = new JButton(name);

button.addActionListener(action);

buttonPanel.add(button);

}

}
接着是控制器。控制器的目的是作为模型修改的入口来提供服务。Action类通过组件addActionListener()方法注册到一个或者多个图形组件中。以下两个Action,一个尝试使用Model进行登录,一个用于退出应用程序。

import java.awt.event.ActionEvent;

import javax.swing.AbstractAction;


public class LoginAction extends AbstractAction


...{

static final long serialVersionUID = 1L;

private Model model;

private CenterPanel panel;

public LoginAction(Model model,CenterPanel panel)


...{

this.model = model;

this.panel = panel;

}

public void actionPerformed(ActionEvent e)


...{

System.out.println("Login Action:" + panel.getLogin() + " " + panel.getPassword());

model.login(panel.getLogin(), panel.getPassword());

}

}

import java.awt.event.ActionEvent;

import javax.swing.AbstractAction;

import javax.swing.JFrame;

import javax.swing.JOptionPane;


public class ExitAction extends AbstractAction


...{

static final long serialVersionUID = 1L;

public void actionPerformed(ActionEvent e)


...{

JFrame frame = new JFrame();

int response = JOptionPane.showConfirmDialog(frame, "Exit Application?", "Exit", JOptionPane.OK_CANCEL_OPTION);

if (JOptionPane.YES_OPTION == response)


...{

System.exit(0);

}

}

}
最后,Application类用来初始化。它创建关联,建立起了MVC逻辑设计原则。
1、创建到Model类的关联;
2、创建View来显示Swing接口;
3、创建Action类,表示控制器并且将通过命令按钮来注册它们;
4、最后用Swing来显示应用程序;

import java.awt.event.WindowAdapter;

import java.awt.event.WindowEvent;

import javax.swing.JFrame;

import javax.swing.JOptionPane;


public class Application extends JFrame


...{

static final long serialVersionUID = 1L;

private Model model;

public Application(Model model)


...{

this.model = model;

CenterPanel center = new CenterPanel();

WorkPanel work = new WorkPanel(center,model);

work.addButton("login", new LoginAction(model,center));

work.addButton("exit", new ExitAction());

model.addPropertyChangeListener(work);

setTitle("MVC Pattern Application");

getContentPane().add(work);

pack();

setVisible(true);

addWindowListener(new WindowAdapter()


...{

public void windowClosing(WindowEvent e)


...{

int response = JOptionPane.showConfirmDialog(null, "Exit Application?", "Exit", JOptionPane.OK_CANCEL_OPTION);

if (JOptionPane.YES_OPTION == response)


...{

// dispose();

// finalize();

System.exit(0);

}

}

});

}

public static void main(String[] args)


...{

Model model = new Model();

Application application = new Application(model);

}

}