第12章-图形用户接口(2)---内部类

来源:互联网 发布:2017年火灾数据 编辑:程序博客网 时间:2024/06/06 20:11

2015/6/16

1、

按下按钮改变图形颜色的实例:

package learn_swing;import javax.swing.*;import java.awt.event.*;import java.awt.*;public class SimpleGui3C implements ActionListener{JFrame frame;//将frame对象声明在这里可以方便其他位置来调用public static void main(String[] args){SimpleGui3C gui=new SimpleGui3C();gui.go();}public void go(){frame=new JFrame();//初始化frameframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);JButton button=new JButton("Change Colors");button.addActionListener(this);//创建MyDrawPanel对象,这个对象会自动调用它已经被重写的paintComponent方法//这就是所谓的绘图MyDrawPanel drawPanel=new MyDrawPanel();//border布局的添加方法frame.getContentPane().add(BorderLayout.SOUTH,button);frame.getContentPane().add(BorderLayout.CENTER,drawPanel);frame.setSize(300,300);frame.setVisible(true);}public void actionPerformed(ActionEvent event){//这里只能用frame,因为frame是全局变量,可以在这里调用。//不能用drawPanel,因为它在这里是局部变量。frame.repaint();}}
MyDrawPanel类,用来实现图形的变化:

package learn_swing;import java.awt.*;import javax.swing.*;public class MyDrawPanel extends JPanel{//public void painComponent(Graphics g){//g.setColor(Color.orange);//g.fillRect(20, 50, 100,100);//}public void paintComponent(Graphics g){//Component组件Graphics2D g2d=(Graphics2D)g;//开始的颜色int red=(int)(Math.random()*255);int green=(int)(Math.random()*255);int blue=(int)(Math.random()*255);Color startColor=new Color(red,green,blue);//结束的颜色red=(int)(Math.random()*255);green=(int)(Math.random()*255);blue=(int)(Math.random()*255);Color endColor=new Color(red,green,blue);GradientPaint gradient=new GradientPaint(70,70,startColor,150,150,endColor);g2d.setPaint(gradient);g2d.fillOval(70, 70, 100, 100);}}

2、想要让不同的按钮执行不同的工作,有两种方法:

(1)getSource()方法

package learn_swing;import javax.swing.*;import java.awt.event.*;class MyGui implements ActionListener{//声明实例变量public void go(){colorButton=new JButton();LabelButton=new JButton();//这两个button对象声明的是同一个监听口colorButton.addActionListener(this);LabelButton.addActionListener(this);//其他gui}public void actionPerformed(ActionEvent e) {//用getSource()方法查询事件对象实际上是哪个事件源发出的if(e.getSource()==colorButton){//相对应的操作}else{//相对应的操作}}}
这种方法虽然可以使用,但是并没有严格按照面向对象的要求。在维护上会出现很多的问题。

(2)用内部类的方式

*内部类:一个类嵌套在另一个类的内部。

class A{     class B{         void go(){            }     }}
内部类可以使用外部类所有的方法和变量,就算是私有的也一样。同时外部类里可以创建内部类的对象,并且通过该对象调用内部类的方法。

class MyOuter{private int x;MyInner inner=new MyInner();//创建内部类对象public void doStuff(){inner.go();//用内部类对象调用方法}class MyInner{void go(){x=42;//调用外部类的私有变量}}}
如果需要用外部类以外的程序代码来实例化内部类,需要用特殊的语法:

class Foo{public static void main(String[] args){MyOuter outer=new MyOuter();  //先创建一个外部类对象MyOuter.MyInner inner=outer.new MyInner();  //通过外部类来创建内部类对象}}
使用内部类的范例:

package learn_swing;import javax.swing.*;import java.awt.event.*;import java.awt.*;public class SimpleGui3C implements ActionListener{JFrame frame;//将frame对象声明在这里可以方便其他位置来调用JLabel label;public static void main(String[] args){SimpleGui3C gui=new SimpleGui3C();gui.go();}public void go(){frame=new JFrame();//初始化frameframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);JButton colorButton=new JButton("Change Colors");//不在使用this关键字,而是在被触发时,创建一个内部类对象,即同时创建了一个ActionEventcolorButton.addActionListener(new ColorListener());JButton labelButton=new JButton("Change label");//不在使用this关键字,而是在被触发时,创建一个内部类对象,即同时创建了一个ActionEventlabelButton.addActionListener(new LabelListener());//创建MyDrawPanel对象,这个对象会自动调用它已经被重写的paintComponent方法//这就是所谓的绘图MyDrawPanel drawPanel=new MyDrawPanel();label=new JLabel("I'm a label");//border布局的添加方法frame.getContentPane().add(BorderLayout.SOUTH,colorButton);frame.getContentPane().add(BorderLayout.EAST,labelButton);frame.getContentPane().add(BorderLayout.WEST,label);frame.getContentPane().add(BorderLayout.CENTER,drawPanel);frame.setSize(300,300);frame.setVisible(true);}//下面两个类分别实现了ActionListener接口,并且重写了actionPerformed()方法class LabelListener implements ActionListener{public void actionPerformed(ActionEvent e){label.setText("Ouch!");}}class ColorListener implements ActionListener{public void actionPerformed(ActionEvent e){frame.repaint();}}public void actionPerformed(ActionEvent e) {//虽然在外部类里添加了actionPerformed()方法,但并不使用//甚至即使不实现(不写改方法),虽然在eclipse上会报错,但程序的运行并没有问题。}}
虽然在外部类里添加了actionPerformed()方法,但并不使用。甚至即使不实现(不写改方法),虽然在eclipse上会报错,但程序的运行并没有问题。

3、内部类为什么重要

内部类为我们提供了在一个类中实现同一个接口的多次机会。我们可以让不同的内部类实现同一个接口

4、何时使用内部类

任何一个你需要一个独立却又好像是另一个类成员之一的类时,内部类是唯一的解。

有时,我们需要两个不同的类来表示不同的事物。

当两个类需要相互的调用数据,且又有自己不同的继承时,采用内部类是个好方法,并且,这可以体现多态的特性。

5、内部类的特点

(1)内部类和外部类紧密的结合在一起,它只存在外部类对象的内部。它无法像独立的类一样重用,因为它和外部类紧密的结合在了一起。

(2)内部类的实例一定会绑定在外部类的实例上(这就是为什么其他的类创建内部类对象,必须要借用外部类的特殊方法的原因)。

0 0
原创粉丝点击