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 }