所谓用户界面,在java里依旧是一个一个的类,(主要是javax.swing包里的类),组成一个界面的表现,则是这些类的对象之间相互调用的结果。
所有的swing组件都继承于javax.swing.JComponent这个抽象类。
swing组件分类
1.Container(容器)组件,例如JPanel、JFrame
2.元素组件,JLabel、JTextField
1)每个Swing组件都有一个或多个add<事件名称>Listener的方法,例如常用的JButton类、Jlist类(下拉框)、JMenu类(菜单)都有一个addActionListenerd方法,其中ActionListener接口定义如下
package java.awt.event;
import java.util.EventListener;
public interface ActionListener extends EventListener {
/**
* Invoked when an action occurs.
*/
public void actionPerformed(ActionEvent e);
}
这个方法只有一个ActionEvent(事件对象)类型的参数;这个ActionEvent对象有许多方法可以得到事件源的相关信息,ActionEvent对象的getSource()返回一个Object类型的对象,指向了发出这个事件的事件源,如是点击了一个JButton,就可以将这个Object强制转型为JButton类型,即可得到事件源对象;getActionCommand()方法可以得到事件源上的标签作为一String 类型返回等等
import javax.swing.JButton;
public class MyButtonListener implements java.awt.event.ActionListener{
public void actionPerformed(ActionEvent e) {
//自动转型,sour指向了事件源
Object sour = e.getSource();
if(sour instanceof javax.swing.JButton) {
//将sour强制转型为JButton,得到指向事件源的对象
javax.swing.JButton bu = (javax.swing.JButton)sour;
String lab = bu.getActionCommand();
System.out.println("按下了个按钮: "+lab);
bu.setText("我被按了一下!");
}
else{
System.out.println("其他组件发生事件");
}
}
}
instanceof是Java、php的一个二元操作符(运算符),和==,>,<是同一类东西。由于它是由字母组成的,所以也是Java的保留关键字。它的作用是判断其左边对象是否为其右边类的实例,返回boolean类型的数据。可以用来判断 继承中的子类的实例是否为父类的实现。
2)通过内部类简化事件处理方式
//通过内部类创建 按钮监听器:
bu_login.addActionListener(new java.awt.event.ActionListener() {
//必须是重写ActionListener重的方法,当事件发生时,这个方法就会被调用:
public void actionPerformed(ActionEvent e) {
//调用本类内部的事件处理方法
processEvent();
}
}
);
3)系统提供一个MouseAdapter类:
public abstract class MouseAdapter implements MouseListener,
MouseWheelListener, MouseMotionListener {
public void mouseClicked(MouseEvent e) {}
public void mousePressed(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mouseWheelMoved(MouseWheelEvent e){}
public void mouseDragged(MouseEvent e){}
public void mouseMoved(MouseEvent e){}
}
我们的鼠标事件监听器类只需要继承MouseAdapter类,重写我们需要重写的方法即可,对于这种方法,有一个专有名词,叫做“适配器设计模式”。
this.addMouseListener(new MouseAdapter(){
public void mouseClicked(MouseEvent e) {
for(int k = 0; k<30000; k++) {
int i = (int)(Math.random()*3)+1;
if(i == 1) {
grc.drawLine((datax[0]+datax[3])/2,(datay[0]+datay[3])/2, (datax[0]+datax[3])/2, (datay[0]+datay[3])/2);
datax[3] = (datax[0]+datax[3])/2;
datay[3] = (datay[0]+datay[3])/2;
}else if(i == 2) {
grc.drawLine((datax[1]+datax[3])/2, (datay[1]+datay[3])/2, (datax[1]+datax[3])/2, (datay[1]+datay[3])/2);
datax[3] = (datax[1]+datax[3])/2;
datay[3] = (datay[1]+datay[3])/2;
}else if(i == 3) {
grc.drawLine((datax[2]+datax[3])/2, (datay[2]+datay[3])/2, (datax[2]+datax[3])/2, (datay[2]+datay[3])/2);
datax[3] = (datax[2]+datax[3])/2;
datay[3] = (datay[2]+datay[3])/2;
}
}
}
});
4)抽取“形状”父类并实现
我们可以将各种形状相同的属性都在父类中定义,不同的属性在各自的子类中定义
package Demo;
import java.awt.Color;
import java.awt.Graphics;
/**
* 绘图形状的抽象类定义
* @author 袁可可
*
*/
public abstract class NetJavaShape {
public Color color;
/**
* 子类必须实现的抽象方法
* @param g画布对象
*/
public abstract void draw(Graphics g);
}
如果有了如上抽象类的实现类,在界面主城中,要绘制某种形状时,调用的代码格式就会是
//创建直线对象
NetJavaShape shape = new ImpLine(x1,y1,x2,y2,color);
//调用shape对象绘制方法,传入画布对象。坐标点和颜色对象;
//具体的shape对象就知道如何绘制出自己
shape.draw(g);
5)通过系统提供的颜色选择器选择颜色
this.color = JColorChooser.showDialog(null,"请选择颜色",Color.BLACK);
Declaration
public static Color showDialog(Component component,
String title, Color initialColor) throws HeadlessException {
final JColorChooser pane = new JColorChooser(initialColor != null?
initialColor : Color.white);
ColorTracker ok = new ColorTracker(pane);
JDialog dialog = createDialog(component, title, true, pane, ok, null);
dialog.show(); // blocks until user brings dialog down...
return ok.getColor();
}