java 图形界面 mvc模式控制

使用模型-视图-控件结构来开发GUI程序。

下面的程序演示了MVC模式开发的java程序。

其中CircleModel为模型,包含了圆的半径,是否填充,等属性。

CircleView为视图,显示这个圆。

CircleController为控制器,控制圆的大小,以及是否被填充。

模型:

 1 package circleMVC;
 2 
 3 import java.awt.Color;
 4 import java.awt.event.*;
 5 import java.util.*;
 6 
 7 public class CircleModel {
 8     //圆半径
 9     private double radius = 20;
10     
11     //是否填充
12     private boolean filled;
13     
14     //颜色
15     private java.awt.Color color;
16     
17     private ArrayList<ActionListener> actionListenerList;
18 
19     public double getRadius() {
20         return radius;
21     }
22 
23     public void setRadius(double radius) {
24         this.radius = radius;
25         processEvent(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "radius"));//当属性值改变是通知监听器
26     }
27 
28     public boolean isFilled() {
29         return filled;
30     }
31 
32     public void setFilled(boolean filled) {
33         this.filled = filled;
34         processEvent(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "filled"));//当属性值改变是通知监听器
35     }
36     
37     
38 
39     public java.awt.Color getColor() {
40         return color;
41     }
42 
43     public void setColor(java.awt.Color color) {
44         this.color = color;
45         processEvent(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "color"));//当属性值改变是通知监听器
46     }
47 
48     public synchronized void addActionListener(ActionListener l){
49         if(actionListenerList == null){
50             actionListenerList = new ArrayList<ActionListener>();
51         }
52         actionListenerList.add(l);
53     }
54     
55     public synchronized void removeActionListener(ActionListener l){
56         if(actionListenerList != null && actionListenerList.contains(l)){
57             actionListenerList.remove(l);
58         }
59     }
60     
61     private void processEvent(ActionEvent e){
62         ArrayList list;
63         
64         synchronized(this){
65             if(actionListenerList == null) return;
66             list = (ArrayList)actionListenerList.clone();
67         }
68         for(int i = 0; i < list.size(); i++){
69             ActionListener listener = (ActionListener)list.get(i);
70             listener.actionPerformed(e);
71         }
72     }
73 }
View Code

视图:

 1 package circleMVC;
 2 
 3 import java.awt.*;
 4 import java.awt.event.*;
 5 import javax.swing.*;
 6 public class CircleView extends JPanel implements ActionListener{
 7     private  CircleModel model;
 8     
 9     public void actionPerformed(ActionEvent actionEvent){
10         repaint();
11     }
12     
13     //设置一个model
14     public void setModel(CircleModel newModel) {
15         model = newModel;
16         
17         if(model != null){
18             //给model增加啊监听器
19             model.addActionListener(this);
20         }
21         
22         repaint();
23     }
24     
25     public CircleModel getModel(){
26         return model;
27     }
28     
29     public void paintComponent(Graphics g){
30         super.paintComponent(g);
31         
32         if(model == null)  return;
33         
34         g.setColor(model.getColor());
35         
36         int xCenter = getWidth() / 2;
37         int yCenter = getHeight() / 2;
38         int radius = (int)model.getRadius();
39         
40         if(model.isFilled()) {
41             g.fillOval(xCenter - radius, yCenter - radius, 2 * radius, 2 * radius);
42         }else{
43             g.drawOval(xCenter - radius, yCenter - radius, 2 * radius, 2 * radius);
44         }
45     }
46 }
View Code

控制器

 1 package circleMVC;
 2 
 3 import java.awt.*;
 4 import java.awt.event.*;
 5 import javax.swing.*;
 6 public class CircleController extends JPanel{
 7     private CircleModel model;
 8     private JTextField jtfRadius = new JTextField();
 9     @SuppressWarnings("unchecked")
10     private JComboBox jcboFilled = new JComboBox(new Boolean[]{
11             new Boolean(false), new Boolean(true)
12     });
13     private JRadioButton jrbRed, jrbGreen, jrbBlue; 
14     
15     //创建一个新的CircleController
16     public CircleController(){
17         JPanel panel1 = new JPanel();
18         panel1.setLayout(new GridLayout(2,1));
19         panel1.add(new JLabel("Radius"));
20         panel1.add(new JLabel("Filled"));
21         
22         //
23         JPanel panel2 = new JPanel();
24         panel2.setLayout(new GridLayout(2,1));
25         panel2.add(jtfRadius);
26         panel2.add(jcboFilled);
27         
28         JPanel panel3 = new JPanel();
29         panel3.setLayout(new GridLayout(1, 3));
30         panel3.add(jrbRed = new JRadioButton("Red"));
31         panel3.add(jrbGreen = new JRadioButton("Green"));
32         panel3.add(jrbBlue = new JRadioButton("Blue"));
33         
34         
35         
36         setLayout(new BorderLayout());
37         add(panel1, BorderLayout.WEST);
38         add(panel2, BorderLayout.CENTER);
39         add(panel3, BorderLayout.SOUTH);
40         
41         //将三个单选框组成单选按钮
42          ButtonGroup group = new ButtonGroup();
43         group.add(jrbRed);
44         group.add(jrbGreen);
45         group.add(jrbBlue);
46         
47         jtfRadius.addActionListener(new ActionListener(){
48             public void actionPerformed(ActionEvent e) {
49                 if(model == null) return ;//还没有model
50                 model.setRadius(new Double(jtfRadius.getText()).doubleValue());
51             }
52         });
53         
54         jcboFilled.addActionListener(new ActionListener(){
55             public void actionPerformed(ActionEvent e){
56                 if(model == null) return;
57                 model.setFilled(  ((Boolean)jcboFilled.getSelectedItem()).booleanValue());
58             }
59         });
60         
61         //单选按钮监听
62         jrbRed.addActionListener(new ActionListener(){
63             public void actionPerformed(ActionEvent e){
64                 if(model == null) return;
65                 model.setColor(Color.RED);
66             }
67         });
68         
69         jrbGreen.addActionListener(new ActionListener(){
70             public void actionPerformed(ActionEvent e){
71                 if(model == null) return;
72                 model.setColor(Color.GREEN);
73             }
74         });
75         
76         jrbBlue.addActionListener(new ActionListener(){
77             public void actionPerformed(ActionEvent e){
78                 if(model == null) return;
79                 model.setColor(Color.BLUE);
80             }
81         });
82     }
83     
84     public void setModel(CircleModel newModel){
85         model = newModel;
86     }
87 
88     public CircleModel getModel() {
89         return model;
90     }
91 }
View Code

MVCDemo:

 1 package circleMVC;
 2 
 3 import java.awt.*;
 4 import java.awt.event.*;
 5 import javax.swing.*;
 6 public class MVCDemo extends JApplet {
 7     private JButton jbtController = new JButton("Show Contuoller");
 8     private JButton jbtView = new JButton("Show View");
 9     private CircleModel model = new CircleModel();
10     
11     public MVCDemo() {
12         setLayout(new FlowLayout());
13         add(jbtController);
14         add(jbtView);
15         
16         jbtController.addActionListener(new ActionListener() {
17             @Override
18             public void actionPerformed(ActionEvent e) {
19                 
20                 JFrame frame = new JFrame("Controller");
21                 CircleController controller = new CircleController();
22                 controller.setModel(model);
23                 frame.add(controller);
24                 frame.setSize(240, 100);
25                 frame.setLocation(200, 200);
26                 frame.setVisible(true);
27             }
28         });
29         
30         jbtView.addActionListener(new ActionListener() {
31             
32             @Override
33             public void actionPerformed(ActionEvent e) {
34                 JFrame frame = new JFrame("view");
35                 CircleView view = new CircleView();
36                 view.setModel(model);
37                 frame.add(view);
38                 frame.setSize(200, 200);
39                 frame.setLocation(200, 200);
40                 frame.setVisible(true);
41             }
42         });
43     }
44 
45 }
View Code

运行效果:

二、

在同一个窗口中使用MVC模式,控制器和视图都在同一个窗口中,可以使用鼠标拖动来控制半径,也可以使用输入来控制半径,同时面积和体积要同步更新。

难点:在同一个窗口中,控制器的数据怎么和视图的数据进行交互,而且要同步显示,控制器和视图相互交错,控制器也是视图,视图也是控制器。

代码如下:

模型:

 1 /**
 2  * java MVC模式 模型部分
 3  * 2016/5/22
 4  */
 5 package circleMVC_x;
 6 
 7 import java.awt.Color;
 8 import java.awt.event.*;
 9 import java.util.*;
