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();//初始化frame
frame.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();//初始化frame
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton colorButton=new JButton("Change Colors");
//不在使用this关键字,而是在被触发时,创建一个内部类对象,即同时创建了一个ActionEvent
colorButton.addActionListener(new ColorListener());
JButton labelButton=new JButton("Change label");
//不在使用this关键字,而是在被触发时,创建一个内部类对象,即同时创建了一个ActionEvent
labelButton.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)内部类的实例一定会绑定在外部类的实例上(这就是为什么其他的类创建内部类对象,必须要借用外部类的特殊方法的原因)。