Root Pane Container(二)

8.2 JFrame类

JFrame类是使用JRootPane并且实现了RootPaneContainer接口的Swing高层容器。另外,他使用WindowConstants接口来帮助管理相关操作。

8.2.1 创建JFrame

JFrame类提供了两个基本构造函数:一个用于不带标题的框架,而另一个用来创建带标题的框架。还有另外两个构造函数使用特定的GraphicsConfiguration来创建框架。

public JFrame()
JFrame frame = new JFrame();
 
public JFrame(String title)
JFrame frame = new JFrame("Title Bar");
 
public JFrame(GraphicsConfiguration config)
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gsd[] = ge.getScreenDevices();
GraphicsConfiguration gc[] = gsd[0].getConfigurations();
JFrame frame = new JFrame(gc[0]);
 
public JFrame(String title, GraphicsConfiguration config)
GraphicsConfiguration gc = ...;
JFrame frame = new JFrame("Title Bar", gc);

8.2.2 JFrame属性

表8-5显示了JFrame的九个属性。

JFrame属性

属性名
数据类型

访问性

accessibleContext
AccessibleContext

只读

contentPane
Container

读写

defaultCloseOperation
int

读写

glassPane
Component

读写

iconImage
Image

只写

jMenuBar
JMenuBar

读写

layeredPane
JLayeredPane

读写

layout
LayoutManager

只写

rootPane
JRootPane

只读

尽管大多数的属性都是实现RootPaneContainer接口的结果,但是有两个特殊的属性:defaultCloseOperation以及layout。(我们首先在第2章看到了defaultCloseOperation。)默认情况下,当用户关闭容器时,JFrame会隐藏自己。要修改这种设置,当设置默认关闭行为时我们可以表8-6中所列表出的常量来作为参数。第一个直接来自于JFrame;其他的则是WindowConstants接口的一部分。

aFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

关闭操作常量

常量

描述

EXIT_ON_CLOSE

调用System.exit(0)

DISPOSE_ON_CLOSE

在窗体上调用dispose()

ON_NOTHING_ON_CLOSE

忽略请求

HIDE_ON_CLOSE

在窗体上调用setVisible(false);这是默认行为

layout属性是比较奇特的。默认情况下,设置JFrame的布局管理器会将调用传递给内容面板。我们不可以修改JFrame的默认布局管理器。

JFrame还有另外一个静态属性:defaultLookAndFeelDecorated。这个属性与JRootPane的windowDecorationStyle属性结合使用。当设置为true时,新创建的窗体会使用观感中的装饰而不是窗口管理中的装饰进行装饰。当然,只有当前的观感支持窗口装饰时才会发生这种情况。列表8-2显示了另一种创建与图8-2相同的屏幕的方法(通过使用Metal观感所提供的窗口装饰)。

package swingstudy.ch08;
 
import java.awt.EventQueue;
 
import javax.swing.JFrame;
 
public class AdornSample2 {
 
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
 
		Runnable runner = new Runnable() {
			public void run() {
				JFrame.setDefaultLookAndFeelDecorated(true);
				JFrame frame = new JFrame("Adornment Sample");
				frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				frame.setSize(300,200);
				frame.setVisible(true);
			}
		};
 
		EventQueue.invokeLater(runner);
	}
 
}

8.2.3 向JFrame添加组件

因为JFrame实现了RootPaneContainer接口并且使用JRootPane,我们不能直接向JFrame添加组件。相反,我们将组件添加到JFrame所包含的JRootPane。在J2SE 5.0之前,我们需要使用下面的方法来添加组件:

JRootPane rootPane = aJFrame.getRootPane();
Container contentPane = rootPane.getContentPane();
contentPane.add(...);

这可以用下面的语句进行简化:

aJFrame.getContentPane().add(...);

如果我们尝试直接向JFrame添加组件,则会抛出运行时错误。

由于许多建议(或是抱怨?),Sun最终决定将add()方法修改为代理:

aJFrame.add(...);

使用J2SE 5.0时,当我们向JFrame添加组件时,他们实际上被添加到了RootPaneContainer的内容面板。