10 
11 public class CircleModel {
12     //圆半径
13     private double radius = 20;
14     
15     //是否填充
16     private boolean filled;
17     
18     //颜色
19     private java.awt.Color color;
20     
21     private ArrayList<ActionListener> actionListenerList;
22 
23     public double getRadius() {
24         return radius;
25     }
26 
27     public void setRadius(double radius) {
28         this.radius = radius;
29         processEvent(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "radius"));//当属性值改变是通知监听器
30     }
31 
32     public boolean isFilled() {
33         return filled;
34     }
35 
36     public void setFilled(boolean filled) {
37         this.filled = filled;
38         processEvent(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "filled"));//当属性值改变是通知监听器
39     }
40     
41     
42 
43     public java.awt.Color getColor() {
44         return color;
45     }
46 
47     public void setColor(java.awt.Color color) {
48         this.color = color;
49         processEvent(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "color"));//当属性值改变是通知监听器
50     }
51 
52     public synchronized void addActionListener(ActionListener l){
53         if(actionListenerList == null){
54             actionListenerList = new ArrayList<ActionListener>();
55         }
56         actionListenerList.add(l);
57     }
58     
59     public synchronized void removeActionListener(ActionListener l){
60         if(actionListenerList != null && actionListenerList.contains(l)){
61             actionListenerList.remove(l);
62         }
63     }
64     
65     private void processEvent(ActionEvent e){
66         ArrayList list;
67         
68         synchronized(this){
69             if(actionListenerList == null) return;
70             list = (ArrayList)actionListenerList.clone();
71         }
72         for(int i = 0; i < list.size(); i++){
73             ActionListener listener = (ActionListener)list.get(i);
74             listener.actionPerformed(e);
75         }
76     }
77 }
模型

 控制器:

  1 /**
  2  * java MVC模式 控制器部分(其中面积,体积部分不能设置,算作视图)
  3  * 2016/5/22
  4  */
  5 package circleMVC_x;
  6 
  7 import java.awt.*;
  8 import java.awt.event.*;
  9 import javax.swing.*;
 10 public class CircleController extends JPanel implements ActionListener{
 11     private CircleModel model;
 12     private JTextField jtfRadius = new JTextField();
 13     private JTextField jtfArea = new JTextField();
 14     private JTextField jtfVolume= new JTextField();
 15     private JRadioButton jrbRed, jrbGreen, jrbBlue; 
 16     
 17     //创建一个新的CircleController
 18     public CircleController(){
 19         JPanel panel1 = new JPanel();
 20         panel1.setLayout(new GridLayout(3,1));
 21         panel1.add(new JLabel("半径:"));
 22         panel1.add(new JLabel("面积:"));
 23         panel1.add(new JLabel("体积:"));
 24         
 25         //
 26         JPanel panel2 = new JPanel();
 27         panel2.setLayout(new GridLayout(3,1));
 28         panel2.add(jtfRadius);
 29         panel2.add(jtfArea);
 30         panel2.add(jtfVolume);
 31         
 32         JPanel panel3 = new JPanel();
 33         panel3.setLayout(new GridLayout(1, 3));
 34         panel3.add(jrbRed = new JRadioButton("Red"));
 35         panel3.add(jrbGreen = new JRadioButton("Green"));
 36         panel3.add(jrbBlue = new JRadioButton("Blue"));
 37         
 38         
 39         
 40         setLayout(new BorderLayout());
 41         add(panel1, BorderLayout.WEST);
 42         add(panel2, BorderLayout.CENTER);
 43         add(panel3, BorderLayout.SOUTH);
 44         
 45         //将三个单选框组成单选按钮
 46          ButtonGroup group = new ButtonGroup();
 47         group.add(jrbRed);
 48         group.add(jrbGreen);
 49         group.add(jrbBlue);
 50         
 51         jtfRadius.addActionListener(new ActionListener(){
 52             public void actionPerformed(ActionEvent e) {
 53                 if(model == null) return ;//还没有model
 54                 model.setRadius(new Double(jtfRadius.getText()).doubleValue());
 55             }
 56         });
 57         
 58         
 59         //单选按钮监听
 60         jrbRed.addActionListener(new ActionListener(){
 61             public void actionPerformed(ActionEvent e){
 62                 if(model == null) return;
 63                 model.setColor(Color.RED);
 64             }
 65         });
 66         
 67         jrbGreen.addActionListener(new ActionListener(){
 68             public void actionPerformed(ActionEvent e){
 69                 if(model == null) return;
 70                 model.setColor(Color.GREEN);
 71             }
 72         });
 73         
 74         jrbBlue.addActionListener(new ActionListener(){
 75             public void actionPerformed(ActionEvent e){
 76                 if(model == null) return;
 77                 model.setColor(Color.BLUE);
 78             }
 79         });
 80     }
 81     
 82     public void setModel(CircleModel newModel){
 83         model = newModel;
 84         if(model != null){
 85             //给model增加啊监听器
 86             model.addActionListener(this);
 87         }
 88     }
 89 
 90     public CircleModel getModel() {
 91         return model;
 92     }
 93 
 94     @Override
 95     public void actionPerformed(ActionEvent e) {
 96         double radius = model.getRadius();
 97         jtfRadius.setText(model.getRadius()+"");
 98         double num_1 = 4 * Math.PI * radius * radius;
 99         double num_1_1 =  (Math.round(num_1 * 100) / 100.0);// 保留两位小数
100         jtfArea.setText(num_1_1+"");
101         double num_2 = 4 / 3 * Math.PI * radius * radius;
102         double num_2_2 = (Math.round(num_2 * 100) / 100.0);// 保留两位小数
103         jtfVolume.setText(num_2_2+"");
104         
105     }
106 }
控制器

 视图:

 1 /**
 2  * java MVC模式 视图部分
 3  * 2016/5/22
 4  */
 5 package circleMVC_x;
 6 
 7 import java.awt.*;
 8 import java.awt.event.*;
 9 import javax.swing.*;
