前言:
我们继续接着前面的内容来继续学习
高级GUI组件设计
Java采用委托事件模型来处理事件。当事件产生时,通过注册的监听器对象的Listener接口的事件处理方法来进行处理。然而,当一个Listener接口有多个处理方法(例如:鼠标事件有按下鼠标按钮、释放鼠标按键、单机鼠标按键)时,则不管是否需要,必须实现所有方法,这样下去会造成资源的浪费,并使系统开销加大。为了解决此类问题,Java语言为这些Listener接口提供了适配器类(Adapter),事件适配器(EventAdapter)为我们提供了一种简单的处理手段。当事件源注册了含有多个处理方法的监听器对象时,可以通过继承事件所对应的Adapter类,重写所需要的方法,而不需要的方法则不用重写,这样就可以缩短程序代码的编写。
KeyEvent事件及其响应:
KeyEvent事件
能触发KeyEvent事件的动作是键盘操作,所以简称为键盘操作。KeyEvent事件有三种:两个低级事件(按下(Pressed)和释放键(Released))和一个高级事件(键按下并释放(按键被敲击,Typed))。
键盘事件的响应
package 测试;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class test extends JApplet
{
String s,s1;
JLabel lb1=new JLabel("请按键盘");
JLabel lb2=new JLabel("复制结果");
//用来输入文字
JTextField tf1=new JTextField(10);
//用来显示文件内容
JTextArea tf2=new JTextArea(5,10);
Container cp=getContentPane();
FlowLayout flow=new FlowLayout(FlowLayout.CENTER,5,5);
public void init()
{
cp.setLayout(flow);
cp.add(lb1);
cp.add(tf1);
cp.add(lb2);
cp.add(tf2);
tf1.addKeyListener(new koLis());
}
//继承了一个事件适配器的类,对应的监听器是KeyListener
//这里是一个Java嵌套类
class koLis extends KeyAdapter
{
//只要有键入就会触发
public void keyTyped(KeyEvent e)
{
//获取文本框的内容及键入的字符
s=tf1.getText()+e.getKeyChar();
//若按回车键,则将文本框的内容送入文本域
if(e.getKeyChar()=='\n')
{
//文本域中已经有的文字再加上新的
s1=tf2.getText()+s;
tf1.setText("");
tf2.setText(s1);
}
}
}
}
MouseEvent事件及其响应
MouseEvent事件是低级事件,在任何组件上都可以触发该事件。组件上触发MouseEvent事件的动作是鼠标操作。MouseEvent事件分为两类:
- 使用MouseListener接口处理的鼠标事件。awt.Event类的MouseListener接口能够监听的5种鼠标事件是:按下鼠标按键、释放鼠标按键、单机鼠标按键(按下并释放)、鼠标光标进入或离开组件几何形状的未遮掩部分
- 使用MouseMotionListener接口处理的鼠标移动事件。awt.Event类的MouseMotionListener接口能够监听的两种鼠标移动的事件是:移动鼠标和拖动鼠标事件
package 测试;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class test extends JApplet
{
int x,y;
JLabel lb1=new JLabel("X:"),lb2=new JLabel("Y:"),lb3=new JLabel("");
JTextField tf1=new JTextField(5),tf2=new JTextField(5);
Container cp=getContentPane();
FlowLayout flow=new FlowLayout(FlowLayout.CENTER,5,5);
public void init()
{
cp.setLayout(flow);
cp.add(lb1);
cp.add(tf1);
cp.add(lb2);
cp.add(tf2);
cp.add(lb3);
addMouseListener(new mouseListener());
addMouseMotionListener(new koLis());
}
//此适配器类监听鼠标各种信息情况
class mouseListener extends MouseAdapter
{
public void mouseClicked(MouseEvent e)
{
lb3.setText("点击鼠标");
}
public void mousePressed(MouseEvent e)
{
lb3.setText("鼠标按钮按下");
}
public void mouseExited(MouseEvent e)
{
lb3.setText("鼠标不在窗口");
}
public void mouseReleased(MouseEvent e)
{
lb3.setText("鼠标按钮松开");
}
}
//此监听器监听移动情况
class koLis implements MouseMotionListener
{
public void mouseMoved(MouseEvent e)
{
x=e.getX();
y=e.getY();
tf1.setText(String.valueOf(x));
tf2.setText(String.valueOf(y));
}
public void mouseDragged(MouseEvent e)
{
lb3.setText("拖动鼠标");
}
}
}
WindowsEvent事件及其响应
在JFrame容器上,如果用户打开或关闭容器,则可以触发WindowEvent事件。 WindwoEvent事件是低级事件,可以设计打开、关闭、激活、停用、图标化或取消图标化JFrame容器的操作来产生WindowEvent事件。
package 测试;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class test
{
JLabel lb1=new JLabel("这是第一个窗口");
JLabel lb2=new JLabel("这是第二个窗口");
public static void main(String [] arg)
{
test t=new test();
}
public test()
{
//创建JFrame对象
JFrame f1=new JFrame();
JFrame f2=new JFrame();
//创建JFrame的容器对象,获得ContentPane
Container cp=f1.getContentPane();
Container cp1=f2.getContentPane();
f1.setTitle("JFrame1");
f2.setTitle("JFrame2");
f1.setSize(150,100);
f2.setSize(150,100);
cp.add(lb1);
//设置窗口可见
f1.setVisible(true);
cp1.add(lb2);
f2.setVisible(true);
f1.addWindowListener(new WinLis());
f2.addWindowListener(new WinLis());
}
//Window事件适配器
class WinLis extends WindowAdapter
{
//打开窗口
public void windowOpen(WindowEvent e)
{
}
//设置窗口成为活动窗口
public void windowActivated(WindowEvent e)
{
}
//设置窗口成为非活动窗口
public void windowDeactivated(WindowEvent e)
{
}
//窗口关闭
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
//最小化窗口
public void windowIconified(WindowEvent e)
{
}
}
}
JScrollPane与JScrollBar组件:
JScollPane:
当窗口的内容大于窗口时,可以在窗口的右边和下边设置滚动条,借助于滚动条就可以看到整个窗口的内容。JScrollPane就是具有这种功能的组件,我们将它成为滚动窗面板,用于滚动窗口。
JScrollBar组件:
JScrollPane是由JViewPort和JScrollBar组件组成的。JViewPort组件主要是负责显示内容的区域大小;JScrollBar组件则产生窗口滚动条,让用户看到整个内容。用户使用JScrollPane组件时不会直接与JViewPort和JScrollBar组件接触,使用比较方便。但是,当想对滚动条做更细的设置时(例如,在拖动时一次滚动多少区域等),就必须了解JScrollBar所提供的功能。
AdjustmentEvent事件应用举例:
JScrollBar对象接收AdjustmentEvent事件。
示例:
package 测试;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class test
{
int r=0,g=0,b=0;
String s,s1=" ",s2=" ",s3=" ";
//声明建立滚动条的变量
JScrollBar sbr,sbg,sbb;
JLabel lb1=new JLabel("刻度:"),lb2=new JLabel(" 标签:"),lb3=new JLabel(" 调色板 "),
lbr=new JLabel("红色"),lbg=new JLabel("绿色"),lbb=new JLabel("蓝色");
public test()
{
JFrame f=new JFrame("JScrollBar");
Container cp=f.getContentPane();
Box baseBox=Box.createHorizontalBox();
cp.add(baseBox);
//创建box1
Box box1=Box.createHorizontalBox();
//给box1加两个标签
box1.add(lb1);
box1.add(lb2);
//加box1加到baseBox中
baseBox.add(box1);
//创建box3
Box box3=Box.createVerticalBox();
//将box3加入到baseBox中
baseBox.add(box3);
//设置标签颜色
lb3.setBackground(new Color(0,0,0));
//设置标签边框
lb3.setBorder(BorderFactory.createEtchedBorder());
//让组件变得不透明,使标签颜色显示出来
lb3.setOpaque(true);
lb3.setMaximumSize(new Dimension(450,200));
box3.add(lb3);
//sbr滚动条的设置
//创建水平方向滚动条对象
sbr=new JScrollBar(JScrollBar.HORIZONTAL,10,10,0,260);
//设置此滚动条拖动滚动块时的单位向量
sbr.setUnitIncrement(5);
//设置鼠标在滚动条上点击时滚动块的块增量
sbr.setBlockIncrement(10);
//注册监听器对象
sbr.addAdjustmentListener(new Dj());
//给box3添加滚动条和对应标签
box3.add(lbr);
box3.add(sbr);
//sbg滚动条的设置
sbg=new JScrollBar(JScrollBar.HORIZONTAL,10,10,0,260);
sbg.setUnitIncrement(5);
sbg.setBlockIncrement(10);
sbg.addAdjustmentListener(new Dj());
box3.add(lbg);
box3.add(sbg);
//sbb滚动条的设置
sbb=new JScrollBar(JScrollBar.HORIZONTAL,10,10,0,260);
sbb.setUnitIncrement(5);
sbb.setBlockIncrement(10);
sbb.addAdjustmentListener(new Dj());
box3.add(lbb);
box3.add(sbb);
f.pack();
f.setVisible(true);
f.addWindowListener(new WinLis());
}
class WinLis extends WindowAdapter
{
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
class Dj implements AdjustmentListener
{
@Override
public void adjustmentValueChanged(AdjustmentEvent e) {
if((JScrollBar)e.getSource()==sbr)
{
r=e.getValue();
s1="red";
}
if((JScrollBar)e.getSource()==sbg)
{
g=e.getValue();
s2="green";
}
if((JScrollBar)e.getSource()==sbb)
{
b=e.getValue();
s3="blue";
}
s=s1+r+" "+s2+g+" "+s3+b;
lb2.setText(s);
lb3.setBackground(new Color(r,g,b));
}
}
public static void main(String[] arg)
{
test t=new test();
}
}
JTabbedPane容器:
当界面上需要放置的组件很多时,可以使用的另一个容器是JTabbedPane。JTabbedPane容器与我们日常使用的卡片盒相似,它由多个称为标签框架的卡片和表明该框架的标签组成。每个标签框架和标签都自成一个系统(也可以称为一张卡片),我们可以在标签框架中加入各式各样的组件和功能。由于这些卡片被叠放在一起,为了使用方便,卡片上的标签在顶行或底部排成一行(也可以在左边或右边排成一列),当用鼠标点击某一个标签时,这个标签所在的卡片(标签框窗口)就会被翻到最上面,显示出此框架的内容
示例:
package 测试;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class test extends JFrame
{
//创建JTabblePane对象,并指定标签显示在上方
JTabbedPane jtab=new JTabbedPane(JTabbedPane.TOP);
//声明JScrollPane的引用变量
JScrollPane sp;
public static void main(String args[])
{
test f=new test();
f.setTitle("JTabbedPane对象的应用");
f.setSize(300,300);
f.setVisible(true);
}
public test()
{
//声明标签的数组
JLabel lb[]=new JLabel[6];
//声明图片对象的引用变量
Icon pic;
//声明标签名称对象的引用变量
String title;
String p;
for(int i=1;i<=5;i++)
{
p="/image/"+"00"+i+".jpg";
//获取图片
pic=new ImageIcon(getClass().getResource(p));
//创建JLabel对象
lb[i]=new JLabel();
//设定JLabel图标
lb[i].setIcon(pic);
//设定标签名称
title="第 "+String.valueOf(i)+" 页";
//将JLabel对象加入jtab的对象中
jtab.add(title,lb[i]);
}
//将jtab对象加入到窗口中
getContentPane().add(jtab);
int v=ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED;
int h=ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED;
//创建JScrollPane对象,并加载jtab对象
sp=new JScrollPane(jtab,v,h);
getContentPane().add(sp);
//注册监听器
addWindowListener(new WinLis());
}
class WinLis extends WindowAdapter
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
}
}
菜单设计:
菜单和工具可提供简单明了的指示说明,使用户顺利地完成软件的操作。菜单是非常重要的GUI组件,是软件中必备的组件之一,Java语言提供了多种多样的菜单,如一般式、复选框式、快捷键式及弹出框式等,这里仅介绍一般式菜单。
在Java中一个一般式菜单由菜单栏(JMenuBar)、菜单(JMenu)和菜单项(JMenuItem)三类对象组成。
菜单栏
菜单栏(JMenuBar)用来封装与菜单相关的各项操作,它只是用来管理菜单,不参与交互式操作。Java应用程序中的菜单都包含在一个菜单栏对象之中,
菜单
菜单(JMenu)是用来存放和整合菜单项(JMenuItem)的组件,它是构成一个菜单栏不可或缺的组件之一。菜单可以是单一层次的结构,也可以是一个多层次的结构,具体使用何种形式的结构取决于界面设计的需要。
菜单项
菜单项(JMenuItem)是用来封装与菜单项相关的操作,它是菜单系统中最基本的组件。
接下来我们来看个制作菜单的示例:
package 测试;
import javax.swing.*;
import java.awt.BorderLayout;
import java.awt.event.*;
public class test extends JFrame
{
JTextArea tf=new JTextArea();
//创建JMenuBar对象
JMenuBar bar=new JMenuBar();
//创建JMenu对象
JMenu menu=new JMenu("文件");
//创建JMenuItem对象
JMenuItem newf=new JMenuItem("新建");
JMenuItem open=new JMenuItem("打开");
JMenuItem close=new JMenuItem("关闭");
JMenuItem quit=new JMenuItem("退出");
public test()
{
//设定JFrame的标签
//这里是手动给父类的构造函数传了个参数
//一般子类创建对象都会调用父类的无参构造函数
super("test");
//创建JFrame的容器对象
getContentPane().add(new JScrollPane(tf));
//设置文本区域为不可编辑
tf.setEditable(false);
//设置bar为不透明,若设置bar为透明,则在选择菜单时会有残影存留在JMenuBar上
bar.setOpaque(true);
//加入bar到JFrame上
setJMenuBar(bar);
//加入JMenuItem对象到menu上
menu.add(newf);
menu.add(open);
menu.add(close);
//在JMenu中加入一条分割线
menu.addSeparator();
menu.add(quit);
//将menu加载到bar上
bar.add(menu);
//注册监听器
newf.addActionListener(new Ac());
open.addActionListener(new Ac());
close.addActionListener(new Ac());
quit.addActionListener(new Ac());
addWindowListener(new WinLis());
}
class Ac implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
if(e.getSource()==newf) tf.setText("新建");
if(e.getSource()==open) tf.setText("打开");
if(e.getSource()==close) tf.setText("关闭");
if(e.getSource()==quit) System.exit(0);
}
}
class WinLis extends WindowAdapter
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
}
public static void main(String[] args)
{
JFrame f=new test();
f.setSize(400,200);
//设置窗口可见
f.setVisible(true);
}
}
对话框设计
对话框(Dialog),也就类似于c++那边的messagebox,是一种特殊的窗体,通过一个或多个组件与用户交互。
与JFrame一样,对话框有边缘、有标题且独立存在的容器,并且不能被其他容器所包容,但是对话框不能作为程序的最外层容器,也不能包含菜单条,此外,Java的对话框上没有最大化和最小化按钮。
Java提供了 JDialog 和 JOptionPane 两类对话框组件。
JOptionPane
JOptionPane提供了许多现成的对话框样式,用户只需使用该类提供的静态方法,指定方法中所需要的参数,JOptionPane对话框就能轻易地显示出来。
可将JOptionPane类的对话框分为4种类型,分别只是给出提示信息的Message Dialog、要求用户进行确认的Confirm Dialog、可输入数据的Input Dialog、和由用户自己定义类型的Option Dialog。
示例展示Message Dialog:
package 测试;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class test implements ActionListener
{
JFrame f=null;
public test()
{
f=new JFrame("OptionPane Demo");
Container cp=f.getContentPane();
cp.setLayout(new GridLayout(2,2));
JButton bt=new JButton("Show Error Icon");
bt.addActionListener(this);
cp.add(bt);
bt=new JButton("Show Warning Icon");
bt.addActionListener(this);
cp.add(bt);
bt=new JButton("Show Plain Icon");
bt.addActionListener(this);
cp.add(bt);
bt=new JButton("Show User Define Icon");
bt.addActionListener(this);
cp.add(bt);
//调整此窗口的大小
f.pack();
//可视
f.setVisible(true);
f.addWindowListener(new WinLis());
}
class WinLis extends WindowAdapter
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
}
public static void main(String []args) {
new test();
}
@Override
public void actionPerformed(ActionEvent e) {
String cmd=e.getActionCommand();
//对话框标题名
String title="Message Dialog";
String message="";
//指定信息类型
int type=JOptionPane.PLAIN_MESSAGE;
if(cmd.equals("Show Error Icon")) {
type=JOptionPane.ERROR_MESSAGE;
message="Error Message";
}else if(cmd.equals("Show Warning Icon")) {
type=JOptionPane.WARNING_MESSAGE;
message="Warning Message";
}else if(cmd.equals("Show Plain Icon")) {
type=JOptionPane.PLAIN_MESSAGE;
message="Plain Message";
}else if(cmd.equals("Show User Define Icon")) {
type=JOptionPane.PLAIN_MESSAGE;
//输出设置图标的信息对话框
JOptionPane.showMessageDialog(f, message,title,type,new ImageIcon("/image/001.jpg"));
return;
}
//输出未设图标的信息对话框
JOptionPane.showMessageDialog(f, message,title,type);
}
}
实现可输入的对话框(Input Dialog):
package 测试;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class test implements ActionListener
{
JFrame f=null;
JLabel lb=null;
public test()
{
f=new JFrame("OptionPane Demo");
Container cp=f.getContentPane();
//面板
JPanel pa=new JPanel();
pa.setLayout(new GridLayout(2,1));
//给Panel加入两个按钮
JButton bt=new JButton("Show Text Input");
bt.addActionListener(this);
pa.add(bt);
bt=new JButton("Show ComboBox Input");
bt.addActionListener(this);
pa.add(bt);
lb=new JLabel("",JLabel.CENTER);
//在JFrame容器中,上面加上标签(标签很窄),下面加上Panel面板
cp.add(lb,BorderLayout.NORTH);
cp.add(pa,BorderLayout.CENTER);
f.pack();
f.setVisible(true);
f.addWindowListener(new WinLis());
}
class WinLis extends WindowAdapter{
public void WindowClosing(WindowEvent e) {
System.exit(0);
}
}
public static void main(String[] arge) {
new test();
}
@Override
public void actionPerformed(ActionEvent e) {
String cmd=e.getActionCommand();
String title="Input Dialog";
String message="您最喜欢哪一种编程语言";
int messageType=JOptionPane.QUESTION_MESSAGE;
String[] values= {"VB","C++","JAVA","ASP"};
String result="";
if(cmd.equals("Show Text Input")) {
result=JOptionPane.showInputDialog(f,message,title,messageType);
}else if(cmd.equals("Show ComboBox Input")) {
result=(String)JOptionPane.showInputDialog(f,message,title,
messageType,null,values,values[0]);
}
if(result==null)
lb.setText("您取消了对话框");
else
lb.setText("您输入:"+result);
}
}
JDialog对话框
如果JOptionPane提供的样式无法满足我们的需求,就需要使用JDialog来自行设计对话框。用JDialog来制作对话框时,必须制作对话框中的每一个组件,所以比较麻烦。但是,当我们想要了解对话框的更多细节时,还是有必要学习用JDialog来制作对话框的过程的。事实上,当使用JOptionPane时,系统会自动产生JDialog组件,并将JOptionPane的内容放入JDialog的ContentPane中,而不需要我们介入。
需要说一下的是,在JDialog的初始方法中有一个这样的构造方法:
JDialog(Frame owner,String title,boolean modal)
表中的modal是对话框的操作模式,可分为模态和非模态两种,用modal参数的true与false表示。当modal为true,则称为模态对话框,它要求用户在应用程序继续执行之前必须对该对话框进行响应,关闭对话框后才能回到原来的应用程序继续执行。当false时,则称为非模态对话框,非模态对话框则无上述要求。
使用JDialog与JFrame非常类似,要加入组件到JDialog上必须先取得JDialog的ContentPane,然后再把组件加到此ContentPane中
示例:
package 测试;
import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;
public class test implements ActionListener
{
String s1=" ";
JFrame f=null;
JLabel lb=new JLabel("对话框示例:");
//声明对话框中的文本框引用变量
JTextField tf1,tf2;
//声明对话框引用变量
JDialog dialog;
public test()
{
f=new JFrame("对话框示例");
Container cp=f.getContentPane();
JPanel pa=new JPanel(new GridLayout(3,1));
pa.add(lb);
JButton bt=new JButton("进入对话框");
bt.addActionListener(this);
pa.add(bt);
bt=new JButton("结束");
bt.addActionListener(this);
pa.add(bt);
pa.setBorder(BorderFactory.createTitledBorder(
BorderFactory.createLineBorder(Color.blue,3),
"对话框示例",TitledBorder.CENTER,TitledBorder.TOP));
cp.add(pa,BorderLayout.CENTER);
f.pack();
f.setVisible(true);
f.addWindowListener(new WinLis());
}
class WinLis extends WindowAdapter{
public void WindowClosing(WindowEvent e) {
System.exit(0);
}
}
@Override
public void actionPerformed(ActionEvent e) {
String cmd=e.getActionCommand();
if(cmd.equals("进入对话框")) {
//在该方法中创建对话框
dial();
}else if(cmd.equals("结束")) {
System.exit(0);
}
//对话框中的按钮事件
if(cmd.equals("确定")) {
}else if(cmd.equals("返回")) {
s1=tf1.getText();
s1=s1+tf2.getText();
lb.setText(s1);
dialog.dispose();
}
}
public static void main(String[] args) {
new test();
}
public void dial() {
//创建对话框对象(模态)
dialog=new JDialog(f,"进入对话框",true);
//创建对话框的容器对象
Container diacp=dialog.getContentPane();
//设置所创建对话框的容器的布局
JLabel lb1=new JLabel("输入学号:");
JLabel lb2=new JLabel("输入姓名:");
//面板布局为3行2列
JPanel pa1=new JPanel(new GridLayout(3,2));
tf1=new JTextField(8);
tf2=new JTextField(8);
pa1.add(lb1);
pa1.add(tf1);
pa1.add(lb2);
pa1.add(tf2);
JButton bt1=new JButton("确定");
pa1.add(bt1);
bt1=new JButton("返回");
bt1.addActionListener(this);
pa1.add(bt1);
//对话框的容器放入上述面板
diacp.add(pa1);
//设置对话框的容器的大小
dialog.setBounds(150,150,200,150);
//将对话框变为可见
dialog.setVisible(true);
}
}
小插曲:
截止这里终于把Java的UI设计记录完了,后面就是学习多线程、网络、数据库了
异常处理
异常处理机制
Java的异常处理机制用于及时有效地处理程序运行中的异常情况,Java引入了异常和异常类,并且定义了很多异常类,每个异常类代表一类运行错误,类中包含了该运行错误的信息和处理错误的方法等内容。每当Java程序运行过程中发生一个可识别的运行错误时,系统都会产生一个相应异常类的对象,并由系统中相应的机制来处理,以确保不会产生死机、死循环或其他对操作系统有损害的结果,从而保证了整个程序运行的安全性。
在Java程序中,当程序运行过程中发生异常时,可采用两种方法来处理:
- 程序被终止并显示一些错误信息给用户
- 使用Java语言提供的 try-catch-finally 语句自行处理异常
第二种方法的优点很多,其中最主要的优点是将处理异常的代码与程序代码的主线分离开,增强了程序的可读性;其次是可减少中途终止程序运行的可能性。
我们来看一个程序自动抛出异常
package 测试;
public class test{
public static void main(String[] args) {
int a,b,c;
a=67;
b=0;
c=a/b;
System.out.println(a+"/"+b+"="+c);
}
}
终端输出:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at 测试.test.main(test.java:7)
异常类的继承:
在Java语言中所有的异常类都继承自java.lang.Throwable类。Throwable类有两个直接子类:一个是Error子类,它包含Java系统或执行环境中所发生的异常,这些异常是用户无法捕捉到的;另一个是Exception类,它包含了一般性的异常,例如I/O异常、SQL异常,这些异常是用户可以捕捉到的(我们的try-catch就是要抓这一类的异常),可以通过产生它的子类来创建自己的异常处理
系统定义的运行异常Error类中,除AWTError类在java.awt包中外,其余的全部在java.lang包中
异常处理语句:
try-catch-finally语句
结构如下
try {
//可能发生异常的语句
statements
}
catch(ExceptionType1 ExceptionObject) {
//处理异常的程序代码1
Exception Handing
}
catch(ExceptionType2 ExceptionObject) {
//处理异常的程序代码2
Exception Handing
}
.
.
.
finally {
//无论是否发生异常都要执行的程序代码
Finally Handing
}
我们接下来来看一个示例:
package 测试;
public class test{
public static void main(String args[]) {
int a,b,c;
a=67;
b=0;
try {
int x[]=new int[-5];
c=a/b;
System.out.println(a+"/"+b+"="+c);
}
catch(NegativeArraySizeException e) {
System.out.println("异常:"+e.getMessage());
//在命令行打印异常信息在程序中出错的位置及原因
e.printStackTrace();
}
catch(ArithmeticException e) {
System.out.println("b=0:"+e.getMessage());
}
finally {
System.out.println("End");
}
}
}
输出:
异常:null
java.lang.NegativeArraySizeException
End
at 测试.test.main(test.java:8)
printStackTrace的输出是有可能混乱的,原因如下:
printStackTrace()默认使用了System.err输出流进行输出,与System.out是两个不同的输出流,那么在打印时自然就形成了交叉。还有就是输出流是有缓冲区的,所以对于什么时候具体输出也形成了随机。
我们再来看一个嵌套异常的示例:
package 测试;
public class test{
static int a,b,c;
public static void main(String args[]) {
try {
a=10;
b=0;
try {
c=a/b;
System.out.println("a/b="+c);
}
//但是改程序其实并没有这个异常
catch(IndexOutOfBoundsException E) {
System.out.println("捕捉超出索引异常……");
}
finally {
System.out.println("嵌套内层的finally区块");
}
}
catch(ArithmeticException E) {
System.out.println("捕捉数学运算异常,b="+b);
}
finally {
System.out.println("嵌套外层的finally区块");
if(b==0) {
System.out.println("程序执行发生异常!");
}
else {
System.out.println("程序正常执行完毕");
}
}
}
}
输出:
嵌套内层的finally区块
捕捉数学运算异常,b=0
嵌套外层的finally区块
程序执行发生异常!
抛出异常的throw与throws语句
throw
package 测试;
public class test{
public static void main(String[] args) {
try {
throw new NullPointerException("自编异常");
}
catch(NullPointerException e) {
System.out.println("异常:"+e);
}
}
}
异常:java.lang.NullPointerException: 自编异常
throws
在有些情况下,不需要一个方法本身来处理异常,而是希望把异常向上移交给调用这个方法的方法来处理,此时,就可以用throws语句。
throws的语句格式如下:
returnType methodName(para1,para2,……) throws exception
示例:
package 测试;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JApplet;
public class test extends JApplet{
static void throwOne() throws IllegalAccessException{
throw new IllegalAccessException("自编异常");
}
public void paint(Graphics g) {
Graphics2D g2=(Graphics2D)g;
try {
throwOne();
}
catch(IllegalAccessException e) {
g2.drawString("发生异常"+e, 20,20);
}
}
}
博客:is-hash.com
商业转载 请联系作者获得授权,非商业转载 请标明出处,谢谢