8.2.4 处理JFrame事件

JFrame类支持11种不同的监听器的注册:

  • ComponentListener:确定窗体何时移动或修改尺寸
  • ContainerListener:通常并不添加到JFrame,因为我们将组件添加到其JRootPane的内容面板。
  • FocusListener:确定窗体何时获得或是失去输入焦点。
  • HierarchyBoundsListener:确定窗体何时移动或是修改尺寸。其作用与ComponentListener类似,因为窗体是组件的顶层容器。
  • HierarchyListener:确定窗体何时显示或隐藏。
  • InputMethodListener:用于国际化时与输入法结合使用。
  • KeyListener:通常并不添加到JFrame。相反,我们为其内容面板注册一个键盘动作,如下所示:
JPanel content = (JPanel)frame.getContentPane();
KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
content.registerKeyboardAction(actionListener, stroke, 
  JComponent.WHEN_IN_FOCUSED_WINDOW);

  • MouseListener与MouseMotionListener:用于监听鼠标以及鼠标动作事件。
  • PropertyChangeListener:用来监听绑定属性的改变。
  • WindowListener:来确定窗口何时被图标化或是取消图标化或是用户正在尝试打开或关闭窗口。

通过defaultCloseOperation属性,我们通常并不需要添加WindowListener来帮助处理关闭窗体或是停止程序。

8.2.5 扩展JFrame

如果我们需要扩展JFrame,这个类有两个重要的protected方法:

protected void frameInit()
protected JRootPane createRootPane()

通过在子类中重写这些方法,我们可以自定义初始外观以及窗体或是其JRootPane的行为。例如,在列表8-3中所示的ExitableJFrame类的例子中,默认的关闭操作被初始化EXIT_ON_CLOSE状态。无需要为每一个创建的窗体调用setDefaultCloseOperation()方法,我们可以使用这个类进行替换。因为JFrame被继承,我们并不需要在其构造函数中添加frameInit()方法的调用。其父类自动调用这个方法。

package swingstudy.ch08;
 
import javax.swing.JFrame;
 
public class ExitableFrame extends JFrame {
 
	public ExitableFrame() {
 
	}
 
	public ExitableFrame(String title) {
		super(title);
	}
 
	protected void frameInit() {
		super.frameInit();
		setDefaultCloseOperation(EXIT_ON_CLOSE);
	}
}

注意:如果我们重写JFrame的frameInit()方法,记住首先调用super.frameInit()来初始化其默认行为。如果我们忘记了并没有自己重新实现所有的默认行为,我们的新窗体的外观与行为就会不同。

该程序允许用户比较摄氏和华氏温度的相等性。具体要求如下: 建立一个Temperature类,它有两个实例变量:一个是温度值(float);另一个是温度的计量单位(char),即取值 ’C’ 或 ’F’,C表示Celsius(摄氏温度)、F表示Fahrenheit(华氏温度)。这个类还应有2 个构造方法: 给每一个实例变量设置缺省值,即温度值为0、计量单位为C(摄氏); 通过两个参数分别给两个实例变量赋初值。 这个类应包括: 两个存取方法:一个返回用摄氏计量的温度、另一个返回华氏温度。摄氏和华氏温度的转换公式如下: degreesC = 5 * (degreesF - 32)/9 degreesF = (9* (degreesC)/5) + 32 三个改变对象属性的方法:一个设置温度值、一个设置计量单位(’F’或’C’)、另一个同时设置温度值和计量单位。 三个比较方法:一个用来是否两个温度相等;一个方法用来测试比较一个温度大于另一个温度;一个方法用来测试比较一个温度小于另一个温度。 最后写一个测试程序(main方法),测试Temperature类中的所有方法。要确保使用到所用的构造方法;要测试每一个比较方法,并确保至少有一个真(true)一个假(false)的结果。例如测试:0.0 degrees C = 32.0 degrees F -40.0 degrees C = - 40.0 degrees F -100.0 degrees C = 212.0 degrees F 请注意:必须保证输入的数据是有效的。所有非法的输入字符都应产生相应的错误信息并提示用户重新输入正确的数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值