我是一个Java爱好者
分类: Java
2009-07-20 15:42:15
● AWT的基础知识
● AWT事件处理
● GUI组件上的图形操作
● 常用的AWT组件
● 布局管理器
● Swing
AWT的基础知识
● GUI全称是Graphical User Interface,即图形用户界面
● JDK中提供了AWT和Swing两个包,用于GUI程序的设计和开发
● GUI组件可以分为两大类:基本组件和容器,分别是java.awt.Component和java.awt.Container的直接或间接子类
● 程序的GUI部分由AWT线程管理
编程举例:让框架窗口显示5秒钟后关闭,查AWT线程的状态。
import java.awt.*;
import javax.swing.*;
public class TestFrame
{
public static void main(String[] args)
{
// TODO: Add your code here
/*Frame f=new Frame("Jianke");
f.setSize(300,300);
f.add(new Button("OK"));
f.setVisible(true);
try
{
Thread.sleep(5000);
}
catch(Exception e)
{
e.printStackTrace();
}
//f.setVisible(false);
f.dispose();
*/
JFrame jf=new JFrame("Jianke");
jf.setSize(300,300);
jf.add(new JButton("hello"));
jf.setVisible(true);
try
{
Thread.sleep(5000);
}
catch(Exception e)
{
e.printStackTrace();
}
jf.setVisible(false);
jf.dispose();
}
}
AWT事件处理
● 事件处理机制
● 事件分类
● 事件监听器
● 事件适配器
● 灵活设计事件监听器类
● 用匿名内置类实现事件监听器
● 事件处理的多重运用
● 修改组件的默认事件处理方式
事件处理机制
三个重要的概念:
◆ 事件:用户对组件的一个操作,称之为一个事件。
◆ 事件源:发生事件的组件就是事件源
◆ 事件处理器:某个Java类中的负责处理事件的成员方法
事件源、事件、事件处理器之间的工作关系:
事件分类
按产生事件的物理操作和GUI组件的表现效果进行分类:
◆ MouseEvent
◆ WindowEvent
◆ ActionEvent
◆ ……
按事件的性质分类:
◆ 低级事件
◆ 语义事件(高级事件)
如何区分低级事件与高级事件:与事件类的名称相对应的事件监听器接口类包含多个成员方法,就是低级事件;与事件类的名称相对应的事件监听器接口类包含一个成员方法,就是高级事件。
事件监听器
● 一个事件监听器对象负责处理一类事件
● 一类事件的每一种发生情况,分别由事件监听器对象中的一个方法来具体处理
● 在事件源和事件监听器对象中进行约定的接口类,被称为事件监听器接口
● 事件监听器接口类的名称与事件类的名称是相对应的,例如,MouseEvent事件类的监听器接口名为MouseListener
编程实例:实现关闭窗口的事件的处理,讲解用不同层次的事件类型来表示同一个事件源对象
import javax.swing.*;
public class TestFrame
{
public static void main(String[] args)
{
// TODO: Add your code here
JFrame jf=new JFrame("Jianke");
jf.setSize(300,300);
jf.setVisible(true);
//jf.dispose();
jf.addWindowListener(new MyWindowsListener());
}
}
import java.awt.event.WindowListener;
import java.awt.event.WindowEvent;
import java.awt.*;
public class MyWindowsListener implements WindowListener
{
public void windowOpened(WindowEvent e)
{
// TODO: Add your code here
}
public void windowClosing(WindowEvent e)
{
// TODO: Add your code here
/*e.getWindow().setVisible(false);
e.getWindow().dispose();
((Window)e.getSource()).setVisible(false);
((Window)e.getSource()).dispose();
*/
((Window)e.getComponent()).setVisible(false);
((Window)e.getComponent()).dispose();
}
public void windowClosed(WindowEvent e)
{
// TODO: Add your code here
}
public void windowIconified(WindowEvent e)
{
// TODO: Add your code here
}
public void windowDeiconified(WindowEvent e)
{
// TODO: Add your code here
}
public void windowActivated(WindowEvent e)
{
// TODO: Add your code here
}
public void windowDeactivated(WindowEvent e)
{
// TODO: Add your code here
}
}
◆ 处理发生在某个GUI组件上的XxxEvent事件的某种情况,其事件处理的通用编写流程:
◆ 编写一个实现了XxxListener接口的事件监听器类;
◆ XxxListener类中的用于处理该事件情况的方法中,编写处理代码;
◆ 调用组件的addXxxListener方法,将类XxxListener创建的实例对象注册到GUI组件上。
事件适配器
● JDK中也提供了大多数事件监听器接口的最简单的实现类,称之为事件适配器(Adapter)类
● 用事件适配器来处理事件,可以简化事件监听器编写
编程实例:使用事件适配器类来关闭窗口
import java.awt.*;
import javax.swing.*;
public class TestFrame
{
public static void main(String[] args)
{
// TODO: Add your code here
JFrame jf=new JFrame("Jianke");
jf.setSize(300,300);
jf.add(new Button("hello"));
jf.setVisible(true);
try
{
Thread.sleep(5000);
}
catch(Exception e)
{
e.printStackTrace();
}
jf.setVisible(false);
jf.dispose();
//jf.addWindowListener(new MyWindowListener());
jf.addWindowListener(new MyWindowAdapter());
}
}
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class MyWindowAdapter extends WindowAdapter
{
public void windowClosing(WindowEvent e)
{
e.getWindow().setVisible(false);
e.getWindow().dispose();
System.exit(0);
}
}
● 初学者使用事件适配器时常见问题,解决问题的思路:
◆ 是方法没有被调用,还是方法中的程序代码的执行问题?
◆ 是方法名写错了,还是没有注册事件监听器?
灵活设计事件监听器类
● 如果要在事件监听器类中访问非事件源的其他GUI组件,程序该如何编写?
例:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.EventListener;
public class TestFrame implements ActionListener
{
JFrame jf=new JFrame("Jianke");
public void init()
{
jf.setVisible(true);
jf.setSize(300,300);
JButton jbn=new JButton("Exit");
jf.add(jbn);
jbn.addActionListener(this);
}
public static void main(String[] args)
{
// TODO: Add your code here
TestFrame tf=new TestFrame();
tf.init();
}
public void actionPerformed(ActionEvent e)
{
// TODO: Add your code here
jf.dispose();
System.exit(0);
}
}
使用内置类形式来访问非事件源的其他GUI组件:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.EventListener;
public class TestFrame
{
JFrame jf=new JFrame("Jianke");
public void init()
{
jf.setVisible(true);
jf.setSize(300,300);
JButton jbn=new JButton("Exit");
jf.add(jbn);
jbn.addActionListener(new MyClassListener());
}
public static void main(String[] args)
{
// TODO: Add your code here
TestFrame tf=new TestFrame();
tf.init();
}
class MyClassListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
// TODO: Add your code here
jf.dispose();
System.exit(0);
}
}
}
使用匿名内置类形式来访问非事件源的其他GUI组件:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.EventListener;
public class TestFrame
{
JFrame jf=new JFrame("Jianke");
public void init()
{
jf.setVisible(true);
jf.setSize(300,300);
JButton jbn=new JButton("Exit");
jf.add(jbn);
jbn.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
jf.dispose();
System.exit(0);
}
});
}
public static void main(String[] args)
{
// TODO: Add your code here
TestFrame tf=new TestFrame();
tf.init();
}
}
事件处理的多重运用
● 如何知道一个GUI组件倒底能够触发哪几种事件?
● 一个组件上的一个动作可以产生多种不同类型的事件
● 一个事件监听器对象可以注册到多个事件源上
● 在一个事件源上也可以注册对同一类事件进行处理的多个事件监听器对象
修改组件的默认事件处理方式
● 只有在一个组件上注册了某种事件的事件监听器对象后,组件才会产生相应的事件对象
● 默认的processEvent方法调用相应的processXxxEvent方法
● 调用enableEvents(long events ToEnable)方法,可以在即使没有注册事件监听器的情况下,组件也能够对某些类型的事件进行响应和产生相应的事件对象。
注:
protected void processKeyEvent( e)
处理组件上发生的按键事件,方法是将其指派到任意已注册的 KeyListener
对象。
如果组件上没有启用按键事件,则不调用此方法。发生下列之一时启用按键事件:
· 通过 addKeyListener
注册了一个 KeyListener
对象。
· 通过 enableEvents
启用了按键事件。
如果为某个 Component
启用了按键事件,则当前的 KeyboardFocusManager
确定是否应该将按键事件指派到已注册的 KeyListener
事件。DefaultKeyboardFocusManager
不会为非焦点所有者或未显示的 Component
指派按键事件。
在 J2SE 1.4 中,已将 KeyEvent
重定向到焦点所有者。有关更多信息,请参阅 Focus Specification。
只要组件正在显示、已定焦、已启用并且其上的按键事件已启用,那么使用 dispatchEvent
作为参数来调用 KeyEvent
的 Component
方法将导致调用 Component
的 processKeyEvent
方法,而不管当前的 KeyboardFocusManager
如何。
注意,如果事件参数为 null
,则未指定行为并且可能导致异常
protected void processMouseEvent( e)
处理组件上发生的鼠标事件,方法是将其指派到任意已注册的 MouseListener
对象。
如果组件上没有启用鼠标事件,则不调用此方法。发生下列之一时启用鼠标事件:
· 通过 addMouseListener
注册了一个 MouseListener
对象。
· 通过 enableEvents
启用了鼠标事件。
注意,如果事件参数为 null
,则未指定行为并且可能导致异常。
protected void processMouseMotionEvent( e)
处理组件上发生的鼠标移动事件,方法是将其指派到任意已注册的 MouseMotionListener
事件。
如果组件上没有启用鼠标移动事件,则不调用此方法。发生下列之一时启用鼠标移动事件:
· 通过 addMouseMotionListener
注册了一个 MouseMotionListener
对象。
· 通过 enableEvents
启用了鼠标移动事件。
注意,如果事件参数为 null
,则未指定行为并且可能导致异常。
编程实例:在一个窗口上显示一个按钮,一但鼠标移动到这个按钮上时,按钮就移动到了其他位置,这样鼠标就永远无法点击到这个按钮。
import java.awt.*;
import java.awt.event.*;
public class MyButton extends Frame
{
public MyButton()
{
addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
e.getWindow().dispose();
System.exit(0);
}
});
}
public static void main(String[] args)
{
// TODO, add your application code
MyButton mainFrame=new MyButton();
mainFrame.setSize(300,300);
AddMyButton mbt1=new AddMyButton("Hello");
AddMyButton mbt2=new AddMyButton("Hello");
mbt1.setFriend(mbt2);
mbt2.setFriend(mbt1);
mainFrame.add(mbt1,"North");
mainFrame.add(mbt2,"South");
mainFrame.setVisible(true);
mbt2.setVisible(false);
}
}
import java.awt.*;
import java.awt.event.*;
public class AddMyButton extends Button
{
private AddMyButton friend=null;
public void setFriend(AddMyButton friend)
{
this.friend=friend;
}
public AddMyButton(String title)
{
super(title);
enableEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK);
}
protected void processMouseMotionEvent(MouseEvent e)
{
this.setVisible(false);
friend.setVisible(true);
}
}
GUI组件上的图形操作
● Graphics类与图形绘制
● 组件重绘的处理
● 图像显示
● 双缓冲技术
Graphics类与图形绘制组件重绘的处理
● Component.getGraphics方法与Graphic类
● Graphics.drawLine(int x1,int y1,int x2,int y2)方法
● Graphics.drawString(String str,int x,int y)方法。
● Graphic.drawString方法的坐标参数:如图
● 编程举例:以鼠标在窗口中按下的位置作为起始点,鼠标释放时的位置作为终止点,在鼠标释放时将直线画出,并在每条直线的起始和终止位置上打印出它们的坐标值。
import java.awt.*;
import java.awt.event.*;
public class TestDrawLine extends Frame
{
public TestDrawLine()
{
addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
e.getWindow().dispose();
System.exit(0);
}
});
addMouseListener(new MouseAdapter()
{
int orgX;
int orgY;
public void mousePressed(MouseEvent e)
{
orgX=e.getX();
orgY=e.getY();
}
public void mouseReleased(MouseEvent e)
{
Graphics gs=getGraphics();
gs.setFont(new Font("隶书",Font.ITALIC|Font.BOLD,20));
gs.setColor(Color.RED);
gs.drawString("("+orgX+","+orgY+")",orgX,orgY);
gs.drawString("("+e.getX()+","+e.getY()+")",e.getX(),e.getY());
gs.setColor(Color.blue);
gs.drawLine(orgX,orgY,e.getX(),e.getY());
//gs.drawArc(e.getX(),e.getY(),100,50,30,60);
gs.draw3DRect(e.getX(),e.getY(),200,100,true);
}
});
}
public static void main(String[] args)
{
// TODO, add your application code
System.out.println("Hello World!");
TestDrawLine mainFrame=new TestDrawLine();
mainFrame.setTitle("Welcome To Jianke Working Room");
mainFrame.setSize(400,300);
mainFrame.setVisible(true);
}
}
组件重绘的处理
● paint(Graphics g)的作用
● AWT线程对组件重绘的调用过程(如图)
编程举例:在窗口上画直线和打印文本的功能,并在窗口重绘窗口上的所有直线
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class DrawAllLine extends Frame
{
int x;
int y;
int endX;
int endY;
Vector v=new Vector();
public void paint(Graphics g)
{
Enumeration e=v.elements();
while(e.hasMoreElements())
{
MyLine ml=(MyLine)e.nextElement();
ml.drawMe(g);
}
}
public DrawAllLine()
{
addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
e.getWindow().dispose();
System.exit(0);
}
});
addMouseListener(new MouseAdapter()
{
public void mousePressed(MouseEvent e)
{
x=e.getX();
y=e.getY();
}
public void mouseReleased(MouseEvent e)
{
endX=e.getX();
endY=e.getY();
v.add(new MyLine(x,y,endX,endY));
repaint();
}
});
}
public static void main(String[] args)
{
// TODO, add your application code
System.out.println("Hello World!");
DrawAllLine mainFrame=new DrawAllLine();
mainFrame.setTitle("Welcome To Jianke Workroom");
mainFrame.setSize(400,300);
mainFrame.setVisible(true);
}
}
class MyLine
{
private int x;
private int y;
private int endX;
private int endY;
public MyLine(int x,int y,int endX,int endY)
{
this.x=x;
this.y=y;
this.endX=endX;
this.endY=endY;
}
public void drawMe(Graphics g)
{
g.setColor(Color.RED);
g.drawString("("+x+","+y+")",x,y);
g.drawString("("+endX+","+endY+")",endX,endY);
g.setColor(Color.BLUE);
g.drawLine(x,y,endX,endY);
}
}
图像显示
● 使用Graphics.drawImage(Image img,int x,int y,ImageObserver observer)方法显示图像
● 使用Component.getToolkit.getImage(String path)语句获得Image实例对象
编程实例:在窗口上显示图像文件中的图像,并解决由于drawImage内部实现机制所造成的图像不能显示问题,和实现图像的永久化显示。
import java.awt.*;
import java.awt.event.*;
public class TestDrawImage extends Frame
{
Image img=getToolkit().getImage("..""gg.gif");
public void paint(Graphics g)
{
g.drawImage(img,10,10,Color.RED,this);
}
public TestDrawImage()
{
addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
e.getWindow().dispose();
}
});
}
public static void main(String[] args)
{
// TODO: Add your code here
TestDrawImage mainFrame=new TestDrawImage();
mainFrame.setTitle("剑客工作室");
mainFrame.setSize(600,500);
//设置图标
Image imgIco=mainFrame.getToolkit().getImage("ico.jpg");
mainFrame.setIconImage(imgIco);
mainFrame.setVisible(true);
}
}
双缓冲技术
● Component.createImage方法创建内存Image对象
● 在Image对象上进行绘制的结果就成了一幅图像
● 在Image对象上执行与组件表面同样的绘制,Image对象中的图像是组件表面内容的复制,当组件重画时,只需将内存中的Image对象在组件上画出
编程实例:使用双缓冲区技术重绘组件表面的所有图形。
注:Dimension
类封装单个对象中组件的宽度和高度(精确到整数)。
import java.awt.*;
import java.awt.event.*;
public class TestDrawImage extends Frame
{
Image img=null;
Graphics Memoryg=null;
Image imgBack=this.getToolkit().getImage("..""images""back.jpg");
public void paint(Graphics g)
{
g.drawImage(img,0,0,this);
//g.drawImage(imgBack,0,0,this);
}
public TestDrawImage()
{
//先要实现主窗体,再createImage。
setTitle("Jianke");
setSize(400,400);
this.setVisible(true);
Dimension d=this.getSize();
img=this.createImage(d.width,d.height);
Memoryg=img.getGraphics();
addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
e.getWindow().dispose();
}
});
addMouseListener(new MouseAdapter()
{
int x;
int y;
public void mousePressed(MouseEvent e)
{
x=e.getX();
y=e.getY();
}
public void mouseReleased(MouseEvent e)
{
Graphics g=getGraphics();
g.setColor(Color.RED);
g.setFont(new Font("隶书",Font.ITALIC|Font.BOLD,20));
g.drawString("("+x+","+y+")",x,y);
g.drawString("("+e.getX()+","+e.getY()+")",e.getX(),e.getY());
g.setColor(Color.BLUE);
g.drawLine(x,y,e.getX(),e.getY());
Memoryg.setColor(Color.RED);
Memoryg.setFont(new Font("隶书",Font.ITALIC|Font.BOLD,20));
Memoryg.drawString("("+x+","+y+")",x,y);
Memoryg.drawString("("+e.getX()+","+e.getY()+")",e.getX(),e.getY());
Memoryg.setColor(Color.BLUE);
Memoryg.drawLine(x,y,e.getX(),e.getY());
}
});
}
public static void main(String[] args)
{
// TODO, add your application code
System.out.println("Hello World!");
TestDrawImage mainFrame=new TestDrawImage();
mainFrame.setIconImage(mainFrame.getToolkit().getImage("..""images""ico.jpg"));
}
}
Canvas
● Canvas是具有最基本和最简单的GUI功能的组件
● Canvas代表屏幕上的一块空白的矩形区域,程序能够在这个部件表面绘图,也能够捕获用户的操作,产生相应的事件
● 当要设计自定制的具有GUI功能的组件类时,继承Canvas将会大大简化编程难度。应用程序必须为 Canvas
类创建子类,以获得有用的功能(如创建自定义组件)。必须重写 paint
方法,以便在 canvas 上执行自定义图形。
编程实例:设计一个自定制的计时器组件,当鼠标在计时器组件上按下时,计时器开始时,并显示计时时间,当鼠标释放时,计时器停止计时
import java.awt.*;
import java.awt.event.*;
public class TestStopWatch extends Frame
{
public TestStopWatch()
{
//this.add(new StopWatch());
this.add(new StopWatch1());
addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
e.getWindow().dispose();
System.exit(0);
}
});
}
public static void main(String[] args)
{
// TODO, add your application code
System.out.println("Hello World!");
TestStopWatch mainFrame=new TestStopWatch();
mainFrame.setTitle("TestStopWatch");
mainFrame.setSize(400,400);
mainFrame.setVisible(true);
}
}
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.text.*;
public class StopWatch1 extends Canvas implements Runnable
{
long startTime=0;
long endTime=0;
Date useTime=null;
boolean bStart=false;
private Runnable runnable = this;
public StopWatch1()
{
//enableEvents(AWTEvent.MOUSE_EVENT_MASK);
addMouseListener(new MouseAdapter()
{
public void mousePressed(MouseEvent e)
{
startTime=endTime=System.currentTimeMillis();
bStart=true;
new Thread(runnable).start();
repaint();
}
public void mouseReleased(MouseEvent e)
{
endTime=System.currentTimeMillis();
bStart=false;
repaint();
}
});
}
public void paint(Graphics g)
{
SimpleDateFormat sdf=new SimpleDateFormat("HH:mm:ss");
try
{
useTime=sdf.parse("00:00:00");
}
catch(Exception e)
{
e.printStackTrace();
}
useTime.setTime(useTime.getTime()+endTime-startTime);
String strTime=sdf.format(useTime);
g.fill3DRect(0,0,300,200,true);
g.setColor(Color.WHITE);
g.drawString(strTime,160,150);
}
/*protected void processMouseEvent(MouseEvent e)
{
if(e.getID()==e.MOUSE_PRESSED)
{
startTime=endTime=System.currentTimeMillis();
new Thread(this).start();
bStart=true;
repaint();
}
else if(e.getID()==e.MOUSE_RELEASED)
{
endTime=System.currentTimeMillis();
bStart=false;
repaint();
}
}*/
public void run()
{
while(bStart)
{
try
{
Thread.sleep(500);
}
catch(Exception e)
{
e.printStackTrace();
}
repaint();
endTime=System.currentTimeMillis();
}
}
}
菜单
● 一个完整的菜单系统由菜单条、菜单和菜单项组成,它们之间的关系如图:
● Java中与菜单相关的类主要有:MenuBar(菜单条)、Menu(菜单)、MenuItem(菜单项)
public void setActionCommand( command)
设置由此菜单项引发的动作事件的命令名。
默认情况下,动作命令设置为菜单项的标签
public getActionCommand()
获取由此菜单项引发的动作事件的命令名。
● 编程实例:实现图中的菜单和相关事件处理。
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.*;
publicclass TestMenu extends JFrame
{
privatestaticfinallongserialVersionUID = 1L;
JMenuBar jmenubar=new JMenuBar();
JMenu fileM=new JMenu("文件");
//fileM.setActionCommand("File");
JMenu editM=new JMenu("编辑");
JMenu toolM=new JMenu("工具");
JMenu helpM=new JMenu("帮助");
JMenuItem fileM1=new JMenuItem("新建");
JMenuItem fileM2=new JMenuItem("Close");
JMenuItem fileM3=new JMenuItem("保存");
JMenu fileM4=new JMenu("打印");
JMenuItem printM1=new JMenuItem("预览");
JMenuItem printM2=new JMenuItem("设置");
JCheckBoxMenuItem fileM5=new JCheckBoxMenuItem("退出",true);
JMenuItem toolM1=new JMenuItem("计算器");
JButton bt=new JButton("Exit");
TestMenu tm=this;
public TestMenu()
{
this.setJMenuBar(jmenubar);
jmenubar.add(fileM);
jmenubar.add(editM);
jmenubar.add(toolM);
jmenubar.add(helpM);
fileM.add(fileM1);
fileM.add(fileM2);
fileM.add(fileM3);
fileM.add(fileM4);
fileM4.add(printM1);
fileM4.add(printM2);
fileM.addSeparator();
fileM.add(fileM5);
toolM.add(toolM1);
this.add(bt,"South");
//fileM2.addActionListener(new QuitMenuListener());
toolM1.addActionListener(new QuitMenuListener());
fileM2.addActionListener(new ActionListener()
{
publicvoid actionPerformed(ActionEvent e)
{
tm.dispose();
System.out.println("打开");
}
});
addWindowListener(new WindowAdapter()
{
publicvoid windowClosing(WindowEvent e)
{
e.getWindow().dispose();
System.exit(0);
}
});
bt.addActionListener(new ActionListener()
{
publicvoid actionPerformed(ActionEvent e)
{
tm.dispose();
System.out.println("Exit");
}
});
}
publicstaticvoid main(String[] args)
{
// TODO Auto-generated method stub
TestMenu mainJFrame=new TestMenu();
mainJFrame.setTitle("TestMenu");
mainJFrame.setSize(400,400);
mainJFrame.setVisible(true);
}
}
import java.awt.event.*;
publicclass QuitMenuListener implements ActionListener
{
publicvoid actionPerformed(ActionEvent e)
{
if(e.getActionCommand().equals("Close"))
{
TestMenu tm=new TestMenu();
tm.dispose();
System.out.println("打开");
//System.exit(0);
}
elseif(e.getActionCommand().equals("计算器"))
{
try
{
Runtime.getRuntime().exec("calc.exe");
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
}
}
Container
● Container类是所胡容器的父类,Container.add方法用于将组件添加到容器中
● Container也是Component的子类,因此也可以作为组件增加到其它容器上
Dialog与FileDialog类
● Dialog类用于产生对话框
● 模态对话框和非模态对话框
● Dialog类的两个常用构造方法:
public JDialog( owner,
title)
创建一个具有指定标题和指定所有者对话框的无模式对话框。
此构造方法将该组件的语言环境属性设置为 JComponent.getDefaultLocale
所返回的值。
参数:
owner
- 显示该对话框的所有者 Dialog
;如果此对话框没有所有者,则为 null
title
- 该对话框的标题栏中所显示的 String
public JDialog( owner,
title,
boolean modal)
创建一个具有指定标题、模式和指定所有者 Dialog
的对话框。
此构造方法将该组件的语言环境属性设置为 JComponent.getDefaultLocale
所返回的值。
参数:
owner
- 显示该对话框的所有者 Dialog
;如果此对话框没有所有者,则为 null
title
- 该对话框的标题栏中所显示的 String
modal
- 指定对话框在显示时是否阻塞用户向其他顶层窗口输入。如果为 true
,则模式类型属性被设置为 DEFAULT_MODALITY_TYPE
;否则对话框是无模式的。
● 编程实例:主框架窗口通过两个按钮分别打开一个模态对话框和一个非模态对话框,并与这两个对话框进行数据交换。
package Dialog;
import javax.swing.*;
import java.awt.event.*;
public class TestDialog extends JFrame
{
private static final long serialVersionUID = 1L;
private JTextField tf=new JTextField(10);
public TestDialog()
{
JButton bt1=new JButton("打开模态对话窗");
JButton bt2=new JButton("打开非模态对话窗");
this.add(tf,"North");
this.add(bt1,"Center");
this.add(bt2,"East");
bt1.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
MyDialog dlg=new MyDialog(TestDialog.this,"Modal Dialog",true);
dlg.setBounds(300,200,300,300);
dlg.getInfo(tf.getText());
dlg.setVisible(true);
//注:(模态下)在MyDialog窗口没有关闭前,下面的代码不会执行
tf.setText(dlg.setInfo());
}
});
bt2.addActionListener(new ActionListener ()
{
public void actionPerformed(ActionEvent e)
{
MyDialog dlg=new MyDialog(TestDialog.this,"Modaless Dialog",false);
dlg.setBounds(300,200,300,300);
dlg.getInfo(tf.getText());
dlg.setVisible(true);
//注:(非模态下)在MyDialog窗口没有关闭前,下面的代码会执行
//......
}
});
addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
e.getWindow().dispose();
}
});
}
public void setInfo(String strInfo)
{
tf.setText(strInfo);
}
public static void main(String[] args)
{
// TODO Auto-generated method stub
TestDialog mainFrame=new TestDialog();
mainFrame.setTitle("TestDialog");
mainFrame.setBounds(200,100,500,400);
mainFrame.setVisible(true);
}
}
package Dialog;
import javax.swing.JDialog;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class MyDialog extends JDialog
{
private JTextField tf=new JTextField(10);
private String str=null;
private static final long serialVersionUID = 1L;
public MyDialog(Frame owner,String title,boolean modal)
{
super(owner,title,modal);
JButton bt1=new JButton("应用");
JButton bt2=new JButton("确定");
this.add(tf,"North");
this.add(bt1,"Center");
this.add(bt2,"East");
if(this.isModal()==true)
{
bt1.setEnabled(false);
}
bt1.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
((TestDialog)(MyDialog.this.getOwner())).setInfo(tf.getText());
}
});
bt2.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
if(MyDialog.this.isModal()==true)
{
str=new String(tf.getText());
}
else
{
((TestDialog)MyDialog.this.getOwner()).setInfo(tf.getText());
}
dispose();
}
});
}
public void getInfo(String strInfo)
{
tf.setText(strInfo);
}
public String setInfo()
{
return str;
}
}
FileDialog
类显示一个对话框窗口,用户可以从中选择文件。
由于它是一个模式对话框,当应用程序调用其 show
方法来显示对话框时,它将阻塞其余应用程序,直到用户选择一个文件
● 例:如图
package Dialog;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TestFileDialog extends JFrame
{
private static final long serialVersionUID = -2241805119101248119L;
public TestFileDialog()
{
/*JButton bt1=new JButton("打开");
JButton bt2=new JButton("保存");
this.add(bt1,"Center");
this.add(bt2,"East");
bt1.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
MyFileDialog
fdg=new MyFileDialog(TestFileDialog.this,"FileDialog",FileDialog.LOAD);
fdg.setSize(300,200);
Dimension
d=new Dimension(TestFileDialog.this.getWidth(),TestFileDialog.this.getHeight());
fdg.setSize(d);
fdg.setVisible(true);
}
});
*/
JMenuBar menubar=new JMenuBar();
JMenu menu=new JMenu();
menu.setText("File");
JMenuItem open=new JMenuItem();
JMenuItem save=new JMenuItem();
open.setText("Open");
save.setText("Save");
this.setJMenuBar(menubar);
menubar.add(menu);
menu.add(open);
menu.add(save);
re=getMaximizedBounds();
this.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
e.getWindow().dispose();
}
});
open.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
MyFileDialog fdg=
New MyFileDialog(TestFileDialog.this,"Openmage",FileDialog.LOAD);
//fdg.setSize(200,200);
fdg.setVisible(true);
String str=fdg.getFile();
System.out.println(str);
}
});
save.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
MyFileDialog fdg=
new MyFileDialog(TestFileDialog.this,"Save Image",FileDialog.SAVE);
//fdg.setSize(200,200);
fdg.setVisible(true);
}
});
}
public static void main(String[] args)
{
// TODO Auto-generated method stub
TestFileDialog mainFrame=new TestFileDialog();
mainFrame.setTitle("TestFileDialog");
mainFrame.setBounds(200,100,600,500);
//mainFrame.setMaximizedBounds(null);
mainFrame.setVisible(true);
}
}
package Dialog;
//import java.awt.Event.*;
import java.awt.*;
publicclass MyFileDialog extends FileDialog
{
privatestaticfinallongserialVersionUID = 1L;
public MyFileDialog(Frame parent,String title,int modal)
{
super(parent,title,modal);
}
}