一实现两个数求和并且输出结果
利用所学的GUI编程实现上述的要求。
TFMath.java源代码:
<span style="font-size:18px;">import java.awt.*; import java.awt.event.*; public class TFMath { public static void main(String[] args) { new TFFrame().launchFrame(); } } class TFFrame extends Frame{ TextField num1, num2, num3; public void launchFrame(){ num1 = new TextField(10); num2 = new TextField(10); num3 = new TextField(15); Label lblPlus = new Label("+"); Button btnEqual = new Button("="); //在等号对象上添加监听器 btnEqual.addActionListener(new MyMonitor(num1.num2,num3)); setLayout(new FlowLayout()); add(num1); add(lblPlus); add(num2); add(btnEqual); add(num3); pack(); setVisible(true); } } class MyMonitor implements ActionListener{ TextField num1, num2, num3; public MyMonitor(TextField num1, TextField num2, TextField num3){ this.num1 = num1; this.num2 = num2; this.num3 = num3; } public void actionPerformed(ActionEvent e) { int n1 = Integer.parseInt(num1.getText()); int n2 = Integer.parseInt(num2.getText()); num3.setText("" + (n1+n2)); } }</span>
运行结果:
对上面的代码进行优化,体现设计模式的门面模式以及调停这模式。
优化后的代码:
<span style="font-size:18px;">import java.awt.*; import java.awt.event.*; public class TFMath { public static void main(String[] args) { new TFFrame().launchFrame(); } } class TFFrame extends Frame{ TextField num1, num2, num3; public void launchFrame(){ num1 = new TextField(10); num2 = new TextField(10); num3 = new TextField(15); Label lblPlus = new Label("+"); Button btnEqual = new Button("="); //在等号对象上添加监听器 btnEqual.addActionListener(new MyMonitor(this)); setLayout(new FlowLayout()); add(num1); add(lblPlus); add(num2); add(btnEqual); add(num3); pack(); setVisible(true); } } class MyMonitor implements ActionListener{ TFFrame tf = null; public MyMonitor(TFFrame tf) { this.tf = tf; } public void actionPerformed(ActionEvent e) { int n1 = Integer.parseInt(tf.num1.getText()); int n2 = Integer.parseInt(tf.num2.getText()); tf.num3.setText("" + (n1+n2)); } }</span>
我们也可以使用内部类进行代码优化。
优化后的代码:
<span style="font-size:18px;">import java.awt.*; import java.awt.event.*; public class TFMath { public static void main(String[] args) { new TFFrame().launchFrame(); } } class TFFrame extends Frame{ TextField num1, num2, num3; public void launchFrame(){ num1 = new TextField(10); num2 = new TextField(10); num3 = new TextField(15); Label lblPlus = new Label("+"); Button btnEqual = new Button("="); //在等号对象上添加监听器 btnEqual.addActionListener(new MyMonitor()); setLayout(new FlowLayout()); add(num1); add(lblPlus); add(num2); add(btnEqual); add(num3); pack(); setVisible(true); } //内部类MyMonitor private class MyMonitor implements ActionListener { public void actionPerformed(ActionEvent e) { int n1 = Integer.parseInt(num1.getText()); int n2 = Integer.parseInt(num2.getText()); num3.setText("" + (n1+n2)); } } }</span>
两个的结果都同第一个结果。
有关于内部类的使用,详细参考:JavaSE入门学习14:Java面向对象之内部类。
使用内部类好处:
1)可以方便的访问包装类的成员。
2)可以更清楚的组织逻辑,放置不应该被其它类访问的类进行访问。
何时使用内部类?
该类不允许或不需要其他类进行访问时。
对于上面的代码,我们还可以再进行优化。
TFMathTest.java源代码:
<span style="font-size:18px;">import java.awt.*; import java.awt.event.*; public class TFMathTest extends Frame{ TextField num1; TextField num2; TextField sum; public static void main(String[] args){ new TFMathTest().launchFrame(); } public void launchFrame(){ num1 = new TextField(); num2 = new TextField(); sum = new TextField(); num1.setColumns(10); num2.setColumns(10); sum.setColumns(15); setLayout(new FlowLayout()); //setSize(500, 30); Label lblPlus = new Label("+"); Button btnEqual = new Button("="); btnEqual.addActionListener(new MyListener(this)); add(num1); add(lblPlus); add(num2); add(btnEqual); add(sum); pack(); setVisible(true); } } class MyListener implements ActionListener{ private TFMathTest tfmt; public MyListener(TFMathTest tfmt){ this.tfmt = tfmt; } public void actionPerformed(ActionEvent e){ String s1 = tfmt.num1.getText(); String s2 = tfmt.num2.getText(); int i1 = Integer.parseInt(s1); int i2 = Integer.parseInt(s2); tfmt.sum.setText(String.valueOf(i1 + i2)); } }</span>
二Graphics类
每个Component都有一个paint(Graphics g)用于实现绘图目的,每次重画该Component时都会自动调用paint()方法。
Graphics类中提供了许多绘图方法,如:
drawRect(int x,int y,int width,int height)
fillRoundRect(int x,int y,int width,int height,int arcWidth,int arcHeight)
更多的方法和用法请查看API文档。
实例:
TestPaint.java源代码:
<span style="font-size:18px;">import java.awt.*; public class TestPaint { public static void main(String[] args) { new PaintFrame().launchFrame(); } } class PaintFrame extends Frame { public void launchFrame() { setBounds(200,200,640,480); setVisible(true); } public void paint(Graphics g) { Color c = g.getColor(); g.setColor(Color.red); g.fillOval(50, 50, 30, 30); g.setColor(Color.green); g.fillRect(80,80,40,40); //恢复原来画笔的颜色 g.setColor(c); } }</span>
运行结果:
三鼠标事件适配器
抽象类java.awt.event.MouseAdapter实现类MouseListener接口,可以使用其子类作为MouseEvent的监听器,
只要重写其相应的方法即可。
对于其他的监听器,也有对应的适配器。使用适配器可以避免监听器类定义没有必要的空方法。
机制:repaint()方法中调用了update()方法,而update()方法又调用了paint()方法。
实例:
MyMouseAdapter.java源代码:
<span style="font-size:18px;">import java.awt.*; import java.awt.event.*; import java.util.*; public class MyMouseAdapter{ public static void main(String args[]){ new MyFrame("drawing"); } } class MyFrame extends Frame{ ArrayList<Point> points = null; //构造方法 MyFrame(String s){ super(s); points = new ArrayList<Point>(); setLayout(null); setBounds(300,300,400,300); this.setBackground(new Color(204,204,255)); setVisible(true); this.addMouseListener(new Monitor()); } //画圆 public void paint(Graphics g){ Iterator<Point> i = points.iterator(); while(i.hasNext()){ Point p = (Point)i.next(); g.setColor(Color.BLUE); g.fillOval(p.x,p.y,20,20); } } public void addPoint(Point p){ //向points对象中添加点对象 points.add(p); } } //MouseAdapter类实现了MouseListener接口 class Monitor extends MouseAdapter{ public void mousePressed(MouseEvent e){ MyFrame f = (MyFrame)e.getSource(); f.addPoint(new Point(e.getX(),e.getY()); //进行重画 f.repaint(); } }</span>
运行结果:
在窗口中点击会画出很多实心小圆
四Window事件
Window事件所对应的事件类为WindowEvent,所对应的事件监听接口为WindowListener。
WindowListener接口定义的方法有:
与WindowListener对应的适配器为WindowAdapter,下面的例子使用了适配器Adapter设计模式。
TestWindowClose.java源代码:
<span style="font-size:18px;">import java.awt.*; import java.awt.event.*; public class TestWindowClose{ public static void main(String args[]){ new MyFrame55("Java窗口"); } } class MyFrame55 extends Frame{ MyFrame55(String s){ super(s); setLayout(null); setBounds(300, 300, 400, 300); this.setBackground(new Color(204, 204, 255)); setVisible(true); this.addWindowListener(new MyWindowMonitor()); } //内部类MyWindowMonitor //WindowAdapter类实现了WindowListener接口 class MyWindowMonitor extends WindowAdapter{ public void windowClosing(WindowEvent e){ setVisible(false); System.exit(0); } } }</span>
运行结果:
使用匿名类优化后的代码:
<span style="font-size:18px;">import java.awt.*; import java.awt.event.*; public class TestWindowClose{ public static void main(String args[]){ new MyFrame55("Java窗口"); } } class MyFrame55 extends Frame{ MyFrame55(String s){ super(s); setLayout(null); setBounds(300, 300, 400, 300); this.setBackground(new Color(204, 204, 255)); setVisible(true); //使用匿名方法内部类 //WindowAdapter类实现了WindowListener接口 this.addWindowListener(new WindowAdapter(){ public void windowClosing(WindowEvent e){ setVisible(false); System.exit(-1); } }); } }</span>
匿名内部类
实例
<span style="font-size:18px;">import java.awt.*; import java.awt.event.*; /* 范例名称:匿名类在事件处理中的使用 * 源文件名称:TestAnonymous.java * 要 点: * 1. 匿名类的性质和用法 * 2. 将监听器类定义为匿名类的好处---- * 在内部类的基础上进一步简化了代码 */ public class TestAnonymous { Frame f = new Frame("匿名内部类测试"); TextField tf = new TextField(30); public TestAnonymous(){ f.add(new Label("请按下鼠标左键并拖动"), "North"); f.add(tf, "South"); //使用匿名类 f.addMouseMotionListener( new MouseMotionAdapter(){ public void mouseDragged(MouseEvent e) { String s = "鼠标拖动到位置(" + e.getX() + "," + e.getY() + ")"; tf.setText(s); } public void mouseMoved(MouseEvent e) { } } ); f.setSize(300, 200); f.setVisible(true); } public static void main(String args[]) { TestAnonymous t = new TestAnonymous(); } }</span>
运行结果:
TestAnonymous2.java源文件代码:
<span style="font-size:18px;">import java.awt.*; import java.awt.event.*; /* 范例名称:匿名类在事件处理中的使用 * 源文件名称:TestAnonymous2.java * 要 点: * 1. 匿名类只能是内部类 * 2. 匿名类的两种创建方式----既可以继承父类、也可以单重实现接口 */ public class TestAnonymous2 { Frame f = new Frame("Test"); TextField tf = new TextField(10); Button b1 = new Button("Start"); public TestAnonymous2(){ f.add(b1,"North"); f.add(tf,"South"); //使用匿名内部类 b1.addActionListener(new ActionListener(){ private int i; public void actionPerformed(ActionEvent e) { tf.setText(e.getActionCommand() + ++i); } }); //使用匿名内部类 f.addWindowListener(new WindowAdapter(){ public void windowClosing(WindowEvent e){ System.exit(0); } }); f.pack(); f.setVisible(true); } public static void main(String args[]) { new TestAnonymous2(); } }</span>
运行结果:
适用场合:
1)逻辑比较简单;
2)代码比较少;
五键盘事件处理
实例:
<span style="font-size:18px;">import java.awt.*; import java.awt.event.*; public class TestKey { public static void main(String[] args) { new KeyFrame().launchFrame(); } } class KeyFrame extends Frame { public void launchFrame() { setSize(400, 300); setLocation(300,300); addKeyListener(new MyKeyMonitor()); setVisible(true); } //使用内部类 //KeyAdapter类实现了KeyListener接口 class MyKeyMonitor extends KeyAdapter { public void keyPressed(KeyEvent e) { int keyCode = e.getKeyCode(); //按下UP键 if(keyCode == KeyEvent.VK_UP) { System.out.println("UP"); } } } }</span>
运行结果: