MODEL-View-Controller,既模型-视图-控制器

Swing组件采用MVC(MODEL-View-Controller,既模型-视图-控制器)设计模式,其中模型(Model)用于维护组件的各种状态,视图(View)是组件的可视化表现,控制器(Controller)用于控制对于各种事件,组件做出怎样的响应.当模型发送改变时,它会通知所有依赖它的视图,视图会根据模型数据更新自己.Swing使用UI代理来包装视图和控制器,还有另一个模型对象来维护该组件的状态.例如 , 按钮JButton有一个维护其状态信息的模型ButtonModel对象,Swing组件的模型是自动设置的,因此一般都使用JButton,而无须关系ButtonModel对象.因此,Swing组件的模型是自动设置的,因此一般都使用JButton,而无须关系ButtonModel对象.因此,Swing的MVC实现也被称为Model-Delegate(模型--代理)

  1 package Com.SwingTest;
  2 
  3 
  4 import java.awt.*;
  5 import java.awt.event.*;
  6 
  7 public class SwingText_13
  8 {
  9     public static void main(String[] args)
 10     {
 11         new Calculate().launch();
 12     }    
 13 } 
 14 
 15 class Calculate extends Frame
 16 {
 17     private boolean firstFlag = true;
 18     private String str1 = "";
 19     private String str2 = "";
 20     private TextField tf = null;
 21     private String strOper = null;   //20行  strOper用来记录到底是+还是-还是*还是/操作,因为我们点击"="按钮时是无法通过该事件得到上次我们执行的到底是+还是-还是*还是/操作,所以我们需要定义一个属性strOper来记录单击"="之前的上次执行的操作
 22     
 23     
 24     public void launch()
 25     {
 26         Frame f = new Frame();
 27         f.setTitle("简单实现的计算器");
 28         tf = new TextField(30);
 29         tf.setBackground(Color.WHITE);
 30         //setLayout(new BorderLayout());  //Frame默认的布局管理器就是BorderLayout
 31         f.add(tf, BorderLayout.NORTH);
 32         Panel p = new Panel(new GridLayout(4, 4, 5, 5));
 33         for (int i=0; i<10; ++i)
 34         {
 35             Button bn = new Button("" + i);
 36             bn.setActionCommand("数字");
 37             p.add(bn);
 38             bn.addActionListener(new MyMonitor());            
 39         }
 40         
 41         Button bnAdd = new Button("+");  
 42         p.add(bnAdd);
 43         bnAdd.setActionCommand("算术操作");
 44         bnAdd.addActionListener(new MyMonitor());
 45         
 46         Button bnSub = new Button("-");  
 47         p.add(bnSub);
 48         bnSub.setActionCommand("算术操作");
 49         bnSub.addActionListener(new MyMonitor());
 50         
 51         Button bnMult = new Button("*"); 
 52         bnMult.addActionListener(new MyMonitor()); 
 53         p.add(bnMult);
 54         bnMult.setActionCommand("算术操作");
 55         
 56         Button bnDiv = new Button("/");  
 57         p.add(bnDiv);
 58         bnDiv.setActionCommand("算术操作");
 59         bnDiv.addActionListener(new MyMonitor());
 60         
 61         Button bnEq = new Button("=");  
 62         p.add(bnEq);
 63         bnEq.setActionCommand("=");
 64         bnEq.addActionListener(new MyMonitor());
 65         
 66         Button bnClear = new Button("清零");  
 67         p.add(bnClear);
 68         bnClear.setActionCommand("清零");
 69         bnClear.addActionListener(new MyMonitor());
 70         
 71         p.add(bnAdd);
 72         p.add(bnSub);
 73         p.add(bnMult);
 74         p.add(bnDiv);
 75         p.add(bnEq);
 76         p.add(bnClear);        
 77         
 78         f.add(p, BorderLayout.CENTER);
 79         f.setBounds(200, 200,300, 300);
 80         f.setBackground(Color.CYAN);
 81         f.setVisible(true);
 82         f.addWindowListener(  new WindowAdapter()
 83                               {
 84                                     @Override
 85                                     public void windowClosing(WindowEvent e)
 86                                     {
 87                                         System.exit(-1);
 88                                     }                 
 89                               }        
 90         );
 91     }
 92     
 93     
 94     //内部类
 95     class MyMonitor implements ActionListener
 96     {
 97         public void actionPerformed(ActionEvent e)
 98         {
 99             //如果是对=按钮的点击操作,则我们需要得到上次动作命令名称的信息,因为本次事件中只能得到按钮标签的信息= 和 按钮动作命令名称=, 无法得到上次执行的到底是+还是-还是*还是/操作,所以我们需要单独定义一个属性用来记录动作命令名称的信息,参见20行代码
100             /*actionPerformed()方法算法如下:
101                 第一:    我们必须先得通过e得到按钮的动作命令名称strAc和按钮标签字符串的
102                         信息strLab
103                 第二:  然后通过判断按钮的动作命令名称strAc来执行不同的操作,即:
104                         如果strAc是"数字",即如果是对0-9按钮的单击操作, 则更新str1 或者 str2的值
105                         如果strAc是"算术操作",即如果是对"+" "-" "*" "/"按钮的单击操作,则我们必须得把按钮标签字符窜strLb的值赋给属性strOper, 注意不能把strAc赋给strOper, 因为此时strAc的值是"算术操作"  
106                         如果strAc是"=", 则。。。。。。略
107                         如果strAc是"清零",则。。。。。。略
108             
109             */
110             
111             
112             String strAc = e.getActionCommand();
113             Button bn = (Button)e.getSource();
114             String strLb = bn.getLabel();
115             
116             if (strAc.equals("数字"))
117             {
118                 if (firstFlag)
119                 {
120                     str1 = str1 + strLb;   //103
121                     tf.setText(str1);
122                 }
123                 else
124                 {
125                     str2 = str2 + strLb;  //109
126                     tf.setText(str2);
127                 }
128             }
129             else if (strAc.equals("算术操作"))  //如果是+ - * / 操作 
130             {
131                 strOper = strLb;  //118   千万不要写成了 strOper = strAc;  因为本语句要被执行的话,此时strAc的值一定是"算术操作", 我们需要的是+ - * / 即我们需要的是按钮标签字符窜的信息
132                 firstFlag = false;
133             }
134             else if (strAc.equals("="))
135             {
136                 result();
137             }
138             else if (strAc.equals("清零"))
139             {
140                 str1 = str2 = "";
141                 tf.setText("");
142                 firstFlag = true;
143             }                
144         }
145     }
146     
147     public void result()
148     {
149         double num1 = Double.parseDouble(str1);
150         double num2 = Double.parseDouble(str2);
151         double num3 = 0;
152         
153         if (strOper.equals("+"))
154         {
155             num3 = num1 + num2;
156         }
157         else if (strOper.equals("-"))
158         {
159             num3 = num1 - num2;
160         }
161         else if (strOper.equals("*"))
162         {
163             num3 = num1 * num2;
164         }
165         else if (strOper.equals("/"))
166         {
167             num3 = num1 / num2;
168         }
169         
170         tf.setText("" + num3);
171         str1 = String.valueOf(num3);   //不能写成了 str1 = str2;
172         str2 = "";
173         //firstFlag = false;      //本行代码可以省略    
174     }    
175 }
原文地址:https://www.cnblogs.com/borter/p/9398542.html