1.创建框架
AWT中Frame类用来描述顶层窗口,在Swing中,这个类的名为JFrame,它从Frame类扩展。
JFrame是少数几个在Swing不用绘制在画布上的组件之一,因此,它的修饰部件(按钮、标题栏、图标等)由用户的窗口系统绘制。
import java.awt.EventQueue; import javax.swing.JFrame; public class SimpleFrameTest { public static void main(String[] args) { EventQueue.invokeLater(new Runnable(){ public void run (){ SimpleFrame frame = new SimpleFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } }); } } class SimpleFrame extends JFrame{ private static final int DEFAULT_WIDTH = 300; private static final int DEFAULT_HEIGHT = 200; public SimpleFrame (){ setSize(DEFAULT_WIDTH,DEFAULT_HEIGHT); } }
效果为一个空的框架。
首先,所有的Swing组件必须由事件分派线程进行配置,线程将鼠标点击和按键控制转移到用户接口组件。
下面的代码片段是事件分派线程中的执行代码:
EventQueue.invokeLater(new Runnable(){ public void run (){ statement } });
许多Swing程序没有在事件分派线程中初始化用户界面。在主线程中完成初始化是通常采用的方式。
所以写成这种方式也行
public static void main(String[] args) { SimpleFrame frame = new SimpleFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); }
但由于Swing组件十分复杂,无法保证这种方式的安全。所以不用。
2.框架定位
JFrame类本身只包含若干个改变框架外观的方法。当然,通过继承,从JFrame的各个超类中继承了许多用于处理框架大小和位置的方法。其中最重要的有下面几个:
setLocation 和 setBounds 方法用于设置框架的位置。(对于框架来说是相对于整个屏幕的位置)
setIconImage 用于告诉窗口系统在标题栏、任务切换窗口等位置显示哪个图标。
setTitle 用于改变标题栏的文字。
setLocationByPlatform 设置窗口下次可见时应该出现的位置:本机窗口系统的默认位置,还是当前位置
setResizable 利用一个boolean值确定框架的大小是否允许用户改变。
JFrame类的继承层次 | |
|
对于专业的应用程序来说,应该检查屏幕的分辨率,并根据分辨率编写代码重置框架的大小。
得到屏幕大小的步骤:
1、调用Toolkit类的静态方法getDefaultToolkit得到一个Toolkit对象(Toolkit类包含很多与本地窗口系统打交道的方法)
2、调用getScreenSize方法,这个方法以Dimension对象的形式返回屏幕的大小。Dimension对象同事用公有实例变量width和height保存着屏幕的宽度和高度。
代码如下:
public class FrameAutoChange { public static void main(String[] args) { EventQueue.invokeLater(new Runnable(){ public void run (){ JFrame frame = new JFrame(); frame.setTitle("这是一个例子"); Toolkit kit = Toolkit.getDefaultToolkit(); Dimension screenSize = kit.getScreenSize(); int screenWidth = screenSize.width; int screenHeight = screenSize.height; //将框架大小调整为屏幕长宽的一半 frame.setSize(screenWidth/2, screenHeight/2); frame.setLocationByPlatform(true); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } }); } }
本例生成一个长宽均为屏幕一半的窗口。
如果框架中只包含标准的组件,如按钮和文本框,那么可以通过调用pack方法设置框架大小。框架将被设置为刚好能够放置所有组件的大小。在通常情况下,将程序的主框架设置为最大:frame.setExtendedState(Frame.MAXIMIZED_BOTH); //全屏
如果编写一个使用多个显示屏幕的应用程序,应该利用GraphicsEnvironment和Graphics Device类获得显示屏幕的大小
常用方法:
java.awt.Component
boolean isVisible()
void setVisible(boolean b) //设置visible属性
void setSize(int wideh , int height) //使用给定的宽度和高度,重新设置组件的大小
void setLocation(int x, int y ) //将组件移到一个新的位置上,如果这个组件不是顶层组件,x和y坐标是容器坐标,否则是屏幕坐标
voidee setBounds(int x , int y,int width , int height) //移动并重新设置组件大小
Dimension getSize()
void setSize(Dimension d)
java.awt.Window
void toFront() //将这个窗口显示在其他窗口前面
void toBack() //将这个窗口移到桌面窗口栈的后面,并重新排列所有的可见窗口
boolean isLocaionByPlatform()
void setLocationByPlatform(boolean b) //设置locationByPlatform属性。这个属性在窗口显示之前被设置,由平台选择一个合适的位置
java.awt.Frame
boolean isResizale()
void setResizable(boolean b) //获取或设置resizable属性。这个属性设置后,用户可以重新设置框架的大小。
String getTitle()
void setTitle(String s) //获取或设置title属性,这个属性确定框架标题栏中的文字void getIconImage()
void setIconImage(Image image)//获取或设置iconImage属性,这个属性确定框架的图标,窗口系统可能会将图标作为框架装饰或其他部位的一部分显示。
boolean isUndecorated()
void setUndecorated(boolean b) //获取或设置undecorated属性。这个属性设置后,框架显示中没有标题栏或关闭按钮这样的装饰.
int getExtendedState()
void setExtendedState(int state)
获取或设置窗口状态。状态为下列值之一:
Frame.NORMAL
Frame.ICONIFIED
Frame.MAXIMIZED_HORIZ
Frame.MAXIMIZED_VERT
Frame.MAXIMIZED_BOTH
java.swt.Toolkit
static Toolkit getDefaultToolkit() 返回默认的工具箱
Dimension getScreenSize() //返回用户屏幕尺寸
javax.swing.ImageIcon
ImageIcon(String filename) 构造一个图标,其图像存储在一个文件中
Image getImage() 获得该图标的图像
3.在组件中显示信息
可以将字符直接绘制到框架中,这不是一种好习惯。框架是用来放组件的容器,可以将菜单栏和其他用户界面元素放置在其中。在通常情况下,应该在另一组件中绘制信息,并将组件添加到框架中。
JFrame中有四层面板,其中的根面板、层级面板、玻璃面板人们不太关心,他们是用来组织菜单栏和内容窗格以及实现观感的。Swing程序员最关心的是内容窗格。在设计框架的时候,要使用下列代码将所有的组件添加到内容窗格中:
Container contentPane = frame.getContentPane(); Component c = ...; contentPane.add(c);
在之前版本中JFrame类中的add方法抛出一个异常:"Do not use JFrame.adde() .Use JFrame.getContentPane().add instead",Java SE5.0不再提示,只是调用内容窗格的add.
绘制一个组件,需要定义一个扩展JComponent的类,并覆盖其中的paintComponent方法 。
paintComponent方法有一个Graphics类型的参数,这个参数保存着用于绘制图像和文本的设置,如字体、当前颜色。在Java中,所有的绘制必须使用Graphics对象,其中包含了绘制图案、图像、文本的方法。
下列代码给出了如何创建一个能够进行绘制的组件:
class MyComponent extends JComponent{ public void paintComponent(Graphics g){ //code for drawing } }
只要窗口需要重新绘图,事件处理器会通告组件,从而引发执行所有组件的paintComponent方法。
一定不要自己调用paintComponent方法。(如果需要强制刷新平幕,需要调用repaint方法,而不是paintComponent方法)
触发这个自动响应的过程:如用户扩大窗口、极小化窗口,后恢复窗口的大小时会引发重新绘图。用户弹出另一个窗口,此窗口覆盖了已经存在的窗口,被覆盖的窗口不可见,则需重新绘制。
public class MyPane { public static final int DEFAULT_WIDTH= 300; public static final int DEFAULT_HEIGHT =200; public static void main(String[] args) { JFrame frame = new JFrame(); MyComponent mcomp = new MyComponent(); frame.add(mcomp); frame.setSize(DEFAULT_WIDTH,DEFAULT_HEIGHT); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } } class MyComponent extends JComponent{ public static final int MESSAGE_X=75; public static final int MESSAGE_Y =100; public void paintComponent(Graphics g){ //code for drawing g.drawString("Test program!!!!!!", MESSAGE_X,MESSAGE_Y); } }
也可扩展JPanel。JPanel是一个可以包含其他组件的容器,同样可以再其上进行绘制。有一点不同之处是,面板不透明,这意味着要在面板的边界内绘制所有的像素。最容易的实现方法是,在每个面板子类的paintComponent方法中调用super.paintComponent来用背景色绘制面板
class MyPanel extends JPanel{ public static final int MESSAGE_X=75; public static final int MESSAGE_Y =100; public void paintComponent(Graphics g){ //code for drawing super.paintComponent(g); g.drawString("Test panel program!!!!!!", MESSAGE_X,MESSAGE_Y); } }
效果:框架上的面板显示字符串:Test panel program!!!!!!