资源描述
1,第9章 图形用户界面,郑 莉,JAVA语言程序设计,2,目录,9.1 Applet 概述 9.2 Applet应用程序接口 9.3 绘图 9.4 Swing基础 9.5 Swing的特点和概念 9.6 Swing组件 9.7 其它Swing特性 9.8 本章小结 (说明:本章部分例题出自java_tutorial_sun),3,9.1 Applet 概述,Java Applet 一种嵌入HTML文档中的Java程序 与Application相比,Applet具有明显的优点 web浏览器提供了运行Applet所需要的许多功能 Applet是在运行时通过网络从服务器端下载的,因而便于软件的发布和及时更新 Applet也有其局限性, 不能在客户机上读写当地文件 也不能连接除它所在的服务器以外的其它机器,4,在浏览器中加载一个Applet,功能是显示一个字符串“This is a Java Applet!” import java.awt.Graphics; import javax.swing.JApplet; public class Ex9_1 extends JApplet public void paint(Graphics g) /重载JApplet类的paint方法 /参数是Graphics类的对象,是由浏览器传递过来的 super.paint(g); /调用其超类JApplet类的paint方法 g.drawString(This is a Java Applet!,25,25); ,9.1 Applet概述(续) 例9_1,Applet概述,5,在NetBeans IDE中运行,9.1 Applet概述(续) 例9_1运行结果,Applet概述,6,编译ex9_1.java产生字节码文件ex9_1.class。接下来就需要编写一个HTML文件ex9_1.html来嵌入ex9_1.class 将ex9_1.html文件和Ex9_1.class文件放在同一个目录下。现在,在浏览器中打开这个HTML文件,当浏览器遇到Applet标记时,就会自动载入指定的class文件,就会实现在屏幕上绘制一串字符的效果,9.1 Applet概述(续) 例9_1运行结果,Applet概述,7,9.2 Applet应用程序接口,JApplet类 一个applet程序需要继承javax.swing包中的JApplet类,也可以继承老的AWT组件中的Applet类, JApplet类属于新的Swing组件 提供了applet在浏览器中运行需要具备的特定方法 浏览器载入时,要依次运行init、start、paint方法 离开浏览器页面时,执行stop 退出浏览器时,执行destroy 提供了所有这些方法的默认实现,所以我们在编写自己的applet时,就可以不必写出全部方法,只要继承这个JApplet,然后重写特定的方法来增加特殊功能,8,9.2 Applet应用程序接口,Applet应用程序接口,9,9.2 Applet应用程序接口(续),Applet应用程序接口,10,import javax.swing.*;. import java.awt.*; public class HelloSwingApplet extends JApplet public void init() JLabel label = new JLabel( You are successfully running a Swing applet!); label.setHorizontalAlignment(JLabel.CENTER); label.setBorder(BorderFactory.createMatteBorder( 1,1,2,2,Color.black); getContentPane().add(label, BorderLayout.CENTER); ,9.2 Applet应用程序接口(续) HelloSwingApplet.java,Applet应用程序接口,11,9.3 绘图,图形环境和图形对象 颜色和字体 使用Graphics类绘图 使用Graphics2D类绘图,12,9.3.1 图形环境和图形对象,坐标 GUI组件的左上角坐标默认为(0,0) 从左上角到右下角,水平坐标x和垂直坐标y增加。 坐标的单位是象素 Graphics对象 Graphics对象是专门管理图形环境的。Graphics类是一个抽象类 设计一个抽象类Graphics可以给程序员提供一个与平台无关的绘图接口,因而程序员就可以以独立于平台的方式来使用图形。在各个平台上实现的Java系统将创建Graphics类的一个子类,来实现绘图功能,但是这个子类对程序员是透明的,也就是说我们只能看得到Graphics类,却不必关心其实现 在执行paint方法时,系统会传递一个指向特定平台的Graphics子类的图形对象g,绘 图,13,9.3.2 颜色和字体,Java中有关颜色的类是Color类,它在java.awt包中,这个类声明了用于操作Java程序中颜色的方法和常量,绘 图,14,9.3.2 颜色和字体,Font类有关字体控制,在java.awt包中,绘 图,15,9.3.3 使用Graphics类绘图,Graphics类 其对象可以绘制文本、线条、矩形、多边形、椭圆、弧等多种图形,绘 图,18,用各种颜色绘制文字及各种图形 import java.awt.*; import javax.swing.*; public class Ex9_2 extends JFrame public Ex9_2() super( “演示字体、颜色、绘图” ); /调用基类构造方法 setSize( 480, 250 ); /设置窗口大小 setVisible( true ); /显示窗口 public void paint( Graphics g ) super.paint( g ); / call superclasss paint method g.setFont( new Font( SansSerif, Font.BOLD, 12 ) ); g.setColor(Color.blue); /设置颜色 g.drawString(字体ScanSerif,粗体,12号,蓝色,20,50);,9.3.3 使用Graphics类绘图(续) Ex9_2.java,绘 图,19,g.setFont( new Font( Serif, Font.ITALIC, 14 ) ); g.setColor(new Color(255,0,0); g.drawString( 字体Serif,斜体,14号,红色, 250, 50 ); g.drawLine(20,60,460,60); /绘制直线 g.setColor(Color.green); g.drawRect(20,70,100,50); /绘制空心矩形 g.fillRect(130,70,100,50); /绘制实心矩形 g.setColor(Color.yellow); g.drawRoundRect(240,70,100,50,50,50); /绘制空心圆角矩形 g.fillRoundRect(350,70,100,50,50,50); /绘制实心圆角矩形 g.setColor(Color.cyan); g.draw3DRect(20,130,100,50,true); /绘制突起效果空心矩形 g.fill3DRect(130,130,100,50,false); /绘制凹陷效果实心矩形,9.3.3 使用Graphics类绘图(续) Ex9_2.java,绘 图,20,g.setColor(Color.pink); g.drawOval(240,130,100,50); /绘制空心椭圆 g.fillOval(350,130,100,50); /绘制实心椭圆 g.setColor(new Color(0,120,20); g.drawArc(20,190,100,50,0,90); /绘制一段圆弧 g.fillArc(130,190,100,50,0,90); /绘制扇形 g.setColor(Color.black); int xValues=250,280,290,300,330,310,320,290,260,270; int yValues=210,210,190,210,210,220,230,220,230,220; g.drawPolygon(xValues,yValues,10); /绘制空心多边形 int xValues2=360,390,400,410,440,420,430,400,370,380; g.fillPolygon(xValues2,yValues,10); /绘制实心多边形 ,9.3.3 使用Graphics类绘图(续) Ex9_2.java,绘 图,21,public static void main( String args ) JFrame.setDefaultLookAndFeelDecorated(true); /设置窗口的外观感觉为Java默认 Ex9_2 application = new Ex9_2(); application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE ); 运行结果,9.3.3 使用Graphics类绘图(续) Ex9_2.java运行结果,绘 图,22,9.3.4 使用Graphics2D类绘图,Java2D API 提供了高级的二维图形功能 分布在java.awt、java.awt.image、java.awt.color、java.awt.font、java.awt.geom、java.awt.print和java.awt.image.renderable包中 它能轻松使你完成以下功能: 绘制任何宽度的直线 用渐变颜色和纹理来填充图形 平移、旋转、伸缩、切变二维图形,对图像进行模糊、锐化等操作 构建重叠的文本和图形,绘 图,23,Graphics2D类 要想使用Java2D API,就必须通过一个该类的对象 是Graphics类的抽象子类 事实上,所有的paint方法用于绘图操作的对象实际上是Graphics2D的一个子类实例,该实例传递给paint方法,并被向上转型为Graphics类的实例。要访问Graphics2D功能,必须使用如下语句将传递给paint方法的Graphics引用强制转换为Graphics2D引用: Graphics2D g2d=(Graphics2D)g,9.3.4 使用Graphics2D类绘图(续),绘 图,24,实现例9_1的功能,使用Java2D使文字出现渐变色效果 import java.awt.*; import javax.swing.*; public class Ex9_3 extends JApplet public void paint(Graphics g) super.paint(g); Graphics2D g2d=(Graphics2D)g; g2d.setPaint(new GradientPaint(0,0,Color.red,180,45,Color.yellow); g2d.drawString(This is a Java Applet!,25,25); ,9.3.4 使用Graphics2D类绘图(续) Ex9_3.java,绘 图,25,9.3.4 使用Graphics2D类绘图(续) Ex9_3.java运行结果,绘 图,26,9.4 Swing基础,前面介绍了如何在屏幕上绘制普通的图形,但如果需要绘制一个按钮,并使其可以对点击事件作出响应,就需要使用java Swing提供的组件 其实前面我们已经用到的JFrame、JApplet都是Swing组件,它们分别代表窗口组件和Applet容器组件,27,9.4.1 JFC与Swing,JFC Java Foundation Classes(Java基础类)的缩写 是关于GUI 组件和服务的完整集合 作为J2SE 的一个有机部分,主要包含5 个部分 AWT Java2D Accessibility Drag import java.awt.event.*; import javax.swing.*; public class Ex9_4 extends JApplet public void init() Container contentPane=getContentPane(); contentPane.setLayout(new GridLayout(2,1); JButton button=new JButton(Click me); final JLabel label=new JLabel(); contentPane.add(button); contentPane.add(label); button.addActionListener( new ActionListener() public void actionPerformed(ActionEvent event) String information=JOptionPane.showInputDialog(请输入一串字符); label.setText(information); );/创建监听器语句结束 /init方法结束 ,9.4.3在Applet和Application中应用Swing (续) Ex9_4.java,Swing 基础,32,9.4.3在Applet和Application中应用Swing (续) Ex9_4.java运行结果,Swing 基础,33,把JApplet换成JFrame,将例9-4的程序改为Application import javax.swing.*; import java.awt.event.*; import java.awt.*; public class Ex9_5 public static void main(String args) JFrame f=new JFrame(“Simple Swing Application”); Container contentPane=f.getContentPane(); contentPane.setLayout(new GridLayout(2,1); JButton button=new JButton(Click me); final JLabel label=new JLabel(); contentPane.add(button);/添加按钮 contentPane.add(label);/添加标签 button.addActionListener( new ActionListener() public void actionPerformed(ActionEvent event) String information=JOptionPane.showInputDialog(请输入一串字符); label.setText(information); ); f.setSize(200,100);/设置大小 f.show();/显示 f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); ,9.4.3在Applet和Application中应用Swing (续) Ex9_5.java,Swing 基础,34,9.4.3在Applet和Application中应用Swing (续) Ex9_5.java运行结果,Swing 基础,35,9.5 Swing的特点和概念,Swing GUI 组件 javax.swing包 源于AWT(package java.awt)的组件 包括外观和感觉 外观以及用户如何和程序交互 轻量级组件 完全用Java写成,不是用当前平台的GUI功能 某些Swing组件也是重量级的,外观和功能受到本地窗口系统的限制,如 java.awt.Windows的子类 java.applet.Applet的子类,36,9.5.1 Swing的组件和容器层次,绝大多数Swing组件的继承层次,Swing 的特点和概念,37,9.5.1 Swing的组件和容器层次(续),JComponent类是除了顶层容器以外所有Swing组件的基类,根据继承关系,我们可以在每个基类中找到大多数GUI组件的常见操作 Component 类 包含paint、repaint方法,可以在屏幕上绘制组件 大多数GUI组件直接或间接扩展Component Container 类 容纳相关组件 包括add方法,用来添加组件 包括setLayout方法,这个方法可用来设置布局,以帮助Container对象对其中的组件进行定位和设置组件大小 JComponent 类多数Swing组件的超类 可抽换的外观和感觉,即可根据需求定制外观和感觉。 快捷键 (通过键盘直接访问GUI组件) 一般的事件处理功能,Swing 的特点和概念,38,通常将javax.swing包里的Swing组件归为三个层次 顶层容器 中间层容器 原子组件,9.5.1 Swing的组件和容器层次(续),Swing 的特点和概念,39,顶层容器 Swing提供三个顶层容器的类 JFrame 实现单个主窗口 JDialog 实现一个二级窗口(对话框) JApplet 在浏览器窗口中实现一个applet显示区域 必须和操作系统打交道,所以都是重量级组件 从继承结构上来看,它们分别是从原来AWT组件的Frame、Dialog和Applet类继承而来 每个使用Swing组件的Java程序都必须至少有一个顶层容器,别的组件都必须放在这个顶层容器上才能显现出来,9.5.1 Swing的组件和容器层次(续) 顶层容器,Swing 的特点和概念,40,中间层容器 其存在的目的仅仅是为了容纳别的组件 分为两类 一般用途的 JPanel JScrollPane JSplitPane JTabbedPane JToolBar 特殊用途的 JInternalFrame JRootPane 可以直接从顶层容器中获得一个JRootPane对象来直接使用,而别的中间容器使用的时候需要新建一个对象,9.5.1 Swing的组件和容器层次(续) 中间层容器,Swing 的特点和概念,41,原子组件 通常是在图形用户界面中和用户进行交互的组件 基本功能是和用户交互信息,而不像前两种组件那样是用来容纳别的组件的 根据功能的不同,可被分为三类 显示不可编辑信息的JLabel、JProgressBar、JToolTip 有控制功能、可以用来输入信息的JButton、JCheckBox、JRadioButton、JComboBox、JList、JMenu、JSlider、JSpinner、JTexComponent等 能提供格式化的信息并允许用户选择的JColorChooser、JFileChooser、JTable、JTree,9.5.1 Swing的组件和容器层次(续) 原子组件,Swing 的特点和概念,42,三层容器结构示例 import javax.swing.*; import java.awt.*; public class Ex9_6 public static void main(String args) JFrame.setDefaultLookAndFeelDecorated(true); JFrame frame=new JFrame(Swing Frame); Container contentPane=frame.getContentPane(); JPanel panel=new JPanel(); panel.setBorder(BorderFactory.createLineBorder(Color.black,5); panel.setLayout(new GridLayout(2,1); JLabel label=new JLabel(Label,SwingConstants.CENTER); JButton button=new JButton(Button); panel.add(label); panel.add(button); contentPane.add(panel); frame.pack();/对组件进行排列 frame.show();/显示 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); ,9.5.1 Swing的组件和容器层次(续) 例9_6,Swing 的特点和概念,43,程序说明 首先创建一个JFrame类顶级容器 然后获得顶级容器的内容面板contentPane,只有通过它才能加入其他组件。 然后创建一个JPanel类的中间容器panel,并设置边框以及布局 然后创建原子组件Label,button,并将它们添加到中间容器上 然后将中间容器通过内容面板添加到顶层容器上,并/对组件进行排列,9.5.1 Swing的组件和容器层次(续) 例9_6运行结果,Swing 的特点和概念,44,9.5.1 Swing的组件和容器层次(续) Swing组件列表,Swing 的特点和概念,45,9.5.2 布局管理,如何将下级组件有秩序地摆在上一级容器中 在程序中具体指定每个组件的位置 使用布局管理器(Interface LayoutManager) 布局管理器 使用方法是通过调用容器对象的setLayout方法,并以某种布局管理器对象为参数,例如: Container contentPane = frame.getContentPane(); contentPane.setLayout(new FlowLayout(); 使用布局管理器可以更容易地进行布局,而且当改变窗口大小时,它还会自动更新版面来配合窗口的大小,不需要担心版面会因此混乱,Swing 的特点和概念,46,9.5.2 布局管理(续),在Java中有很多实现LayoutManager接口的类,经常用到的有以下几个 BorderLayout FlowLayout GridLayout CardLayout GridBagLayout BoxLayout SpringLayout 上一节提到的内容面板(content pane)默认使用的就是BorderLayout,它可以将组件放置到五个区域:东、西、南、北、中,Swing 的特点和概念,47,在该例中,引用了SUN公司提供的几个的示例程序,演示了布局管理器的使用方法和效果 BorderLayoutDemo.java及其运行效果 BorderLayout以将组件放置到五个区域:东、西、南、北、中,9.5.2 布局管理(续) 例9_7,Swing 的特点和概念,48,FlowLayoutDemo.java FlowLayout是JPanel默认使用的布局管理器,它只是简单地把组件放在一行,如果容器不是足够宽来容纳所有组件,就会自动开始新的一行,9.5.2 布局管理(续) 例9_7,Swing 的特点和概念,49,GridLayoutDemo.java GridLayout将按照其构造方法中程序员提供的行数和列数将界面分为等大的若干块,组件被等大地按加载顺序放置其中,9.5.2 布局管理(续) 例9_7,Swing 的特点和概念,50,CardLayoutDemo.java CardLayout可以实现在一个区域出现不同的组件布局,就像在一套卡片中选取其中的任意一张一样。它经常由一个复选框控制这个区域显示哪一组组件,可通过组合框像选择卡片一样选择某一种布局,9.5.2 布局管理(续) 例9_7,Swing 的特点和概念,51,GridBagLayoutDemo.java GridBagLayout把组件放置在网格中,这一点类似于GridLayout,但它的优点在于不仅能设置组件摆放的位置,还能设置该组件占多少行/列。这是一种非常灵活的布局管理器,9.5.2 布局管理(续) 例9_7,Swing 的特点和概念,52,BoxLayoutDemo.java BoxLayout将组件放在单一的行或列中,和FlowLayout不同的是,它可以考虑到组件的对齐方式,最大、最小、优选尺寸,9.5.2 布局管理(续) 例9_7,Swing 的特点和概念,53,SpringDemo.java SpringLayout是一种灵活的布局管理器。它能够精确指定组件之间的间距。组件之间的距离通过Spring类的对象来表示,每个spring有四个属性,最小值,最大值,优选值和实际值。每个组件的spring对象集合在一起就构成了SpringLayout.Constraints对象,9.5.2 布局管理(续) 例9_7,Swing 的特点和概念,54,9.5.3 事件处理,GUI是由事件驱动的,一些常见的事件包括: 移动鼠标 单双击鼠标各个按钮 单击按钮 在文本字段输入 在菜单中选择菜单项 在组合框中选择、单选和多选 拖动滚动条 关闭窗口 Swing通过事件对象来包装事件,程序可以通过事件对象获得事件的有关信息,Swing 的特点和概念,55,9.5.3 事件处理(续) Swing组件的事件对象,Swing 的特点和概念,56,编写事件处理程序时,要注意三个概念 事件源 与用户进行交互的GUI组件,表示事件来自于哪个组件或对象 比如要对按钮被按下这个事件编写处理程序,按钮就是事件源 事件监听器 负责监听事件并做出响应 一旦它监视到事件发生,就会自动调用相应的事件处理程序作出响应 事件对象 封装了有关已发生的事件的信息 例如按钮被按下就是一个要被处理的事件,当用户按下按钮时,就会产生一个事件对象。事件对象中包含事件的相关信息和事件源,9.5.3 事件处理(续) 事件处理机制的三个部分,Swing 的特点和概念,57,程序员应完成的两项任务 为事件源注册一个事件监听器 实现事件处理方法,9.5.3 事件处理(续) 程序员应完成的两项任务,Swing 的特点和概念,58,事件源 提供注册监听器或取消监听器的方法 维护一个已注册的监听器列表,如有事件发生,就会通知每个已注册的监听器 一个事件源可以注册多个事件监听器,每个监听器又可以对多种事件进行相应,例如一个JFrame事件源上可以注册 窗口事件监听器,响应 窗口关闭 窗口最大化 窗口最小化 鼠标事件监听器,响应 鼠标点击 鼠标移动,9.5.3 事件处理(续) 事件源,Swing 的特点和概念,59,事件监听器 是一个对象,通过事件源的addListener方法被注册到某个事件源上 不同的Swing组件可以注册不同的事件监听器 一个事件监听器中可以包含有对多种具体事件的专用处理方法 例如用于处理鼠标事件的监听器接口MouseListener中就包含有对应于鼠标压下、放开、进入、离开、敲击五种事件的相应方法mousePressed、mouseReleased、mouseEntered、mouseExited、mouseClicked,这五种方法都需要一个事件对象作为参数,9.5.3 事件处理(续) 事件监听器,Swing 的特点和概念,60,通常我们用到的事件对象有 ActionEvent 发生在按下按钮、选择了一个项目、在文本框中按下回车键 ItemEvent 发生在具有多个选项的组件上,如JCheckBox、JComboBox ChangeEvent 用在可设定数值的拖曳杆上,例如JSlider、JProgressBar等 WindowEvent 用在处理窗口的操作 MouseEvent 用于鼠标的操作,9.5.3 事件处理(续) 事件对象,Swing 的特点和概念,61,9.5.3 事件处理(续) Swing事件源可能触发的事件及对应的事件监听器,Swing 的特点和概念,62,9.5.3 事件处理(续) Swing事件源可能触发的事件及对应的事件监听器,Swing 的特点和概念,63,9.5.3 事件处理(续) Swing事件源可能触发的事件及对应的事件监听器,Swing 的特点和概念,64,事件监听器接口 例如MouseListener是一个接口,为了在程序中创建一个鼠标事件监听器的对象,我们需要实现其所有五个方法,在方法体中,我们可以通过鼠标事件对象传递过来的信息(例如点击的次数,坐标),实现各种处理功能 事件监听器适配器类 有时我们并不需要对所有事件进行处理,为此Swing提供了一些适配器类Adapter,这些类含有所有Listener中方法的默认实现(就是什么也不做),因此我们就只需编写那些需要进行处理的事件的方法。例如,如果只想对鼠标敲击事件进行处理,如果使用MouseAdapter类,则只需要重写mouseClicked方法就可以了,9.5.3 事件处理(续) 事件监听器接口和事件监听器适配器类,Swing 的特点和概念,65,实现事件监听器接口 这种方法需要实现接口中所有的方法,对我们不需要进行处理的事件方法,也要列出来,其方法体使用一对空的花括号 继承事件监听器适配器类 只需要重写我们感兴趣的事件 使用匿名内部类 特别适用于已经继承了某个父类(例如Applet程序,主类必须继承JApplet类或Applet类),则根据java语法规则,就不能再继承适配器类的情况,而且使用这种方法程序看起来会比较清楚明了,9.5.3 事件处理(续) 三种实现事件处理的方法,Swing 的特点和概念,66,创建一窗口,当鼠标在窗口中点击时,在窗口标题栏中显示点击位置坐标。方法一:实现MouseListener接口 import java.awt.event.*; /载入MouseListener类所在的包 import javax.swing.*; /载入JFrame所在的包 public class Ex9_8_1 implements MouseListener JFrame f; public Ex9_8_1() f=new JFrame(); /新建一窗口 f.setSize(300,150); f.show(); f.addMouseListener(this); /为窗口增加鼠标事件监听器 f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); public void mousePressed(MouseEvent e) public void mouseReleased(MouseEvent e) public void mouseEntered(MouseEvent e) public void mouseExited(MouseEvent e) public void mouseClicked(MouseEvent e) f.setTitle(点击坐标为 (+e.getX()+, +e.getY public static void main(String args) new Ex9_8_1(); ,9.5.3 事件处理(续) 例9_8_1,Swing 的特点和概念,67,继承MouseAdapter类 import java.awt.event.*; /载入MouseAdapter所在的包 import javax.swing.*; public class Ex9_8_2 extends MouseAdapter JFrame f; public Ex9_8_2() f=new JFrame(); f.setSize(300,150); f.show(); f.addMouseListener(this); f.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); public void mouseClicked(MouseEvent e) f.setTitle(点击坐标为 (+e.getX()+, +e.getY()+); public static void main(String args) new Ex9_8_2(); ,9.5.3 事件处理(续) 例9_8_2,Swing 的特点和概念,68,方法三:使用匿名内部类 import java.awt.event.*; import javax.swing.*; public class Ex9_8_3 JFrame f; public Ex9_8_3() f=new JFrame(); f.setSize(300,150); f.show(); f.addMouseListener(new MouseAdapter() public void mouseClicked(MouseEvent e) f.setTitle(点击坐标为 (+e.getX()+, +e.getY()+); ); /为窗口添加鼠标事件监听器语句结束 f.addWindowListener(new WindowAdapter() public void windowClosing(WindowEvent e) System.exit(0); );/为窗口添加窗口事件监听器语句结束 public static void main(String args) new Ex9_8_3(); ,9.5.3 事件处理(续) 例9_8_3,Swing 的特点和概念,69,采用三种不同方法的程序,其运行效果都是一样的,当鼠标在窗口中点击的时候,窗口标题栏将出现所点位置的坐标信息,9.5.3 事件处理(续) 例9_8运行结果,Swing 的特点和概念,70,9.6 Swing组件,组件和容器 容器层次结构 是一个以顶层容器为根的树状组件集合 为了显示在屏幕上,每个组件必须是一套容器层次结构的一部分 每个组件只能放置在某个容器内一次 如果某个组件已经在一个容器中,又将它加到另外一个容器中,这个组件就会从第一个容器中清除,71,9.6.1 顶层容器,Swing提供了3个顶层容器类:JFrame JApplet JDialog 都是重量级组件,分别继承了AWT组件Frame、Applet和Dialog 每个顶层容器都有一个内容面板,通常直接或间接的容纳别的可视组件 可以有选择地为顶层容器添加菜单,菜单被放置在顶层容器上,但是在内容面板之外,Swing 组件,72,java.lang.Object java.awt.Component java.awt.Container java.awt.Window java.awt.Frame javax.swing.JFrame 每个包含Swing 组件的主窗口都应用JFrame 来实现,9.6.1 顶层容器(续) JFrame的继承结构,Swing 组件,73,java.lang.Object java.awt.Component java.awt.Container java.awt.Panel java.awt.Applet javax.swing.JApplet 每个包含Swing 组件的Applet 都应作为JApplet 的子类来实现,Swing 组件,9.6.1 顶层容器(续) JApplet的继承结构,74,java.lang.Object java.awt.Component java.awt.Container java.awt.Window java.awt.Dialog javax.swing.JDialog 要实现对话框,需要从JDialog派生一个类,Swing 组件,9.6.1 顶层容器(续) JDialog的继承结构,75,9.6.1 顶层容器(续) 如何获得一个顶层容器,JApplet类的顶层容器由浏览器提供,通常我们不需要自己产生一个JApplet类的对象。JFrame和JDialog通过构造方法进行创建,Swing 组件,76,9.6.1 顶层容器(续) 如何获得一个顶层容器续,Swing 组件,77,9.6.1 顶层容器(续) FrameDemo.java,import java.awt.*; import java.awt.event.*; import javax.swing.*; public class FrameDemo public static void main(String s) JFrame frame = new JFrame(FrameDemo); frame.addWindowListener(new WindowAdapter() public void windowClosing(WindowEvent e) System.exit(0); ); JLabel emptyLabel = new JLabel(); emptyLabel.setPreferredSize(new Dimension(175, 100); frame.getContentPane().add(emptyLabel, BorderLayout.CENTER); frame.pack(); frame.setVisible(true); ,Swing 组件,78,import java.awt.*; import java.awt.event.*; import javax.swing.*; public class TopLevelDemo public static void main(String s) JFrame frame = new JFrame(TopLevelDemo); frame.addWindowListener(new WindowAdapter() public void windowClosing(WindowEvent e) System.exit(0); ); JLabel yellowLabel = new JLabel(); yellowLabel.setOpaque(true); yellowLabel.setBackground(Color.yellow); yellowLabel.setPreferredSize(new Dimension(200, 180); JMenuBar cyanMenuBar = new JMenuBar(); cyanMenuBar.setOpaque(true); cyanMenuBar.setBackground(Color.cyan); cyanMenuBar.setPreferredSize(new Dimension(200, 20); frame.setJMenuBar(cyanMenuBar); frame.getContentPane().add(yellowLabel, BorderLayout.CENTER); frame.pack(); frame.setVisible(true); ,9.6.1 顶层容器(续) TopLevelDemo.java,Swing 组件,79,JDialog 必须实现对话框中的每一个组件 JOptionPane 只要显示一段文字,或是做一些简单的选择的简单对话框 在javax.swing包内 通过使用这个类提供的一些静态方法showDialog,就可以产生四种简单的对话框 它们的方法参数中绝大部分(除了输入对话框可以不指定父窗口)都需要提供一个父窗口组件ParentComponent,只有关闭这些简单的对话框后,才可以返回到其父窗口,也就是说,它们绝大部分都是模态的,9.6.1 顶层容器(续) JOptionPane类,Swing 组件,80,9.6.2 中间层容器,中间层容器存在的目的仅仅是为了容纳别的组件,它分为两类 一般用途的 JPanel JScrollPane JSplitPane JTabbedPane JToolBar 特殊用途的 JInternalFrame JRootPane(比较特殊,它由好几个部分构成,我们可以直接从顶层容器中获得一个JRootPane对象来直接使用,而不需要像别的中间容器那样,使用的时候需要新建一个对象),Swing 组件,81,JRootPane的层次结构 glassPane 默认状态下是隐藏的 可以使用glassPane来截获所有要到达JRootPane别的部分的事件 layeredPane 分为很多层(layer),每层都有一个代表层深度的整数值(Z-order),深度值高的组件将覆盖在深度值低的组件上 contentPane 所在层的深度值是-30000 一般我们将所有组件添加到contentPane上 JmenuBar 所在层的深度值是-30000 是可选的,如果没有,contentPane就会充满整个顶层容器,9.6.2 中间层容器(续) JRootPane类,Swing 组件,82,JPanel 是一种经常使用的轻量级中间容器 在默认状态下,除了背景色外它并不绘制任何东西 可以很容易的为它设置边框和绘制特性,我们可以把它设置为顶层容器contentPane。有效地利用JPanel可以使版面管理更为容易 可以使用布局管理器来规划它所容纳的组件的位置和大小 可以通过setLayout方法来改变其布局 也可以在创建一个JPanel对象时就为它确定某种布局方式。在默认状态下panel使用FlowLayout布局,将各组件布局在一行,9.6.2 中间层容器(续) JPanel类,Swing 组件,83,9.6.2 中间层容器(续) JPanel类常用API,Swing 组件,84,Converter.java 用到如下类,都放在JPanelDemo包中 ConversionPanel.java ConverterRangeModel.java DecimalField.java FollowerRangeModel.java FormattedDocument.java Unit.java,9.6.2 中间层容器(续) JPanel示例:Converter.java,Swing 组件,85,JScrollPane容器 当容器内要容纳的内容大于容器大小的时候,我们希望容器能够有一个滚动条,通过拖动滑块,就可以看到更多的内容。JScrollPane就是能够实现这种功能的特殊容器 由九个部分组成,包括一个中心显示地带、四个角和四条边,9.6.2 中间层容器(续) JScrollPane,Swing 组件,86,9.6.2 中间层容器(续) JScrollPane常用API,Swing 组件,87,9.6.2 中间层容器(续) JScrollPane常用API,Swing 组件,88,9.6.2 中间层容器(续) ScrollDemo2.java,Swing 组件,89,JSplitPane 可以把两个组件显示在两个显示区域内,且随着区域间分隔线的拖动,区域内组件的大小也随之发生变动 它允许设置水平分割或者垂直分割;也允许设置动态拖曳功能(拖动分界线时两边组件是否会随着拖曳动态改变大小还是在拖曳结束后才改动) 我们通常先把组件放到Scroll Pane中,再把Scroll Pane放到Split Pane中。这样在每部分窗口中,都可以拖动滚动条看到组件的全部内容,9.6.2 中间层容器(续) JSplitPane,Swing 组件,90,9.6.2 中间层容器(续) JSplitPane常用API,Swing 组件,91,9.6.2 中间层容器(续) JSplitPane常用API,Swing 组件,92,import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; import java.util.*; public class SplitPaneDemo implements ListSelectionListener private Vector imageNames; private JLabel picture; private JList list; private JSplitPane splitPane; public SplitPaneDemo() ResourceBundle imageResource; try /Read image names from a properties file imageResource = ResourceBundle.getBundle(imagenames); String imageNamesString = imageResource.getString(images); imageNames = parseList(imageNamesString); catch (MissingResourceException e) System.exit(1); ,9.6.2 中间层容器(续) JSplitPaneDemo.java,Swing 组件,93,list = new JList(imageNames); list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); list.setSelectedIndex(0); list.addListSelectionListener(this); JScrollPane listScrollPane = new JScrollPane(list); ImageIcon firstImage = new ImageIcon(./build/classes/+(String)imageNames.firstElement(); picture = new JLabel(firstImage); picture.setPreferre
展开阅读全文