JavaGUI/图形用户界面
************************************************************************
AWT的基本知识
GUI(Graphical User Interface)即图形用户界面。
JDK中提供了AWT和Swing两个包,用于GUI程序的设计和开发。
GUI组件可以分为两大类:基本组件和容器,分别是java.awt.Component和java.awt.Container的
直接或间接子类。
程序的GUI部分由AWT线程管理。
/**
* 让框架窗口显示5秒钟后关闭,查AWT线程的状态。
*/
import java.awt.*;
public class TestFrame {
public static void main(String[] args) {
// TODO Auto-generated method stub
Frame f = new Frame("Mytitle");
f.add(new Button("ok"));
f.setSize(300, 300);
f.setVisible(true);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
f.setVisible(false);
f.dispose();
}
}
************************************************************************
AWT事件处理
《事件监听器》
三个重要的概念:
事件:用户对组件的一个操作,称之为一个事件。
事件源:发生事件的组件就是事件源。
事件处理器:某个Java类中的负责处理事件的成员方法。
按产生事件的物理操作和GUI组件的表现效果进行分类:
MouseEvent
WindowEvent
ActionEvent
......
按事件的性质分类:
低级事件
语义事件(又叫作高级事件)
一个事件监听器对象负责处理一类事件。
一类事件的每一种发生情况,分别由事件监听器对象中的一个方法 来具体处理。
在事件源和事件监听器对象中进行约定的接口类,被称为事件监听器接口。
事件监听器接口类的名称与事件类的名称是相对应的,例如,MouseEvent事件类的监听器
接口名为MouseListener。
/**
* 实现关闭窗口的事件处理,讲解用不同层次的事件类型来表示同一个事件源对象。
*/
//TestFrame.java
import java.awt.*;
public class TestFrame {
public static void main(String[] args) {
// TODO Auto-generated method stub
Frame f = new Frame("Mytitle");
f.add(new Button("ok"));
f.setSize(300, 300);
f.setVisible(true);
f.addWindowListener (new MyWindowListener() );
}
}
//MyWindowListener.java
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.*;
public class MyWindowListener implements WindowListener {
@Override
public void windowOpened(WindowEvent e) {
// TODO Auto-generated method stub
}
@Override
public void windowClosing (WindowEvent e) {
// TODO Auto-generated method stub
e.getWindow().setVisible(false);
//((Window)e.getSource()).dispose();
((Window)e.getComponent()).dispose();
System.exit(0);
}
@Override
public void windowClosed(WindowEvent e) {
// TODO Auto-generated method stub
}
@Override
public void windowIconified(WindowEvent e) {
// TODO Auto-generated method stub
}
@Override
public void windowDeiconified(WindowEvent e) {
// TODO Auto-generated method stub
}
@Override
public void windowActivated(WindowEvent e) {
// TODO Auto-generated method stub
}
@Override
public void windowDeactivated(WindowEvent e) {
// TODO Auto-generated method stub
}
}
处理发生在某个GUI组件上的XXXEvent事件的某种情况,其事件处理的通用编写流程:
--编写一个实现了XXXListener接口的事件监听器类;
--XXXListener类中的用于处理该事件情况的方法中,编写处理代码;
--调用组件的addXXXListener方法,将类XXXListener创建的实例对象注册到GUI组件上。
《事件适配器 》
JDK中也提供了大多数事件监听器接口的最简单的实现类,称之为事件适配器(Adapter)
类
用事件适配器来处理事件,可以简化事件监听器编写。
/**
* 使用事件适配器类来关闭窗口。
*/
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class YourWindowListener extends WindowAdapter {
public void windowClosing(WindowEvent e){
e.getWindow().dispose();
System.exit(0);
}
}
如果要在事件监听器类中访问非事件源的其他GUI组件,程序该如何编写?
/**
* 在事件监听器类中访问非事件源的其他GUI组件。
*/
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class TestFrame implements ActionListener{
Frame f = new Frame("Mytitle");
public void init(){
Button btn = new Button("ok");
f.add(btn);
f.setSize(300, 300);
f.setVisible(true);
btn.addActionListener(this);//监听tf
/*btn.addActionListener(new A ctionListener(){
public actionPerformed(ActionEvent e) {
f.dispose();
}
});//匿名内置类对象*/
}
public static void main(String[] args) {
// TODO Auto-generated method stub
TestFrame tf = new TestFrame();
tf.init();
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
f.dispose();
//System.exit(0);
}
}
《修改组件的默认事件处理方式 》
-只有在一个组件上注册了某种事件的事件监听器对象后,组件才会产生相应的事件对象。
-默认的processEvent方法(处理所有事件的总入口)调用相应的processXxxEvent方法(处理Xxx事件的分叉入口)。
-调用enableEvents((long eventsToEnable))方法,可以在即使没有注册事件监听器的情况下,组件也能够对某些类型的事件进行响应和产生相应的事件对象。
-eventsToEnable代表组合事件类型的数值常量
/**
* 窗口上的按钮,一旦鼠标移动到上面时,按钮就移动到其他位置,这样,鼠标就永远无法点击到这个按钮。
*/
//TestMyButton.java
package myprojects.testmybutton;
import java.awt.*;
import java.awt.event.*;
public class TestMyButton extends Frame {
private static final long serialVersionUID = 1L;
public TestMyButton() {
addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
dispose();
System.exit(0);
}
});
}
public static void main(String arg[]){
System.out.println("Starting TestMyButton...");
TestMyButton mainFrame = new TestMyButton();
MyButton btn1 = new MyButton("你来抓我啊!");
MyButton btn2 = new MyButton("你来抓我啊!");
btn1.setFriend(btn2);
btn2.setFriend(btn1);
mainFrame.add(btn1,"North");
mainFrame.add(btn2,"South");
mainFrame.setSize(400,400);
mainFrame.setTitle("TestMyButton");
mainFrame.setVisible(true);
btn2.setVisible(false);
}
}
//MyButton.java
package myprojects.testmybutton;
import java.awt.*;
import java.awt.event.MouseEvent;
public class MyButton extends Button {
/**
*
*/
private static final long serialVersionUID = 1L;
private MyButton friend = null;
public MyButton(String title)
{
super(title);
this.enableEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK);
}
public void setFriend(MyButton friend)
{
this.friend = friend;
}
protected void processMouseMotionEvent(MouseEvent e)
{
this.setVisible(false);
friend.setVisible(true);
}
}
************************************************************************
GUI组件上的图形操作
GUI组件上的图形操作
《Graphics类与图形绘制》
-Component.getGraphics方法与Graphics类
-Graphics.drawLine(int x1,int y1,int x2,int y2)方法
-Graphics.drawString(String str,int x.int y)方法
-Graphics.drawString方法的坐标参数。
/**
* 用鼠标将直线画出,并在每条直线的起始和终止位置上打印出它们的坐标值。
*/
import java.awt.*;
import java.awt.event.*;
public class DrawLine extends Frame {
private static final long serialVersionUID = 1L;
public DrawLine() {
addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
dispose();
System.exit(0);
}
});
this.addMouseListener(new MouseAdapter() {
int orgX;
int orgY;
public void mousePressed(MouseEvent e)
{
orgX = e.getX();
orgY = e.getY();
}
public void mouseReleased(MouseEvent e)
{
Graphics g = getGraphics();
g.setColor(Color.RED);
g.drawLine(orgX, orgY, e.getX(), e.getY());
//先找MouseAdapter对象,没有再找DrawLine对象。
//如果用this.getGraphics(),只找MouseAdapter对象。
g.setFont(new Font(null,Font.ITALIC+Font.BOLD,15));
g.drawString(orgX+","+orgY,orgX,orgY);
g.drawString(e.getX()+","+e.getY(), e.getX(), e.getY());
}
});
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("Starting TestMyButton...");
DrawLine mainFrame = new DrawLine();
mainFrame.setSize(400,400);
mainFrame.setTitle("TestMyButton");
mainFrame.setVisible(true);
}
}
《组件重绘的处理》
-原理
-paint(Graphics g)的作用(重绘时系统调用)
-AWT线程对组件重绘的调用过程。
/**
* 画直线和打印文本,并在窗口重绘后重绘窗口上的所有直线。
*/
//MyLine.java
import java.awt.Graphics;
public class MyLine {
private int orgX;
private int orgY;
private int endX;
private int endY;
public MyLine(int orgX,int orgY,int endX,int endY)
{
this.orgX = orgX;
this.orgY = orgY;
this.endX = endX;
this.endY = endY;
}
public void drawMe(Graphics g)
{
g.drawLine(orgX, orgY, endX, endY);
}
}
//DrawLine.java
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class DrawLine extends Frame {
private static final long serialVersionUID = 1L;
int orgX;
int orgY;
int endX;
int endY;
Vector vLines = new Vector();
public void paint(Graphics g)
{
Enumeration e = vLines.elements();
while(e.hasMoreElements())
{
MyLine line = (MyLine)e.nextElement();
line.drawMe(g);
}
//g.drawLine(orgX, orgY, endX, endY);
}
public DrawLine() {
addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
dispose();
System.exit(0);
}
});
this.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e)
{
orgX = e.getX();
orgY = e.getY();
}
public void mouseReleased(MouseEvent e)
{
endX = e.getX();
endY = e.getY();
/*
Graphics g = getGraphics();
g.setColor(Color.RED);
g.drawLine(orgX, orgY, e.getX(), e.getY());
//先找MouseAdapter对象,没有再找DrawLine对象。
//如果用this.getGraphics(),只找MouseAdapter对象。
g.setFont(new Font(null,Font.ITALIC+Font.BOLD,15));
g.drawString(orgX+","+orgY,orgX,orgY);
g.drawString(e.getX()+","+e.getY(), e.getX(), e.getY());
*/
vLines.add(new MyLine(orgX, orgY, endX, endY));
repaint();//刷新,调用paint方法。
}
});
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("Starting TestMyButton...");
DrawLine mainFrame = new DrawLine();
mainFrame.setSize(400,400);
mainFrame.setTitle("TestMyButton");
mainFrame.setVisible(true);
}
}
《图像显示》
-使用Graphics.drawImage(Image img,int x,int y,ImageObserver observer)方法显示图像。(异步的方法,虽然img没有装载到内存就可以使用,ImageObserver用于监视图像创建加载信息)
-使用Component.getToolkit().getImage(String path)语句获得Image实例对象。
/**
* 显示图片
*/
import java.awt.*;
import java.awt.event.*;
public class DrawImage extends Frame{
private static final long serialVersionUID = 1L;
private Image img = this.getToolkit().getImage(".//logo.gif");
public void paint(Graphics g)
{
g.drawImage(img, 0, 0, this);
}
public DrawImage() {
addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
dispose();
System.exit(0);
}
});
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("Starting DrawImage...");
DrawImage mainFrame = new DrawImage();
//Image img = mainFrame.getToolkit().getImage(".//logo.gif");
mainFrame.setSize(400,400);
mainFrame.setTitle("DrawImage");
mainFrame.setVisible(true);
/*Graphics g = mainFrame.getGraphics();
while(!g.drawImage(img,0,0,mainFrame))
{
}*/
}
}
《双缓冲技术》
-Graphics.createImage方法创建内存Image对象。
-在Image对象上进行绘制的结果就成了一副图像。
-在Image对象上执行与组件表面同样的绘制,Image对象中的图像是组件表面内容的复制,当组件重画时,只需将内存中的Image对象在组件上画出。
/**
* 使用双缓冲区技术重绘组件表面的所有图形。
*/
import java.awt.*;
import java.awt.event.*;
public class DrawLine1 extends Frame {
private static final long serialVersionUID = 1L;
int orgX;
int orgY;
int endX;
int endY;
Image oimg = null;
Graphics og = null;
public void paint(Graphics g)
{
if(oimg !=null)
{
g.drawImage(oimg, 0, 0, this);
}
}
public DrawLine1() {
this.setSize(400,400);
this.setTitle("TestMyButton");
this.setVisible(true);
Dimension d = this.getSize();
oimg = this.createImage(d.width,d.height);
og = oimg.getGraphics();
addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
dispose();
System.exit(0);
}
});
this.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e)
{
orgX = e.getX();
orgY = e.getY();
}
public void mouseReleased(MouseEvent e)
{
endX = e.getX();
endY = e.getY();
Graphics g = getGraphics();
g.setColor(Color.RED);
g.drawLine(orgX, orgY, endX, endY);
g.setFont(new Font(null,Font.ITALIC+Font.BOLD,15));
g.drawString(orgX+","+orgY,orgX,orgY);
g.drawString(endX+","+endY, endX, endY);
og.setColor(Color.RED);
og.drawLine(orgX, orgY, endX, endY);
og.setFont(new Font(null,Font.ITALIC+Font.BOLD,15));
og.drawString(orgX+","+orgY,orgX,orgY);
og.drawString(endX+","+endY, endX, endY);
}
});
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("Starting TestMyButton...");
DrawLine1 mainFrame1 = new DrawLine1();
}
}
************************************************************************
常用的AWT组件
Canvas是具有最基本和最简单的GUI功能的组件。
Canvas代表屏幕上的一块空白的矩形区域,程序能够在这个部件表面绘图,也能够捕获用户的操作,产生相应的事件。
当要设计自定制的具有GUI功能的组件类时,继承Canvas将会大大简化编程难度。
/**
* 设计一个自定制的计时器组件,当鼠标在计时器组件上按下时,计时器开始计时,并像是计时时间,当鼠标释放时,计时器停止计时。
*/
JAVA高级03_07
菜单
-一个完整的菜单系统由菜单条、菜单和菜单项组成,它们之间的关系如图:
-Java中与菜单相关的类主要有:MenuBar(菜单条)、Menu(菜单)、MenuItem(菜单项)。
/**
* 实现图中的菜单和相关事件处理
*/
JAVA高级03_08
-setActionCommand方法的作用。
Container类
-Container类是所有容器类的父类,Container.add方法用于将组件添加到容器中。
-Container也是Component的子类,因此也可以作为组件增加到其它容器上。
Dialog类与FileDialog类
-Dialog类用于产生对话框。
-模态对话框和非模态对话框。
-Dialog类的两个常用构造方法:
public Dialog(Frame owner,String title);
public Dialog(Frame owner,String title,boolean modal);
/**
* 模态对话框和非模态对话框
*/
JAVA高级03_09
-FileDialog类是Dialog类的一个子类,能够产生标准的文件存取对话框。
Checkbox
-Checkbox类用来建立单选按钮和多选按钮(也叫复选框)。
-Checkbox(String label,boolean state)创建多选按钮
-Checkbox(String label,boolean state,CheckboxGroup group)创建单选按钮
单选按钮和多选按钮的语义事件为ItemEvent,对应的监听器接口为ItemListener,该接口中只有一个itemStateChanged方法。
Choice
-Choice类用来制作单选下拉列表框。
-Choice类的语义事件为ItemEvent,对应的监听器接口为ItemListener,该接口中只有一个itemStateChanged方法。
Panel与ScrollPane类
-Panel类是一个容器类,用于产生一种特殊的空白面板,可以容纳其他的组件,但不能独立存在。
-ScrollPane类是一种容器类,用于产生滚动窗口,通过滚动条在一个较小的容器窗口中显示较大的子部件。
************************************************************************
布局管理器
-一个容器中的各个组件之间的位置和大小关系就称之为布局。
-Java语言提供了布局管理器来管理组件在容器中的布局,而不是直接使用位置坐标来设置各个组件的位置和大小。
-AWT中的布局管理器类:
-BorderLayout
-FlowLayout
-GridLayout
-CardLayout
-GridBagLayout
************************************************************************
Swing
************************************************************************