第8章 GUI/图形用户界面
● 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)方法,可以在即使没有注册事件监听器的情况下,组件也能够对某些类型的事件进行响应和产生相应的事件对象。
注:
processKeyEvent
protected void processKeyEvent(KeyEvent e)
处理组件上发生的按键事件,方法是将其指派到任意已注册的 KeyListener
对象。
如果组件上没有启用按键事件,则不调用此方法。发生下列之一时启用按键事件:
· 通过 addKeyListener
注册了一个 KeyListener
对象。
· 通过 enableEvents
启用了按键事件。
如果为某个 Component
启用了按键事件,则当前的 KeyboardFocusManager
确定是否应该将按键事件指派到已注册的 KeyListener
事件。DefaultKeyboardFocusManager
不会为非焦点所有者或未显示的 Component
指派按键事件。
在 J2SE 1.4 中,已将 KeyEvent
重定向到焦点所有者。有关更多信息,请参阅 Focus Specification。
只要组件正在显示、已定焦、已启用并且其上的按键事件已启用,那么使用 dispatchEvent
作为参数来调用 KeyEvent
的 Component
方法将导致调用 Component
的 processKeyEvent
方法,而不管当前的 KeyboardFocusManager
如何。
注意,如果事件参数为 null
,则未指定行为并且可能导致异常
processMouseEvent
protected void processMouseEvent(MouseEvent e)
处理组件上发生的鼠标事件,方法是将其指派到任意已注册的 MouseListener
对象。
如果组件上没有启用鼠标事件,则不调用此方法。发生下列之一时启用鼠标事件:
· 通过 addMouseListener
注册了一个 MouseListener
对象。
· 通过 enableEvents
启用了鼠标事件。
注意,如果事件参数为 null
,则未指定行为并且可能导致异常。
processMouseMotionEvent
protected void processMouseMotionEvent(MouseEvent 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(菜单项)
setActionCommand
public void setActionCommand(String command)
设置由此菜单项引发的动作事件的命令名。
默认情况下,动作命令设置为菜单项的标签
getActionCommand
public String 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(Dialog owner,
String title)
创建一个具有指定标题和指定所有者对话框的无模式对话框。
此构造方法将该组件的语言环境属性设置为 JComponent.getDefaultLocale
所返回的值。
参数:
owner
- 显示该对话框的所有者 Dialog
;如果此对话框没有所有者,则为 null
title
- 该对话框的标题栏中所显示的 String
public JDialog(Dialog owner,
String 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);
}
}
Checkbox类
● Checkbox类用来建立单选按钮和多选按钮(也叫复选框)。
● 创建多选按钮,只需要使用构造函数:
Checkbox
(String label, boolean state)
● 创建单选按钮,需要使用构造函数:
Checkbox
(String label, boolean state, CheckboxGroup group)
● 单选按钮和多选按钮的语义事件为ItemEvent,对应的监听器接口为ItemListener,该接口中只有一个itemStateChanged方法
● 编程实例:创建一个多选按钮和两个属于同一组的单选按钮,并对每个按钮的选中情况进行处理
package checkbox;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;;
publicclass TestCheckbox extends JFrame
{
privatestaticfinallongserialVersionUID = 1L;
Checkbox checkbox=new Checkbox("上海市",true);
JCheckBox jcheckbox1=new JCheckBox("北京市");
JCheckBox jcheckbox2=new JCheckBox("南京市",true);
Image img=this.getToolkit().getImage("..""ico.jpg");
ImageIcon imgicon=new ImageIcon(img);
//Icon icon=imgicon;
CheckboxGroup cbg=new CheckboxGroup();
Checkbox checkbox1=new Checkbox("18岁",true,cbg);
Checkbox checkbox2=new Checkbox("20岁",false,cbg);
Choice cho=new Choice();
class choiceItemListener implements ItemListener
{
publicvoid itemStateChanged(ItemEvent e)
{
if(e.getItem().equals("男孩"))
{
System.out.println("我是男孩");
}
else
{
System.out.println("我是女孩");
}
}
}
class checkboxItemListener implements ItemListener
{
publicvoid itemStateChanged(ItemEvent e)
{
Checkbox cb=new Checkbox();
cb=(Checkbox)e.getItemSelectable();
/*if(cb.getLabel().equals("18岁"))
{
System.out.println("18岁啦");
}
else
{
System.out.println("20岁啦");
}
if(cb.getState()==true)
{
System.out.println(cb.getLabel());
}*/
if(cb==checkbox1)
{
System.out.println("18岁啦");
}
else
{
System.out.println("20岁啦");
}
}
}
public TestCheckbox()
{
//用于产生流式部局管理器
FlowLayout fl=new FlowLayout();
this.setLayout(fl);
cho.add("男孩");
cho.add("女孩");
this.add(cho);
this.add(checkbox);
this.add(jcheckbox1);
this.add(jcheckbox2);
this.add(checkbox1);
this.add(checkbox2);
cho.addItemListener(new choiceItemListener());
checkboxItemListener cbi=new checkboxItemListener();
checkbox1.addItemListener(cbi);
checkbox2.addItemListener(cbi);
addWindowListener(new WindowAdapter()
{
publicvoid windowClosing(WindowEvent e)
{
e.getWindow().dispose();
}
});
}
publicstaticvoid main(String[] args)
{
// TODO Auto-generated method stub
TestCheckbox mainFrame=new TestCheckbox();
mainFrame.setSize(400,400);
mainFrame.setTitle("TestCheckbox");
mainFrame.setVisible(true);
}
}
Panel与ScrollPane类
● Panel类是一个容器类,用于产生一种特殊的空白面板,可以容纳其他的组件,但不能独立存在
Panel的两个构造函数:
public Panel()
使用默认的布局管理器创建新面板。所有面板的默认布局管理器都是 FlowLayout
类
public Panel(LayoutManager layout)
创建具有指定布局管理器的新面板。
参数:
layout
- 此面板的布局管理器。
● ScrollPane类是一种容器类,用于产生滚动窗口,通过滚动条在一个较小的窗口中显示较大的子部件。在ScrollPane容器内只能增加一个组件。
ScrollPanel的两个构造函数:
public ScrollPane()
throws HeadlessException
创建一个具有滚动条策略 "as needed" 的新滚动窗格容器。
public ScrollPane(int scrollbarDisplayPolicy)
throws HeadlessException
创建新的滚动窗格容器
滚动条的显示策略可以设置如下:
- as needed: 创建滚动条,且只在滚动窗格需要时显示
- always: 创建滚动条,且滚动窗格总是显示滚动条
- never: 滚动窗格永远不创建或显示滚动条
编程举例:如何使用ScrollPane 如图:
package TestArea;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
publicclass TestTextArea extends JFrame
{
privatestaticfinallongserialVersionUID = 1L;
public TestTextArea()
{
//关闭窗体
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
JTextArea jta=new JTextArea(30,20);
ScrollPane sp=new ScrollPane();
sp.add(jta);
//把容器添加到窗体
//this.add(sp);
this.getContentPane().add(sp);
addWindowListener(new WindowAdapter()
{
publicvoid windowClosing(WindowEvent e)
{
//e.getWindow().dispose();
}
});
}
publicstaticvoid main(String[] args)
{
// TODO Auto-generated method stub
TestTextArea mainFrame =new TestTextArea();
mainFrame.setTitle("TestTextArea");
mainFrame.setSize(200,200);
mainFrame.setVisible(true);
}
}
布局管理器
● 一个容器中的各个组件之间的位置和大小关系就称之为布局
● Java语言提供了布局管理器来管理组件在容器中的布局,而不是直接使用位置坐标来设置各个组件的位置和大小
● AWT中的布局管理器类:
◆ BorderLayout
◆ FlowLayout
◆ GridLayout
◆ CardLayout
◆ GridBagLayout
BorderLayout编程实例
如图:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
publicclassTestBorderLayout extends JFrame
{
privatestaticfinallongserialVersionUID = 1L;
public TestTextArea()
{
//关闭窗体
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.add(new JButton("North"), "North");
this.add(new JButton("South"), "South");
this.add(new JButton("East"), "East");
this.add(new JButton("West"), "West");
this.add(new JButton("Center"), "Center");
addWindowListener(new WindowAdapter()
{
publicvoid windowClosing(WindowEvent e)
{
//e.getWindow().dispose();
}
});
}
publicstaticvoid main(String[] args)
{
// TODO Auto-generated method stub
TestBorderLayout mainFrame =newTestBorderLayout ();
mainFrame.setTitle("TestBorderLayout");
mainFrame.setSize(300,200);
mainFrame.setVisible(true);
}
}
FlowLayout编程实例
package TestArea;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
publicclass TestTextArea extends JFrame
{
privatestaticfinallongserialVersionUID = 1L;
public TestTextArea()
{
//关闭窗体
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setLayout(new FlowLayout());
this.add(new JButton("East"));
this.add(new JButton("South"));
this.add(new JButton("West"));
this.add(new JButton("North"));
this.add(new JButton("Center"), "Center");
addWindowListener(new WindowAdapter()
{
publicvoid windowClosing(WindowEvent e)
{
//e.getWindow().dispose();
}
});
}
publicstaticvoid main(String[] args)
{
// TODO Auto-generated method stub
TestFlowLayout mainFrame =newTestFlowLayout ();
mainFrame.setTitle("TestFlowLayout");
mainFrame.setSize(300,200);
mainFrame.setVisible(true);
}
}
GridLayout编程实例
● GridLayout布局管理器将容器划分成若干行列的网格,在容器上添加组件时它们会按从左到右、从上到下的顺序在风格中排列
● 在GridLayout的构造方法中,需要指定在容器上划分的网格的行、列数
CardLayout
● CardLayout布局管理器能够实现将多个组件放在同一容器区域内的交替显示,相当于多张卡片摞在一起,在任何时候都只有最上面的一个可见
编程实例
创建两个Panel对象,每个Panel上都能拥有一个布局管理器,左边的Panel使用GridLayout布局器放置3个按钮,右边的Panel上使用CardLayout布局管理器来放置卡片,最后在窗口上使用BorderLayout放置这两个Panel面板。右边的Panel中带有5张卡片(用5个按钮模拟),按下左边的Panel中的prev按钮,依次向前显示,按下next按钮,依次向后显示,按下three按钮,显示第三张卡片
package cardlayout;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
publicclass TestImage extends JFrame
{
privatestaticfinallongserialVersionUID = 1L;
JPanel plCard=new JPanel();
CardLayout cl=new CardLayout();
public TestImage()
{
this.setLayout(new BorderLayout());
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
JPanel pl=new JPanel();
pl.setLayout(new GridLayout(2,1));
JButton btPrev=new JButton(/*"前一个"*/);
JButton btNext=new JButton(/*"下一个"*/);
ImageIcon icon1=new ImageIcon("image""back.gif");
ImageIcon icon2=new ImageIcon("image""next.gif");
btPrev.setIcon(icon1);
btNext.setIcon(icon2);
pl.add(btPrev);
pl.add(btNext);
this.add(pl,"West");
plCard.setLayout(cl);
ImageIcon icon3=new ImageIcon("image""001.gif");
ImageIcon icon4=new ImageIcon("image""002.gif");
ImageIcon icon5=new ImageIcon("image""003.gif");
ImageIcon icon6=new ImageIcon("image""004.gif");
ImageIcon icon7=new ImageIcon("image""005.gif");
ImageIcon icon8=new ImageIcon("image""006.gif");
JLabel lb1=new JLabel();
JLabel lb2=new JLabel();
JLabel lb3=new JLabel();
JLabel lb4=new JLabel();
JLabel lb5=new JLabel();
JLabel lb6=new JLabel();
lb1.setIcon(icon3);
lb2.setIcon(icon4);
lb3.setIcon(icon5);
lb4.setIcon(icon6);
lb5.setIcon(icon7);
lb6.setIcon(icon8);
plCard.add(lb1,"1");
plCard.add(lb2,"2");
plCard.add(lb3,"3");
plCard.add(lb4,"4");
plCard.add(lb5,"5");
plCard.add(lb6,"6");
this.add(plCard);
MyActionListener my=new MyActionListener();
btPrev.addActionListener(my);
btNext.addActionListener(my);
}
class MyActionListener implements ActionListener
{
publicvoid actionPerformed(ActionEvent e)
{
//if(e.getActionCommand().equals("前一个"))
if(e.getID()==e.COMPONENT_EVENT_MASK)
{
cl.previous(plCard);
}
else
{
cl.next(plCard);
}
}
}
publicstaticvoid main(String[] args)
{
// TODO Auto-generated method stub
TestImage mainFrame=new TestImage();
mainFrame.setTitle("显示图片");
mainFrame.setBounds(100,100,400,300);
mainFrame.setVisible(true);
}
}
package cardlayout;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TestCardLayout extends JFrame
{
private static final long serialVersionUID = 1L;
CardLayout cl=new CardLayout();
Panel plCard=new Panel();
public TestCardLayout()
{
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
Panel pl=new Panel();
GridLayout gl=new GridLayout(5,1);
pl.setLayout(gl);
JButton btFirst=new JButton("First");
JButton btPrev=new JButton("Prev");
JButton btNext=new JButton("Next");
JButton btThree=new JButton("Three");
JButton btLast=new JButton("Last");
pl.add(btFirst);
pl.add(btPrev);
pl.add(btNext);
pl.add(btThree);
pl.add(btLast);
this.add(pl,"West");
plCard.setLayout(cl);
//images文件夹和bin目录在同一目录下
ImageIcon icon1=new ImageIcon("images""gcz01.jpg");
ImageIcon icon2=new ImageIcon("images""gcz02.jpg");
ImageIcon icon3=new ImageIcon("images""gcz03.jpg");
ImageIcon icon4=new ImageIcon("images""gcz04.jpg");
ImageIcon icon5=new ImageIcon("images""gcz05.jpg");
JButton bt1=new JButton("One",icon1);
JButton bt2=new JButton("Two",icon2);
JButton bt3=new JButton("Three",icon3);
JButton bt4=new JButton(icon4);
JButton bt5=new JButton();
bt5.setIcon(icon5);
plCard.add(bt1,"1");
plCard.add(bt2,"2");
plCard.add(bt3,"3");
plCard.add(bt4,"4");
plCard.add(bt5,"5");
this.add(plCard);
MyActionListener ml=new MyActionListener();
btPrev.addActionListener(ml);
btNext.addActionListener(ml);
btThree.addActionListener(ml);
btFirst.addActionListener(ml);
btLast.addActionListener(ml);
}
class MyActionListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
if(e.getActionCommand().equals("Prev"))
{
cl.previous(plCard);
}
else if(e.getActionCommand().equals("First"))
{
cl.first(plCard);
}
else if(e.getActionCommand().equals("Last"))
{
cl.last(plCard);
}
else if(e.getActionCommand().equals("Next"))
{
cl.next(plCard);
}
else
{
cl.show(plCard,"3");
}
}
}
public static void main(String[] args)
{
// TODO Auto-generated method stub
TestCardLayout mainFrame=new TestCardLayout();
mainFrame.setBounds(100,100,400,300);
mainFrame.setTitle("TestCardLayout");
mainFrame.setVisible(true);
}
}
取消布局管理器
● 调用Container.setLayout(null)方法取消布局管理器设置,在这种情况下,可以调用Component.setBounds方法来用绝对坐标设置容器上的每个组件的大小和位置。
● 不使用布局管理器将会给程序带来一个潜在的问题,当容器大小改变时,所有组件仍保持原来的位置和大小,交导致整个程序界面比较难看。
Swing和JFC
● 所有的Swing组件,位于java.swing包中,它们是构筑在AWT上层的GUI组件,Swing组件是JComponent类的子类,JComponent又是java.awt.Containt的子类
● 为保证可移植性,Swing完全用Java语言编写
● Swing提供了比AWT更多的组件库,例如,Jtable,Jtree,JcomboBox
● Swing也增加了AWT中原有组件的功能,例如,与AWT中的Button对应的Swing组件是Jbutton
● JFC(java Foundation Class)是指Sun对早期的JDK进行扩展的部分,集合了Swing组件和其他能简化开发的API类,包括Swing,java2D,accessibility,internationalization
编程实例:从AWT到Swing
JFrame
● JFrame是与AWT中的Frame相对应的Swing组件
● JFrame上面只能有一个唯一的组件,这个组件为JRootPane,调用JFrame.getContentPane()方法可获得JFrame中内置的JrootPane对象。
● 应用程序不能直接在JFrame实例对象上增加组件和设置布局管理器,而应该在JRootPane对象上增加子组件和设置布局管理器。
● 调用Jframer setDefaultCloseOperation方法,可以设置单击窗口上的关闭按钮时的事件处理方式,例如:当设置值为JFrame.EXIT_ON_CLOSE时,单击JFrame窗口上的关闭按钮,将直接关闭JFrame框架窗口并结束程序运行。
编程实例:使用JFrame来创建程序的主框架窗口
import java.awt.GridLayout;
import javax.swing.*;
publicclass TestJFrame extends JFrame
{
privatestaticfinallongserialVersionUID = 1L;
public TestJFrame()
{
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton bt=new JButton("OK");
JButton bt1=new JButton("EXIT");
//this.getContentPane().add(bt);
JPanel pl=new JPanel();
pl.setLayout(new GridLayout(2,1));
pl.add(bt);
pl.add(bt1);
this.getContentPane().add(pl);
}
publicstaticvoid main(String[] args)
{
// TODO Auto-generated method stub
TestJFrame mainFrame=new TestJFrame();
mainFrame.setSize(300,200);
mainFrame.setVisible(true);
}
}
JScrollPane
● JScrollPane是与AWT中的ScrollPane相对应的Swing组件
● 最基本的JScrollPane由水平和垂直方向上的JScrollBar、以及一个JViewport组件
● 调用JScrollPane.getViewport方法,可以获得代表滚动窗口中的视图区域的JViewport对象。
● 调用JViewport.setViesport方法,可以将滚动窗口中要显示的内容作为子组件增加到JViewport上。
● 编程实例:使用JScrollPane创建滚动窗口
import javax.swing.*;
publicclass TestJFrame extends JFrame
{
privatestaticfinallongserialVersionUID = 1L;
public TestJFrame()
{
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JScrollPane jsp=new JScrollPane();
JTextArea jta=new JTextArea(20,30);
jsp.getViewport().add(jta);
this.getContentPane().add(jsp);
}
publicstaticvoid main(String[] args)
{
// TODO Auto-generated method stub
TestJFrame mainFrame=new TestJFrame();
mainFrame.setSize(300,200);
mainFrame.setVisible(true);
}
}
JScrollPane
● JOptionPane类提供了若干了showXxxDialog静态方法,可用来产生简单的标准对话框
方法名
|
描述
|
showConfirmDialog
|
询问一个确认问题,如 yes/no/cancel。
|
showInputDialog
|
提示要求某些输入。
|
showMessageDialog
|
告知用户某事已发生。
|
showOptionDialog
|
上述三项的大统一 (Grand Unification)。
|
public static int showConfirmDialog(Component parentComponent,
Object message,
String title,
int optionType,
int messageType)
throws HeadlessException
调用一个由 optionType
参数确定其中选项数的对话框,messageType
参数确定要显示的图标。messageType
参数主要用于提供来自外观的默认图标。
参数:
parentComponent
- 确定在其中显示对话框的 Frame
;如果为 null
或者 parentComponent
不具有 Frame
,则使用默认的 Frame
。
message
- 要显示的 Object
title
- 对话框的标题字符串
optionType
- 指定可用于对话框的选项的整数:YES_NO_OPTION
、YES_NO_CANCEL_OPTION
或 OK_CANCEL_OPTION
messageType
- 指定此消息种类的整数;主要用于确定来自可插入外观的图标:ERROR_MESSAGE
、INFORMATION_MESSAGE
、WARNING_MESSAGE
、QUESTION_MESSAGE
或 PLAIN_MESSAGE
返回:
指示用户所选选项的整数
示例:
显示一个错误对话框,该对话框显示的 message 为 'alert':
JOptionPane.showMessageDialog(null, "alert", "alert", JOptionPane.ERROR_MESSAGE);
显示一个内部信息对话框,其 message 为 'information':
JOptionPane.showInternalMessageDialog(frame, "information",
"information", JOptionPane.INFORMATION_MESSAGE);
显示一个信息面板,其 options 为 "yes/no",message 为 'choose one':
JOptionPane.showConfirmDialog(null,
"choose one", "choose one", JOptionPane.YES_NO_OPTION);
显示一个内部信息对话框,其 options 为 "yes/no/cancel",message 为 'please choose one',并具有 title 信息:
JOptionPane.showInternalConfirmDialog(frame,
"please choose one", "information",
JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE);
显示一个警告对话框,其 options 为 OK、CANCEL,title 为 'Warning',message 为 'Click OK to continue':
Object[] options = { "OK", "CANCEL" };
JOptionPane.showOptionDialog(null, "Click OK to continue", "Warning",
JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE,
null, options, options[0]);
显示一个要求用户键入 String 的对话框:
String inputValue = JOptionPane.showInputDialog("Please input a value");
显示一个要求用户选择 String 的对话框:
Object[] possibleValues = { "First", "Second", "Third" };
Object selectedValue = JOptionPane.showInputDialog(null,
"Choose one", "Input",
JOptionPane.INFORMATION_MESSAGE, null,
possibleValues, possibleValues[0]);
编程举例:使用JOptionPane类,在程序开始运行时,弹出一个对话框提示用户,在主框架窗口的关闭按钮被单击时,弹出一个对话框询问用户是否真的要结束程序的运行。
import java.awt.event.*;
import javax.swing.*;
publicclass TestJFrame extends JFrame
{
privatestaticfinallongserialVersionUID = 1L;
public TestJFrame()
{
this.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
ImageIcon iconMessage=new ImageIcon("images""message.gif");
JOptionPane.showMessageDialog(this,"程序已运行...","Running",
JOptionPane.INFORMATION_MESSAGE,iconMessage);
JScrollPane jsp=new JScrollPane();
JTextArea jta=new JTextArea(20,30);
jsp.getViewport().add(jta);
this.getContentPane().add(jsp);
addWindowListener(new WindowAdapter()
{
publicvoid windowClosing(WindowEvent e)
{
ImageIcon iconExit=new ImageIcon("images""exit.jpg");
if(JOptionPane.showConfirmDialog(TestJFrame.this, "确认要退出吗?",
"退出", JOptionPane.OK_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE,iconExit)==JOptionPane.YES_OPTION)
{
e.getWindow().dispose();
}
}
});
}
publicstaticvoid main(String[] args)
{
// TODO Auto-generated method stub
TestJFrame mainFrame=new TestJFrame();
mainFrame.setTitle("TestJOptionPane");
mainFrame.setSize(300,200);
mainFrame.setVisible(true);
}
}
● JFileChooser类专门用来实现文件存取对话框
例:选择一图片添加到JLabel上。
package filechooser;
import java.awt.BorderLayout;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;;
publicclass TestJFileChooser extends JFrame
{
privatestaticfinallongserialVersionUID = 1L;
JButton bt=new JButton("选择");
JLabel lb=new JLabel();
JPanel pl=new JPanel();
public TestJFileChooser()
{
pl.setLayout(new BorderLayout());
pl.add(bt,"North");
pl.add(lb,"Center");
this.getContentPane().add(pl);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
bt.addActionListener(new ActionListener()
{
publicvoid actionPerformed(ActionEvent e)
{
JFileChooser jchooser=new JFileChooser();
FileNameExtensionFilter filter=new FileNameExtensionFilter
("JPG & GIF Images", "jpg", "gif");
jchooser.setFileFilter(filter);
int returnValue=jchooser.showOpenDialog(TestJFileChooser.this);
if(returnValue==JFileChooser.APPROVE_OPTION)
{
System.out.println("You chose to open this file: " +
jchooser.getSelectedFile().getName());
String strPath=jchooser.getSelectedFile().getAbsolutePath();
ImageIcon icon=new ImageIcon(strPath);
lb.setIcon(icon);
}
}
});
}
publicstaticvoid main(String[] args)
{
// TODO Auto-generated method stub
TestJFileChooser mainJFrame=new TestJFileChooser();
mainJFrame.setTitle("TestJFileChooser");
mainJFrame.setSize(400,400);
mainJFrame.setVisible(true);
}
}
计算器界面的程序实例
要求:
● 单击任何按钮,按钮上面的数字或符号按从左到右的顺序显示在文本框中
● 文本框中的文字是右对齐显示
package calc;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TestCalc extends JFrame implements ActionListener,KeyListener
{
private static final long serialVersionUID = 1L;
JTextField tf=new JTextField(20);
JButton bt1,bt2,bt3,bt4,bt5,bt6,bt7,bt8,bt9,bt10,bt11,bt12,
bt13,bt14,bt15,bt16,bt17,bt18,bt19,bt20;
//按钮旗标
int flag=0;
//键盘旗标
int flagk=0;
double x=0;
double y=0;
double result=0;
String str="";
public TestCalc()
{
super("计算器");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
tf.setHorizontalAlignment(JTextField.RIGHT);
tf.setText("0");
tf.setEditable(false);
Container c=this.getContentPane();
JPanel pl=new JPanel();
JPanel pltf=new JPanel();
//this.setBackground(Color.LIGHT_GRAY);
bt1=new JButton("1");
bt1.setForeground(Color.RED);
bt1.setFont(new Font("",Font.BOLD,20));
bt1.addActionListener(this);
bt2=new JButton("2");
bt2.setForeground(Color.RED);
bt2.setFont(new Font("",Font.BOLD,20));
bt2.addActionListener(this);
bt3=new JButton("3");
bt3.setForeground(Color.RED);
bt3.setFont(new Font("",Font.BOLD,20));
bt3.addActionListener(this);
bt11=new JButton("+");
bt11.setForeground(Color.RED);
bt11.setFont(new Font("",Font.BOLD,20));
bt11.addActionListener(this);
bt4=new JButton("4");
bt4.setForeground(Color.RED);
bt4.setFont(new Font("",Font.BOLD,20));
bt4.addActionListener(this);
bt5=new JButton("5");
bt5.setForeground(Color.RED);
bt5.setFont(new Font("",Font.BOLD,20));
bt5.addActionListener(this);
bt6=new JButton("6");
bt6.setForeground(Color.RED);
bt6.setFont(new Font("",Font.BOLD,20));
bt6.addActionListener(this);
bt12=new JButton("-");
bt12.setForeground(Color.RED);
bt12.setFont(new Font("",Font.BOLD,20));
bt12.addActionListener(this);
bt7=new JButton("7");
bt7.setForeground(Color.RED);
bt7.setFont(new Font("",Font.BOLD,20));
bt7.addActionListener(this);
bt8=new JButton("8");
bt8.setForeground(Color.RED);
bt8.setFont(new Font("",Font.BOLD,20));
bt8.addActionListener(this);
bt9=new JButton("9");
bt9.setForeground(Color.RED);
bt9.setFont(new Font("",Font.BOLD,20));
bt9.addActionListener(this);
bt13=new JButton("*");
bt13.setForeground(Color.RED);
bt13.setFont(new Font("",Font.BOLD,20));
bt13.addActionListener(this);
bt10=new JButton("0");
bt10.setForeground(Color.RED);
bt10.setFont(new Font("",Font.BOLD,20));
bt10.addActionListener(this);
bt14=new JButton(".");
bt14.setForeground(Color.RED);
bt14.setFont(new Font("",Font.BOLD,20));
bt14.addActionListener(this);
bt15=new JButton("/");
bt15.setForeground(Color.RED);
bt15.setFont(new Font("",Font.BOLD,20));
bt15.addActionListener(this);
bt16=new JButton("=");
bt16.setForeground(Color.RED);
bt16.setFont(new Font("",Font.BOLD,20));
bt16.addActionListener(this);
bt17=new JButton("清空");
bt17.setForeground(Color.BLUE);
bt17.addActionListener(this);
bt18=new JButton("Backspace");
bt18.setForeground(Color.BLUE);
bt18.addActionListener(this);
bt19=new JButton("");
bt20=new JButton("");
pltf.add(tf);
pl.add(bt19);
pl.add(bt17);
pl.add(bt20);
pl.add(bt18);
pl.add(bt1);
pl.add(bt2);
pl.add(bt3);
pl.add(bt11);
pl.add(bt4);
pl.add(bt5);
pl.add(bt6);
pl.add(bt12);
pl.add(bt7);
pl.add(bt8);
pl.add(bt9);
pl.add(bt13);
pl.add(bt10);
pl.add(bt14);
pl.add(bt15);
pl.add(bt16);
GridLayout gltf=new GridLayout(1,1,10,5);
GridLayout gl=new GridLayout(5,4,10,20);
pltf.setLayout(gltf);
pl.setLayout(gl);
tf.setFocusable(true);
c.add(pltf,BorderLayout.NORTH);
c.add(pl,BorderLayout.CENTER);
tf.addKeyListener(this);
}
public static void main(String[] args)
{
// TODO Auto-generated method stub
TestCalc mainFrame=new TestCalc();
//mainFrame.setTitle("计算器界面的实现");
mainFrame.setSize(300,300);
mainFrame.setLocation(100,100);
mainFrame.setVisible(true);
mainFrame.setResizable(false);
}
public void actionPerformed(ActionEvent e)
{
//数字键1
if(e.getSource()==bt1)
{
if(tf.getText().trim().indexOf('=')==-1)
{
if(tf.getText().equals("0"))
{
tf.setText(e.getActionCommand().trim());
//tf.setFocusable(true);
}
else
{
tf.setText(tf.getText().trim()+e.getActionCommand().trim());
//tf.setFocusable(true);
}
}
}
//数字键2
else if(e.getSource()==bt2)
{
if(tf.getText().trim().indexOf('=')==-1)
{
if(tf.getText().equals("0"))
{
tf.setText(e.getActionCommand().trim());
}
else
{
tf.setText(tf.getText().trim()+e.getActionCommand().trim());
}
}
}
//数字键3
else if(e.getSource()==bt3)
{
if(tf.getText().trim().indexOf('=')==-1)
{
if(tf.getText().equals("0"))
{
tf.setText(e.getActionCommand().trim());
}
else
{
tf.setText(tf.getText().trim()+e.getActionCommand().trim());
}
}
}
//数字键4
else if(e.getSource()==bt4)
{
if(tf.getText().trim().indexOf('=')==-1)
{
if(tf.getText().equals("0"))
{
tf.setText(e.getActionCommand().trim());
}
else
{
tf.setText(tf.getText().trim()+e.getActionCommand().trim());
}
}
}
//数字键5
else if(e.getSource()==bt5)
{
if(tf.getText().trim().indexOf('=')==-1)
{
if(tf.getText().equals("0"))
{
tf.setText(e.getActionCommand().trim());
}
else
{
tf.setText(tf.getText().trim()+e.getActionCommand().trim());
}
}
}
//数字键6
else if(e.getSource()==bt6)
{
if(tf.getText().trim().indexOf('=')==-1)
{
if(tf.getText().equals("0"))
{
tf.setText(e.getActionCommand().trim());
}
else
{
tf.setText(tf.getText().trim()+e.getActionCommand().trim());
}
}
}
//数字键7
else if(e.getSource()==bt7)
{
if(tf.getText().trim().indexOf('=')==-1)
{
if(tf.getText().equals("0"))
{
tf.setText(e.getActionCommand().trim());
}
else
{
tf.setText(tf.getText().trim()+e.getActionCommand().trim());
}
}
}
//数字键8
else if(e.getSource()==bt8)
{
if(tf.getText().trim().indexOf('=')==-1)
{
if(tf.getText().equals("0"))
{
tf.setText(e.getActionCommand().trim());
}
else
{
tf.setText(tf.getText().trim()+e.getActionCommand().trim());
}
}
}
//数字键9
else if(e.getSource()==bt9)
{
if(tf.getText().trim().indexOf('=')==-1)
{
if(tf.getText().equals("0"))
{
tf.setText(e.getActionCommand().trim());
}
else
{
tf.setText(tf.getText().trim()+e.getActionCommand().trim());
}
}
}
//数字键0
else if(e.getSource()==bt10)
{
if(tf.getText().trim().indexOf('=')==-1)
{
if(tf.getText().equals("0"))
{}
else
{
tf.setText(tf.getText().trim()+e.getActionCommand().trim());
}
}
}
//数字键.
else if(e.getSource()==bt14)
{
int dianStart=tf.getText().trim().indexOf('.');
int dianEnd=tf.getText().trim().lastIndexOf('.');
if(dianEnd-dianStart>4)
{
tf.setText(tf.getText().trim());
}
else
{
if(tf.getText().length()<0)
{
tf.setText("0"+e.getActionCommand().trim());
}
else
{
tf.setText(tf.getText().trim()+e.getActionCommand().trim());
}
}
}
//数字键+
else if(e.getSource()==bt11)
{
if(flag==2||flag==3||flag==4)
{}
else
{
flag=1;
if(tf.getText().trim().indexOf('+')==-1)
{
x=Double.valueOf(tf.getText().trim());
tf.setText(tf.getText().trim()+"+");
y=0d;
}
else
{
tf.setText(tf.getText().trim());
}
}
}
//数字键-
else if(e.getSource()==bt12)
{
if(flag==1||flag==3||flag==4)
{}
else
{
flag=2;
if(tf.getText().trim().indexOf('-')==-1)
{
x=Double.valueOf(tf.getText().trim());
tf.setText(tf.getText().trim()+"-");
y=0d;
}
else
{
tf.setText(tf.getText().trim());
}
}
}
//数字键*
else if(e.getSource()==bt13)
{
if(flag==1||flag==2||flag==4)
{}
else
{
flag=3;
if(tf.getText().trim().indexOf('*')==-1)
{
x=Double.valueOf(tf.getText().trim());
tf.setText(tf.getText().trim()+"*");
y=0d;
}
else
{
tf.setText(tf.getText().trim());
}
}
}
//数字键/
else if(e.getSource()==bt15)
{
if(flag==1||flag==2||flag==3)
{}
else
{
flag=4;
if(tf.getText().trim().indexOf('/')==-1)
{
x=Double.valueOf(tf.getText().trim());
tf.setText(tf.getText().trim()+"/");
y=0d;
}
else
{
tf.setText(tf.getText().trim());
}
}
}
//清空
else if(e.getSource()==bt17)
{
tf.setText("0");
flag=0;
}
//Backspace
else if(e.getSource()==bt18)
{
int len=tf.getText().trim().length();
if(len>1)
{
tf.setText(tf.getText().trim().substring(0, len-1));
flag=0;
}
else if(len==1)
{
tf.setText("0");
}
}
//数字键=
else if (e.getSource()==bt16)
{
System.out.println(flag);
switch(flag)
{
case 1:
if(tf.getText().trim().indexOf('=')==-1)
{
str=tf.getText().trim();
int gy=str.indexOf('+');
if(str.length()-gy>1)
{
y=Double.valueOf(str.substring(gy+1));
result=x+y;
tf.setText(str+"="+String.valueOf(result));
break;
}
}
case 2:
if(tf.getText().trim().indexOf('=')==-1)
{
str=tf.getText().trim();
int gy=str.indexOf('-');
if(str.length()-gy>1)
{
y=Double.valueOf(str.substring(gy+1));
result=x-y;
tf.setText(str+"="+String.valueOf(result));
break;
}
}
case 3:
if(tf.getText().trim().indexOf('=')==-1)
{
str=tf.getText().trim();
int gy=str.indexOf('*');
if(str.length()-gy>1)
{
y=Double.valueOf(str.substring(gy+1));
result=x*y;
tf.setText(str+"="+String.valueOf(result));
break;
}
}
case 4:
if(tf.getText().trim().indexOf('=')==-1)
{
str=tf.getText().trim();
int gy=str.indexOf('/');
if(str.length()-gy>1)
{
y=Double.valueOf(str.substring(gy+1));
if(y==0)
{
tf.setText("除数不能为零");
break;
}
else
{
result=x/y;
tf.setText(str+"="+String.valueOf(result));
break;
}
}
}
}
}
}
@Override
public void keyPressed(KeyEvent e)
{
int keyNum=e.getKeyCode();
//数字键0
if(keyNum==96)
{
if(tf.getText().trim().indexOf('=')==-1)
{
if(tf.getText().equals("0"))
{}
else
{
tf.setText(tf.getText().trim()+String.valueOf(e.getKeyCode()-96).trim());
}
}
}
//数字键1
else if(keyNum==97)
{
if(tf.getText().trim().indexOf('=')==-1)
{
if(tf.getText().equals("0"))
{
tf.setText(String.valueOf(e.getKeyCode()-96).trim());
//tf.setFocusable(true);
}
else
{
tf.setText(tf.getText().trim()+String.valueOf(e.getKeyCode()-96).trim());
//tf.setFocusable(true);
}
}
}
//数字键2
else if(keyNum==98)
{
if(tf.getText().trim().indexOf('=')==-1)
{
if(tf.getText().equals("0"))
{
tf.setText(String.valueOf(e.getKeyCode()-96).trim());
}
else
{
tf.setText(tf.getText().trim()+String.valueOf(e.getKeyCode()-96).trim());
}
}
}
//数字键3
else if(keyNum==99)
{
if(tf.getText().trim().indexOf('=')==-1)
{
if(tf.getText().equals("0"))
{
tf.setText(String.valueOf(e.getKeyCode()-96).trim());
}
else
{
tf.setText(tf.getText().trim()+String.valueOf(e.getKeyCode()-96).trim());
}
}
}
//数字键4
else if(keyNum==100)
{
if(tf.getText().trim().indexOf('=')==-1)
{
if(tf.getText().equals("0"))
{
tf.setText(String.valueOf(e.getKeyCode()-96).trim());
}
else
{
tf.setText(tf.getText().trim()+String.valueOf(e.getKeyCode()-96).trim());
}
}
}
//数字键5
else if(keyNum==101)
{
if(tf.getText().trim().indexOf('=')==-1)
{
if(tf.getText().equals("0"))
{
tf.setText(String.valueOf(e.getKeyCode()-96).trim());
}
else
{
tf.setText(tf.getText().trim()+String.valueOf(e.getKeyCode()-96).trim());
}
}
}
//数字键6
else if(keyNum==102)
{
if(tf.getText().trim().indexOf('=')==-1)
{
if(tf.getText().equals("0"))
{
tf.setText(String.valueOf(e.getKeyCode()-96).trim());
}
else
{
tf.setText(tf.getText().trim()+String.valueOf(e.getKeyCode()-96).trim());
}
}
}
//数字键7
else if(keyNum==103)
{
if(tf.getText().trim().indexOf('=')==-1)
{
if(tf.getText().equals("0"))
{
tf.setText(String.valueOf(e.getKeyCode()-96).trim());
}
else
{
tf.setText(tf.getText().trim()+String.valueOf(e.getKeyCode()-96).trim());
}
}
}
//数字键8
else if(keyNum==104)
{
if(tf.getText().trim().indexOf('=')==-1)
{
if(tf.getText().equals("0"))
{
tf.setText(String.valueOf(e.getKeyCode()-96).trim());
}
else
{
tf.setText(tf.getText().trim()+String.valueOf(e.getKeyCode()-96).trim());
}
}
}
//数字键9
else if(keyNum==105)
{
if(tf.getText().trim().indexOf('=')==-1)
{
if(tf.getText().equals("0"))
{
tf.setText(String.valueOf(e.getKeyCode()-96).trim());
}
else
{
tf.setText(tf.getText().trim()+String.valueOf(e.getKeyCode()-96).trim());
}
}
}
//数字键+
else if(keyNum==107)
{
if(flagk==2||flagk==3||flagk==4)
{
flagk=1;
}
else
{
flagk=1;
if(tf.getText().trim().indexOf('+')==-1)
{
x=Double.valueOf(tf.getText().trim());
tf.setText(tf.getText().trim()+"+");
y=0d;
}
else
{
tf.setText(tf.getText().trim());
}
}
}
//数字键-
else if(keyNum==109)
{
if(flagk==1||flagk==3||flagk==4)
{
flagk=2;
}
else
{
flagk=2;
if(tf.getText().trim().indexOf('-')==-1)
{
x=Double.valueOf(tf.getText().trim());
tf.setText(tf.getText().trim()+"-");
y=0d;
}
else
{
tf.setText(tf.getText().trim());
}
}
}
//数字键*
else if(keyNum==106)
{
if(flagk==1||flagk==2||flagk==4)
{
flagk=3;
}
else
{
flagk=3;
if(tf.getText().trim().indexOf('*')==-1)
{
x=Double.valueOf(tf.getText().trim());
tf.setText(tf.getText().trim()+"*");
y=0d;
}
else
{
tf.setText(tf.getText().trim());
}
}
}
//数字键/
else if(keyNum==111)
{
if(flagk==1||flagk==2||flagk==3)
{
flagk=4;
}
else
{
flagk=4;
if(tf.getText().trim().indexOf('/')==-1)
{
x=Double.valueOf(tf.getText().trim());
tf.setText(tf.getText().trim()+"/");
y=0d;
}
else
{
tf.setText(tf.getText().trim());
}
}
}
//键Backspace
else if(keyNum==8)
{
int len=tf.getText().trim().length();
if(len>1)
{
tf.setText(tf.getText().trim().substring(0, len-1));
flagk=0;
}
else if(len==1)
{
tf.setText("0");
}
tf.setFocusable(true);
}
//回车键
else if(keyNum==10)
{
switch(flagk)
{
case 1:
if(tf.getText().trim().indexOf('=')==-1)
{
str=tf.getText().trim();
int gy=str.indexOf('+');
if(str.trim().length()-gy>1)
{
y=Double.valueOf(str.substring(gy+1));
result=x+y;
tf.setText(str+"="+String.valueOf(result));
break;
}
}
case 2:
if(tf.getText().trim().indexOf('=')==-1)
{
str=tf.getText().trim();
int gy=str.indexOf('-');
if(str.trim().length()-gy>1)
{
y=Double.valueOf(str.substring(gy+1));
result=x-y;
tf.setText(str+"="+String.valueOf(result));
break;
}
}
case 3:
if(tf.getText().trim().indexOf('=')==-1)
{
str=tf.getText().trim();
int gy=str.indexOf('*');
if(str.trim().length()-gy>1)
{
y=Double.valueOf(str.substring(gy+1));
result=x*y;
tf.setText(str+"="+String.valueOf(result));
break;
}
}
case 4:
if(tf.getText().trim().indexOf('=')==-1)
{
str=tf.getText().trim();
int gy=str.indexOf('/');
if(str.trim().length()-gy>1)
{
y=Double.valueOf(str.substring(gy+1));
if(y==0)
{
tf.setText("除数不能为零");
break;
}
else
{
result=x/y;
tf.setText(str+"="+String.valueOf(result));
break;
}
}
}
}
}
}
@Override
public void keyReleased(KeyEvent arg0)
{
// TODO Auto-generated method stub
}
@Override
public void keyTyped(KeyEvent arg0)
{
// TODO Auto-generated method stub
}
}
在javax.swing包中,定义了两种类型的组件:顶层容器(JFrame,JApplet,JDialog和JWindow)和轻量级组件。Swing组件都是AWT的Container类的直接子类和间接子类
组件从功能上分可分为:
1) 顶层容器:JFrame,JApplet,JDialog,JWindow共4个
2) 中间容器:JPanel,JScrollPane,JSplitPane,JToolBar
3) 特殊容器:在GUI上起特殊作用的中间层,如JInternalFrame,JLayeredPane,JRootPane.
4) 基本控件:实现人际交互的组件,如Jbutton, JComboBox, JList, JMenu, JSlider, JtextField。
5) 不可编辑信息的显示:向用户显示不可编辑信息的组件,例如JLabel, JProgressBar, ToolTip。
6) 可编辑信息的显示:向用户显示能被编辑的格式化信息的组件,如JColorChooser, JFileChoose, JFileChooser, Jtable, JtextArea。
JComponent类的特殊功能又分为:
1) 边框设置:使用setBorder()方法可以设置组件外围的边框,使用一个EmptyBorder对象能在组件周围留出空白。
2) 双缓冲区:使用双缓冲技术能改进频繁变化的组件的显示效果。与AWT组件不同,JComponent组件默认双缓冲区,不必自己重写代码。如果想关闭双缓冲区,可以在组件上施加setDoubleBuffered(false)方法。
3) 提示信息:使用setTooltipText()方法,为组件设置对用户有帮助的提示信息。
4) 键盘导航:使用registerKeyboardAction( ) 方法,能使用户用键盘代替鼠标来驱动组件。JComponent类的子类AbstractButton还提供了便利的方法--用setMnemonic( )方法指明一个字符,通过这个字符和一个当前L&F的特殊修饰共同激活按钮动作。
5) 可插入L&F:每个Jcomponent对象有一个相应的ComponentUI对象,为它完成所有的绘画、事件处理、决定尺寸大小等工作。 ComponentUI对象依赖当前使用的L&F,用UIManager.setLookAndFeel( )方法可以设置需要的L&F.
6) 支持布局:通过设置组件最大、最小、推荐尺寸的方法和设置X、Y对齐参数值的方法能指定布局管理器的约束条件,为布局提供支持。