第二节 基本容器:JFrame
如果要使用Swing创建一个窗口,则直接使用JFrame即可,此类事Component类的子类,常用方法如下:
小试牛刀 创建一个简单的窗口
import java.awt.*;
import java.io.*;
import javax.swing.*;
public class JavaSwingTest {
public static void main(String args[]) throws IOException{
test1();
}
//创建一个新的窗体
public static void test1(){
JFrame f=new JFrame("第一个Swing窗口");//实例化窗体对象
f.setSize(230,80);//设置窗体大小
f.setBackground(Color.WHITE);//设置窗体的背景颜色
f.setLocation(1000,600);//设置窗体的显示位置
f.setVisible(true);//让组建显示
}
效果:
以上最重要的是f.setVisible(true);如果没有这一步,窗体就不会显示。是不是有点小激动,其实这没什么,后面还有很多。
在JFrame中也可以使用Dimension类设置窗体的大小,此类封装的组件显示高度和宽度,Dimension常用方法如下:
除了设置组件大小可以使用Dimension类,对于组件的显示位置也存在一个Point类,此类封装的是现实位置X,Y坐标。Point类常用的方法如下:
说明:所谓组件大小以及组件的显示位置是这样布局的
实例:
//使用Dimension和Point类设置组件大小和显示位置
public static void test2(){
JFrame f=new JFrame("第一个Swing窗口");
Dimension d=new Dimension();//实例化Dimension对象
d.setSize(400,200);
f.setSize(d);
f.setBackground(Color.WHITE);
Point p=new Point();//实例化Point对象
p.setLocation(300,200);
f.setLocation(p);
f.setVisible(true);
}
调用该方法运行后效果如下:
实例:
//使用Dimension和Point类设置组件大小和显示位置
public static void test2(){
JFrame f=new JFrame("第一个Swing窗口");
Dimension d=new Dimension();//实例化Dimension对象
d.setSize(400,200);
f.setSize(d);
f.setBackground(Color.WHITE);
Point p=new Point();//实例化Point对象
p.setLocation(300,200);
f.setLocation(p);
f.setVisible(true);
}
调用该方法运行后效果如下:
标签组件:JLabel
JLabel组件表示的是一个标签,本身是用于显示信息的,创建完的Label对象可以通过Container类中的add方法加入到容器中,JLabel常用方法如下:
实例:
//使用一个标签JLable
public static void test3(){
JFrame f=new JFrame("Welcome to 密讯");
Dimension d=new Dimension();//实例化Dimension对象
JLabel lab=new JLabel("MichaelLee",JLabel.CENTER);
f.add(lab);
d.setSize(400,200);
f.setSize(d);
f.setBackground(Color.WHITE);
Point p=new Point();//实例化Point对象
p.setLocation(300,200);
f.setLocation(p);
f.setVisible(true);
}
运行后效果:
以上的标签内容只是使用了默认的字体以及颜色,如果现在要更改字体则可以使用Component类中定义的方法:
Public void setFont();
Font类常用方法如下:
//更改JLabel的文字样式,设置标签的显示字体,大小,背景颜色
public static void test4(){
JFrame f=new JFrame("Welcome to 密讯");
Dimension d=new Dimension();//实例化Dimension对象
JLabel lab=new JLabel("MichaelLee",JLabel.CENTER);
Font font=new Font("隶书",Font.ITALIC+Font.BOLD,28);
lab.setForeground(Color.RED);
lab.setFont(font);
f.add(lab);
d.setSize(400,200);
f.setSize(d);
f.setBackground(Color.WHITE);
Point p=new Point();//实例化Point对象
p.setLocation(300,200);
f.setLocation(p);
f.setVisible(true);
}
运行效果如下
:
可以发现,标签的字体类型以及颜色都发生了变化
如果不知道本机的字体样式,可以使用一下方法得到本机的字体样式:
//取得本机中全部可用的字体
public static void GetAllFonts(){
//取得本地的绘图设备和字体集合
GraphicsEnvironment eq=GraphicsEnvironment.getLocalGraphicsEnvironment();
//取得全部可用字体
String []fontName=eq.getAvailableFontFamilyNames();
for(int i=0;i<fontName.length;i++){
if(i%10==0)
System.out.println("");
System.out.print(fontName[i]+"; ");
}
}
由于内容太多这里只截取部分:
如果我们想直接将一个图像设置到JLabel中也是可以的,不过要使用Icon接口以及ImageIcon子类,ImageIcon类常用方法如下:
下面我们先使用InputStream类完成操作:
//在JLabel中设置图片
public static void test5() throws IOException{
JFrame f=new JFrame("Welcome to MichaelLee!");
String picPath="E:"+File.separator+"李超图片"+File.separator+"sunyanzi.jpg";
File file=new File(picPath);
InputStream inputStream=new FileInputStream(file);
Dimension d=new Dimension();//实例化Dimension对象
byte b[]=new byte[(int)file.length()];
inputStream.read(b);
inputStream.close();
Icon icon=new ImageIcon(b);
JLabel lab=new JLabel("MichaelLee",icon,JLabel.CENTER);
Font font=new Font("隶书",Font.ITALIC+Font.BOLD,28);
lab.setForeground(Color.RED);//设置标签的文字颜色
lab.setBackground(Color.YELLOW);//设置标签的背景颜色
lab.setFont(font);
f.add(lab);
d.setSize(800,400);
f.setSize(d);
f.setBackground(Color.WHITE);
Point p=new Point();//实例化Point对象
p.setLocation(300,200);
f.setLocation(p);
f.setVisible(true);
}
效果如下:
从上例可以看出,使用一个IO流来完成操作很麻烦,那么可以直接将一个图片的路径传递到ImageIcon的实例化对象中,如下所示:
//另一种ImageIcon的用法
public static void test6(){
JFrame f=new JFrame("Welcome to MichaelLee!");
String picPath="E:"+File.separator+"李超图片"+File.separator+"sunyanzi.jpg";
Icon icon=new ImageIcon(picPath,"我喜欢孙燕姿!");//实例化对象,直接加入路径
JLabel lab=new JLabel("MichaelLee",icon,JLabel.CENTER);
Font font=new Font("隶书",Font.ITALIC+Font.BOLD,28);
lab.setForeground(Color.RED);//设置标签的文字颜色
lab.setBackground(Color.YELLOW);//设置标签的背景颜色
lab.setFont(font);
f.add(lab);
Dimension d=new Dimension();//实例化Dimension对象
d.setSize(800,400);
f.setSize(d);
f.setBackground(Color.WHITE);
Point p=new Point();//实例化Point对象
p.setLocation(300,200);
f.setLocation(p);
f.setVisible(true);
}
效果如下:
与上面的效果一样,如果此时是一个不确定的输入流(比如从数据库中读取BLOG字段)中而来,则要使用第一种方法,若是直接从文件中而来,那么就可以使用第二种方法。
按钮组件:JButton
JButton组件是在窗体中添加一个按钮,常用方法如下:
首先建立一个普通的按钮:
//按钮组件,建立一个普通的按钮
public static void test7(){
JFrame jf=new JFrame("Welcome to MichaelLee!");
JButton jb=new JButton("按我");
jb.setBounds(100,100,200,200);
Font font=new Font("serif",Font.BOLD,28);
jb.setFont(font);
jf.add(jb);
jf.setSize(400,300);
jf.setLocation(400,400);
jf.setVisible(true);
}
效果如下:
JButton也可以为按钮设置一张图片:
//在按钮上显示图片
public static void test8(){
JFrame jf=new JFrame("Welcome to MichaelLee!");
String picPath="E:"+File.separator+"李超图片"+File.separator+"sunyanzi.jpg";
Icon icon=new ImageIcon(picPath,"我喜欢孙燕姿!");
JButton jb=new JButton(icon);
jb.setBounds(200,200,200,200);
Font font=new Font("serif",Font.BOLD,28);
jb.setFont(font);
jf.add(jb);
jf.setSize(800,600);
jf.setLocation(500,300);
jf.setVisible(true);
}
效果如下:
中间图片是一个按钮
布局管理器:
通过以上的洋里可以发现,如果不对窗体进行版面设置,则一个组建会直接充满整个窗体,所以在Java中专门提供了布局管理器来管理组件,通过布局管理器可以使用不同的方式排列组件。
在Swing中有五种常见的布局管理器:FlowLayout,BorderLayout,GridLayout,CardLayout,绝对定位。
FlowLayout:
FlowLayout属于流式布局管理器,使用此种布局会使所有的组件像流水一样一次进行排列,FlowLayout常用方法及常量如下:
ut常用方法及常量如下:
设置FlowLayout
//设置流式布局管理器FlowLayout
public static void test9(){
JFrame jf=new JFrame("Welcome to MichaelLee!");
jf.setLayout(new FlowLayout(FlowLayout.CENTER,3,3));
jf.setLocation(500,300);
JButton jb=null;
for(int i=0;i<10;i++){
jb=new JButton("按钮"+i);
jf.add(jb);
}
jf.setSize(400,400);
jf.setVisible(true);
}
运行效果:
BordLayout
BordLayout将一个窗体的版面划分成东西南北中五个区域,可以直接将需要的组件放到这五个区域中,BordLayout类的常用方法:
设置BordLayout
//设置BorderLayout
public static void test10(){
JFrame jframe=new JFrame("Welcome to MichaelLee!");
//设置窗体的布局管理器为BorderLayout,所有组件水平和垂直间距为3
jframe.setLayout(new BorderLayout(3,3));
jframe.add(new JButton("东(EAST)"),BorderLayout.EAST);
jframe.add(new JButton("西(WEST)"),BorderLayout.WEST);
jframe.add(new JButton("南(SOUTH)"),BorderLayout.SOUTH);
jframe.add(new JButton("北(NORTH)"),BorderLayout.NORTH);
jframe.add(new JButton("中(CENTER)"),BorderLayout.CENTER);
jframe.pack();//根据组件自动调整窗口大小
jframe.setVisible(true);
}
运行效果:
GridLayout
GridLayout布局管理器是以表格形式进行管理的,在使用此布局管理器时必须设置显示的行数与列数,GridLayout常用的方法
Public GridLayout(int rows,int cols) //构造一个指定行和列的布局管理器
Public GridLayout(int rows,int cols,int hgap,int vgap)//构造是指定行和列,水平和垂直间距
设置GridLayout
//设置GridLayout布局管理器
public static void test11(){
JFrame jframe=new JFrame("Welcome to MichaelLee!");
jframe.setLayout(new GridLayout(3,5,3,3));//安3*5进行排列,水平和垂直间距为3
JButton jButton=null;
for(int i=0;i<13;i++){
jButton=new JButton("按钮-"+i);
jframe.add(jButton);
}
jframe.pack();
jframe.setVisible(true);
}
运行效果:
CardLayout
CardLayout就是将一组组件彼此重叠的进行布局,就像一张卡片一样,这样每次只展现一个界面。CardLayout常用方法如下:
设置CardLayout
//设置CardLayout布局管理器
public static void test12(){
JFrame jframe=new JFrame("Welcome to MichaelLee!");
CardLayout card=new CardLayout();
jframe.setLayout(card);
jframe.add(new JLabel("标签——A",JLabel.CENTER),"First");
jframe.add(new JLabel("标签——B",JLabel.CENTER),"Second");
jframe.add(new JLabel("标签——C",JLabel.CENTER),"Third");
jframe.add(new JLabel("标签——D",JLabel.CENTER),"Fourth");
jframe.add(new JLabel("标签——E",JLabel.CENTER),"Fifth");
jframe.pack();
jframe.setVisible(true);
card.show(jframe.getContentPane(),"Third");
for(int i=0;i<5;i++){
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
card.next(jframe.getContentPane());
}
}
界面会一个个的显示,且显示顺序如图所示
绝对定位
如果不想在窗体中设置布局管理器,也可以通过设置绝对坐标来完成,Component中提供了setBounds方法,可以定位一个组建的坐标,此方法定义如下:
Public void setBounds(int x,int y,int width,int height);
使用绝对布局
//使用绝对定位排版
public static void test13(){
JFrame jframe=new JFrame("Welcome to MichaelLee!");
jframe.setLayout(null);
JLabel title=new JLabel("MichaelLee!");
JButton enter=new JButton("enter");
JButton help=new JButton("help");
title.setBounds(45,5,150,20);
enter.setBounds(10, 30,80,20);
help.setBounds(100,30,80,20);
jframe.setSize(300,400);
jframe.add(title);
jframe.add(enter);
jframe.add(help);
jframe.setVisible(true);
}
效果如下:
使用绝对定位有一点好处就是不管窗体如何改变大小,组件的位置是固定不变的,而之前的各种布局方式,当窗体大小改变时,组件大小也会改变。