10 public class CircleView extends JPanel implements ActionListener{
11     private  CircleModel model;
12     
13     public CircleView(){
14         super.setBounds(12, 144, 426, 300);
15         repaint();
16         //增加鼠标监听事件
17         addMouseMotionListener(new MouseMotionAdapter() {
18             public void mouseDragged(MouseEvent e){
19                 model = getModel();
20                 
21                 int x = e.getX();
22                 int y = e.getY();
23                 int radius;
24                 
25                 double radius_d = Math.sqrt((x - (getWidth() / 2))
26                         * (x - (getWidth() / 2)) + (y - (getHeight() / 2))
27                         * (y - (getHeight() / 2)));
28                 
29                 radius = (int) radius_d;
30                 
31                 System.out.println("坐标:" + x + "  " + y );
32                 model.setRadius(radius);
33                 repaint();
34                 
35             }
36         });
37     }
38     public void actionPerformed(ActionEvent actionEvent){
39         repaint();
40     }
41     
42     //设置一个model
43     public void setModel(CircleModel newModel) {
44         model = newModel;
45         
46         if(model != null){
47             //给model增加啊监听器
48             model.addActionListener(this);
49         }
50         
51         repaint();
52     }
53     
54     public CircleModel getModel(){
55         return model;
56     }
57     
58     public void paintComponent(Graphics g){
59         super.paintComponent(g);
60         
61         if(model == null)  return;
62         
63         g.setColor(model.getColor());
64         
65         int radius = (int)model.getRadius();
66         
67             g.drawOval(getWidth() / 2 - radius, getHeight() / 2 - radius,
68                     2 * radius, 2 * radius);
69             g.drawOval(getWidth() / 2 - radius / 2, getHeight() / 2 - radius,
70                     radius, 2 * radius);
71             g.drawOval(getWidth() / 2 - radius, getHeight() / 2 - radius / 2,
72                     2 * radius, radius);
73         }
74 }
视图

 程序入口:

 1 /**
 2  * javaMVC模式  入口
 3  * 2016/6/20
 4  */
 5 package circleMVC_x;
 6 
 7 import java.awt.BorderLayout;
 8 import java.awt.EventQueue;
 9 
10 import javax.swing.JFrame;
11 import javax.swing.JPanel;
12 import javax.swing.border.EmptyBorder;
13 import java.awt.FlowLayout;
14 
15 public class MVCdemo_x extends JFrame {
16 
17     private JPanel contentPane;
18     private CircleController controller = new CircleController();
19     private CircleView view = new CircleView();
20     private CircleModel model = new CircleModel();
21 
22     /**
23      * Launch the application.
24      */
25     public static void main(String[] args) {
26         EventQueue.invokeLater(new Runnable() {
27             public void run() {
28                 try {
29                     MVCdemo_x frame = new MVCdemo_x();
30                     frame.setSize(500, 500);
31                     frame.setVisible(true);
32                 } catch (Exception e) {
33                     e.printStackTrace();
34                 }
35             }
36         });
37     }
38 
39     /**
40      * Create the frame.
41      */
42     public MVCdemo_x() {
43         setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
44         setBounds(100, 100, 450, 300);
45         contentPane = new JPanel();
46         contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
47         setContentPane(contentPane);
48         contentPane.setLayout(null);
49         
50         JPanel panel = new JPanel();
51         controller.setModel(model);
52         panel.add(controller);
53         panel.setBounds(57, 34, 310, 98);
54         contentPane.add(panel);
55         
56         view.setModel(model);
57         contentPane.add(view);
58     }
59 }
程序入口

运行结果:

原文地址:https://www.cnblogs.com/snail-lb/p/5516313.html