18. JAVA 图形界面 Part 1 ----- 学习笔记

本文介绍了Java Swing GUI编程的基础概念,包括AWT与Swing的关系、组件、容器、布局管理器、事件处理、文本框组件、密码框组件、表单的建立等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本章目标:

  • 了解AWT与Swing的关系
  • 掌握组件、容器、布局管理器的概念
  • 了解JFrame、JPanel、JSplitPane、JTabbedPane、JScrollPane、JDesktopPane等常见容器
  • 了解JLabel组件、JButton组件,并可以通过设置显示文字风格及显示图像
  • 了解事件处理作用及实现机制
  • 了解文本框组件、密码框组件、文本域组件的使用
  • 了解单选按钮、复选框、列表框、下拉列表框等常见组件的使用及事件处理
  • 了解菜单组件、文件选择组件的使用
  • 了解表格的建立,并可以使用TableModel构建一个表格

        在一个系统中,一个良好的人机界面无外乎是最重要的,Windows以其良好的人机操作界面在操作系统中占有绝对的统治地位,作用可见一斑。

        Java中也可以完成这样的操作界面,图形用户界面(Graphical User Interface, GUI)编程主要有以下几个特征:

  • 图形界面对象及其框架(图形界面对象之间的包含关系)
  • 图形界面对象的布局(图形界面对象之间的位置关系)
  • 图形界面对象上的事件响应(图形界面对象上的动作)

        在Java的图形界面开发中有两种可使用的技术: AWT、Swing。 但是,在AWT中大量地使用了Windows的系统函数,不是使用Java开发的;而Swing是由Java来实现的用户界面类,可以在任意的系统平台上工作,但是在Swing中仍然大量使用了AWT的概念。

18.1 AWT简介

        AWT(Abstract Windowing Toolkit),抽象窗口工具包,是Sun公司在发布JDK1.0时一个重要的组成部分,是Java提供用来建立和设置Java的图形用户界面的基本工具。AWT中的所有工具类都保存在java.awt包中,此包中的所有操作类可用来建立与平台无关的图形用户界面(GUI)的类,这些类又被称为组件(Components)。

        在整个AWT包中提供的所有工具类主要分为以下3种:

  • 组件:Component
  • 容器:Container
  • 布局管理器:LayoutManager

       在java.awt包中所提供的组件类非常多,主要的几个类如下图所示:

      18.1.1 组件

        在图形界面中,用户经常会看到一个个按钮、标签、菜单等,这实际上就是一个个的组件。这些组件都会在一个窗体上显示!!

        在整个AWT包中,所有的组件类(如按钮、文本框等)都是从Component和MenuComponent扩展而来的,这些类会继承这两个类的公共操作,继承关系分别如下2图所示:

(1)Component继承关系

===================================================================================

Swing中的组件: 在Swing中的所有组件类实际上也都是Component的子类,与Component不同的是,所有的组件前都加上了一个“JXx”的形式,如JButton、JLabel等。

===================================================================================

(2)MneuComponent继承关系

      18.1.2 容器

       所有的AWT组件都应该放到容器中,并可以设置其位置、大小等,所有的容器都是Component的子类,在AWT中包含如图所示的集中容器

      18.1.3 布局管理器

       使用布局管理器可以使容器中的组件按照指定的位置进行摆放。另外一个好处是,即使容器改变了大小,布局管理器也可以准确地把组件放到指定的位置,这样就可以有效地保证版面不会混乱。

       在AWT中所有的布局管理器都是LayoutManager的子类。布局管理类的继承关系如下图所示:

18.2 Swing简介

         AWT大量地引入了Windows函数,所以经常被称为重量级组件。在Java 2中提供了轻量级的图像界面组件 ---  Swing, Swing使用Java语句实现,是以AWT平台为基础构建起来的新组件,直接使用Swing可以更加轻松地构建用户界面。

        在Java中所有的Swing都保存在javax.swing包中,从包的名称中(javax)可以清楚地发现此包是一个扩展包,所有的组件是从JComponent扩展出来的。实际上是java.awt.Component的子类,如下图所示:

                           

         JComponent类几乎是所有Swing组件的公共超类。就像Component类是所有AWT组件的父类一样,所以JComponent的所有子类也都是继承了本类的全部公共操作,继承关系如下图:

          从上图各个组件类的定义来看,所有的Swing组件只是比AWT组件前多增加了一个字母“J”而已。

          在Swing中依然存在容器的概念,所有的容器类都是继承自AWT组件包。例如,在Swing中容器使用了JFrame、JWindow、JPanel等,这些分别是Frame、Window、Panel的子类。

          在Swing中依然可以使用AWT中所提供的各个布局管理器,为组件进行统一的布局管理。要想使用布局管理器,则首先应该了解Swing中的容器及基本组件。

18.3 基本容器:JFrame

       如果要使用Swing创建一个窗口,则直接使用JFrame类即可,此类事Component的子类,常用的操作方法如下:

     下面使用以上方法创建一个新的窗体,如下所示:

范例:创建一个新的窗体

package org.forfan06.jframedemo;
import java.awt.Color;
import javax.swing.JFrame;
public class JFrameDemo01{
    public static void main(String args[]){
        JFrame jf = new JFrame("第一个Swing窗体");   //实例化窗体对象
        jf.setSize(230, 80);      //设置窗体大小
        jf.setBackground(Color.WHITE);    //设置窗体的背景颜色
        jf.setLocation(300, 200);   //设置窗体的显示位置
        jf.setVisible(true);  //让组件显示
    }
}

       上面程序运行之后,会直接显示出一个窗体,可以发现此窗体的标题就是在实例化JFrame时设置的标题,底色为白色,通过setSize()方法设置了其显示的大小。在代码中最重要的就是setVisible(true),如果没有这行代码,则窗体不会显示。

       在这时背景颜色时使用了java.awt.Color类完成,此类 存在大量的颜色常量,直接使用这些常量就可以改变颜色。

note:上面的程序运行后,是无法退出的。虽然现在的窗体上有关闭按钮,但是,由于没有编写关于此按钮的事件处理代码。所以此按钮在上面的代码中是无法让程序退出的。


       在JFrame中也可以使用Dimension类设置窗体的大小,此类封装的是组件显示宽度和高度。Dimension类的常用操作方法如下:

       除了设置组件大小可以使用Dimension外,对于组件的显示位置也存在一个Point类,此类封装的是显示位置的X、Y坐标。Point类的常用操作方法如下:

范例:使用Dimension和Point类设置组件大小和显示位置

package org.forfan06.jframedemo;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Point;
import javax.swing.JFrame;
public class JFrameDemo02{
    public static void main(String args[]){
        JFrame jf = new JFrame("第一个Swing窗体");   //实例化窗体对象
        Dimension d = new Dimension();   //实例化Dimension对象
        d.setSize(230, 80);     //设置大小
        jf.setSize(d);   //设置组件大小
        jf.setBackground(Color.WHITE);  //设置窗体的背景颜色
        Point p = new Point(300, 200);  //设置显示的坐标点
        jf.setLocation(p); //设置窗体的显示位置
        jf.setVisible(true);  //让组件显示
    }
}

上面的程序JFrameDemo01和JFrameDemo02的运行结果完全一样。

==================================================================

Question: 为什么在实例化Frame对象时不用异常处理?  在Frame类的构造方法上使用了throws关键字抛出异常,为什么在程序中没有使用try...catch语句块进行异常的捕获及处理呢?

Answer: 因为Frame类构造方法抛出的是HeadlessException异常,而,HeadlessException是RuntimeException的子类。在Java的异常处理中,只要是RuntimeException类型的异常,在程序中可以不使用try...catch进行处理也可以!!!

================================================================== 

18.4 标签组件: JLabel

      18.4.1认识JLabel

       JLabel组件表示的是一个标签,本身也是用于显示信息的,一般情况下是不能直接更改其显示内容的。创建完的Label对象可以通过Container类中的add()方法加入到容器中,JLabel类的常用方法和常量如下图所示:

范例:使用一个标签

package org.forfan06.jframedemo;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Point;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class JLabelDemo01{
    public static void main(String args[]){
        JFrame jf = new JFrame("Welcome to 优快云");  //实例化窗体对象
        JLabel jl = new JLabel("优快云", JLabel.CENTER);  //实例化JLabel对象,使用居中对齐方式
        
        jf.add(jl);
        Dimension d = new Dimension();
        d.setSize(200, 70);
        jf.setSize(d);
        jf.setBackground(Color.WHITE);
        
        Point p = new Point(300, 200);
        jf.setLocation(p);
        jf.setVisible(true);
    }
}

        上面程序中,实例化了一个JLabel对象,并指定内容以及对齐方式,之后将组件加入到了容器中进行显示。

        如果非要在以上代码中体现容器的概念,则可以直接通过JFrame中的getContentPane()取得窗体的Container对象,并在此对象中加入组件。如下:

Container cont = jf.getContentPane(); //取得窗体的容器
cont.add(lab);  //在容器中加入组件

      18.4.2 更改JLabel的文字样式

       以上的标签内容只是使用了默认的字体和颜色显示,如果现在要更改字体,可以直接使用Component类中定义的方法:

public void setFont(Font f)

       在设置时使用了java.awt.Font类来表示字体。Font类的常用操作方法及常量如下所示:

 

范例:设置标签的显示字体、大小、背景颜色

package org.forfan06.jframedemo;
import java.awt.Font;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Point;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class JLabelDemo02{
	public static void main(String args[]){
		JFrame jframe = new JFrame("Welcome to 优快云");  //实例化窗体对象
		JLabel jlabel = new JLabel("优快云", JLabel.CENTER);  //实例化JLabel对象,使用居中对齐
		Font font = new Font("Serief", Font.ITALIC + Font.BOLD, 28);
		
		jlabel.setFont(font);    //设置标签的显示字体
		jlabel.setBackground(Color.RED);  //设置标签的文字颜色

		jframe.add(jlabel);  //向容器中加入组件
		Dimension dim = new Dimension();   //实例化Dimension对象
		dim.setSize(200, 70);    //设置大小
		jframe.setSize(dim);   //设置组件大小
		jframe.setBackground(Color.WHITE);    //设置窗体的背景颜色
		Point point = new Point(300, 200);    //设置显示的坐标点
		jframe.setLocation(point);      //设置窗体的显示位置
		jframe.setVisible(true);       //让组件显示
	}
}

        上面程序通过JLabel标签显示后,文字设置成了红色,而且通过Font指定了其字体风格以及大小。

=================================================================================

Question:如何取得本机的全部字体? 现在的程序中使用了一种字体样式,如果想取得本机的全部字体该如何编写程序呢?

Answer: 可以使用GraphicsEnvironment类来取得本机的全部字体。 java.awt.GraphicsEnvironment可以反悔本机的全部绘图设备和全部字体的集合。该类时抽象类,要想实例化该对象,直接使用类中的getLocalGraphicsEnvironment()方法即可,之后通过getAvailableFontFamilyNames()方法就可以取得全部的可用字体。

=================================================================================

范例:取得本机中的全部可用字体

package org.forfan06.jframedemo;
import java.awt.GraphicsEnvironment;
public class GetAllFonts{
 public static void main(String args[]){
  //取得本地的绘图设备和字体集合
  GraphicsEnvironment eq = GraphicsEnvironment.getLocalGraphicsEnvironment();
  //取得全部可用的字体
  String[] fontNames = eq.getAvailableFontFamilyNames();
  //循环输出全部内容
  for(int x = 0; x < fontNames.length; x++){
   //输出每一个字体名称
   System.out.println(fontNames[x]);
  }
 }
}

      18.4.3 在JLabel中设置图片

       如果现在想将一个图像设置到JLabel中也是可以的,直接使用Icon接口以及ImageIcon子类即可。 在ImageIcon中可以使用如下所示的构造方法,将图像的数据以byte数据的形式设置上去。

(1)     下面先看第一个构造方法的使用。如果要从一个图像文件爱你中取得字节数组,则必须使用InputStream类完成操作。此时假定图像的路径为D:\csdn.gif

范例:在标签上设置图像

package org.forfan06.jlabeldemo;
import java.awt.Color;
import java.awt.Font;
import java.awt.Dimension;
import java.awt.Point;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.ImageIcon;
import javax.swing.Icon;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
public class JLabelDemo03{
	public static void main(String args[]){
		JFrame jframe = new JFrame("Welcome to 优快云");
		String picPath = "D:" + File.separator + "csdn.gif";
		File file = new File(picPath);
		InputStream input = null;
		byte[] b = new byte[(int)file.length()];

		try{
			input = new FileInputStream(file);
			input.read(b);
			input.close();
		}catch(Exception e){
			e.printStackTrace();
		}
		Icon icon = new ImageIcon(b);
		JLabel jlabel = null;
		jlabel = new JLabel("优快云", icon, JLabel.CENTER);

		Font font = new Font("Serief", Font.ITALIC + Font.BOLD, 28);
		jlabel.setFont(font);
		jlabel.setBackground(Color.YELLOW);
		jlabel.setForeground(Color.RED);
		jframe.add(jlabel);
		jframe.setSize(300, 160);
		jframe.setBackground(Color.WHITE);
		jframe.setLocation(300, 200);
		jframe.setVisible(true);
	}
}

(2) 如果使用一个IO流进行图片读取来设置JLabel显示图形太麻烦,则可以直接将一个图片路径传递到ImageIcon的实例化中,并使用JLabel类中可以设置ImageIcon的构造方法即可。如下所示:

范例:通过图片路径来实例化ImageIcon对象

package org.forfan06.jlabeldemo;
import java.awt.Color;
import java.io.File;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.ImageIcon;
import javax.swing.Icon;
public class JLabelDemo04{
	public static void main(String args[]){
		JFrame jframe = new JFrame("Welcome to 优快云");
		String picPath = "D:" + File.separator + "csdn.gif";
		Icon icon = new ImageIcon(picPath);

		JLabel jlabel = null;
		jlabel = new JLabel(icon, JLabel.CENTER);
		jlabel.setBackground(Color.YELLOW);
		jlabel.setForeground(Color.RED);

		jframe.add(jlabel);
		jframe.setSize(300, 160);
		jframe.setBackground(Color.WHITE);
		jframe.setLocation(300, 200);

		jframe.setVisible(true);
	}
}

===================================================================================

如果图像是从一个不确定输入流(如从数据库中读取BLOB字段)中而来,则要使用public ImageIcon(byte[] imageData)来实例化Icon对象;

如果图片是从文件中而来,那么就使用public ImageIcon(String filename)来实例化Icon对象。

===================================================================================

18.5 按钮组件: JButton

         JButton组件表示一个普通的按钮,使用此类可以直接在窗体中增加一个按钮。JButton类的常用方法如下:

范例:建立一个普通的按钮

package org.forfan06.jbuttondemo;
import java.awt.Font;
import java.awt.Color;
import javax.swing.JFrame;
import javax.swing.JButton;
public class JButtonDemo01{
	public static void main(String args[]){
		JFrame jframe = new JFrame("Welcome to 优快云");
		JButton jbutton = new JButton("PUSH ME");
		Font font = new Font("Serief", Font.BOLD, 28);
		jbutton.setFont(font);
		jframe.add(jbutton);
		jframe.setSize(200, 70);
		jframe.setBackground(Color.WHITE);
		jframe.setLocation(300, 200);
		jframe.setVisible(true);
	}
}

从程序代码来看,一个按钮的显示是非常容易的,而且使用起来与JLabel没有任何区别。JButton也可以为一个按钮设置一张显示图片,与JLabel类似,直接在创建按钮对象时设置即可。(图像文件保存路径:D:\jbutton.gif)

范例:在按钮上显示图片

package org.forfan06.jbuttondemo;
import java.awt.Font;
import java.awt.Color;
import java.io.File;
import java.io.InputStream;
import java.io.FileInputStream;
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.Icon;
import javax.swing.ImageIcon;
public class JButtonDemo02{
	public static void main(String args[]){
		JFrame jframe = new JFrame("Welcome to 优快云");
		String picPath = "D:" + File.separator + "jbutton.gif";

		//实例化Icon对象方式1
		File file = new File(picPath);
		InputStream input = null;
		byte[] b= new byte[(int)file.length()];

		try{
			input = new FileInputStream(file);
			input.read(b);
			input.close();
		}catch(Exception e){
			e.printStackTrace();
		}
		Icon icon = new ImageIcon(b);

		//实例化Icon对象方式2
		Icon icon2 = new ImageIcon(picPath);

		JButton jbutton = new JButton(icon);
		
		jframe.add(jbutton);
		jframe.setSize(206, 78);
		jframe.setBackground(Color.WHITE);
		jframe.setLocation(300, 200);
		jframe.setVisible(true);
	}
}

18.6 布局管理器

       了解了基本的窗体和两个组件之后,可以发现,如果不对窗体进行版面设置,则一个组件会直接充满整个窗体,所以在Java中专门提供了布局管理器来管理组件。通过布局管理器可以使用不同方式的排列组件。每当需要重新调整屏幕大小或重新绘制屏幕上任一项时,都要用到布局管理器。

       在Swing中使用的所有布局管理器都可以实现LayoutManager接口,在Swing中主要使用以下5种常见的布局管理器:

  • FlowLayout
  • BorderLayout
  • GridLayout
  • CardLayout
  • 绝对定位

      18.6.1FlowLayout

       FlowLayout属于流式布局管理器,使用此种布局方式会使所有的组件像流水一样依次进行排列。  FlowLayout类的常用方法及常量如下所示:


范例:设置FlowLayout

package org.forfan06.layoutdemo;
import java.awt.FlowLayout;
import javax.swing.JFrame;
import javax.swing.JButton;
public class FlowLayoutDemo01{
    public static void main(String args[]){
        JFrame jframe = new JFrame("Welcome to 优快云");
        jframe.setLayout(new FlowLayout(FlowLayout.CENTER, 3, 3));
        JButton jbutton = null;
        for(int i = 0; i < 9; i++){
            jbutton = new JButton("button - " + i);
            jframe.add(jbutton);
        }
        jframe.setSize(280, 123);
        jframe.setVisible(true);
    }
}
        从程序运行结果可以发现,所有的组件按照顺序依次向下排列,每个组件之间的顺序是3.之前讲解的JPanel就是采用此种布局方式,所以显示组件时顺序地向JPanel中加入。

      18.6.2 BorderLayout

       BorderLayout将一个窗体的版面划分成东、南、西、北、中  5个区域,可以直接将需要的组件放到这5个区域中。BorderLayout的常用方法及常量如下:

范例:设置BorderLayout

package org.forfan06.layoutdemo;
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JButton;
public class BorderLayoutDemo01{
    public static void main(String args[]){
        JFrame jframe = new JFrame("Welcome to 优快云");  //实例化窗体对象
        //设置窗体中的布局管理器为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("中,middle"), BorderLayout.CENTER);
        jframe.pack();    //根据组件自动调整窗体大小
        jframe.setVisible(true);  //设置窗体可见
    }
}

      18.6.3 GridLayout

       GridLayout布局管理器是以表格的形式进行管理的,在使用此布局管理器时必须设置显示的行数和列数。其常用的方法如下:

范例:设置GridLayout

package org.forfan06.layoutdemo;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JButton;
public class GridLayoutDemo01{
    public static void main(String args[]){
        JFrame jframe = new JFrame("Welcome to 优快云");
        //设置窗体的布局管理器为GridLayout,按3*5进行排列,水平和垂直间距均为3
        jframe.setLayout(new GridLayout(3, 5, 3, 3));
        JButton jbutton = null;
        for(int i = 0; i < 13; i++){
            jbutton = new JButton("button - " + i);
            jframe.add(jbutton);
        }
        jframe.pack();   //根据组件自动调整窗体大小
        jframe.setVisible(true);
    }
}
===============================================================================

在计算器的操作上可以使用GridLayout布局管理器。 在Windows的计算器程序中,可以发现有很多个按钮,此时实际上就可以通过GridLayout布局管理器摆放全部的按钮!

===============================================================================

      18.6.4 CardLayout

       CardLayout就是将一组组件彼此重叠地进行布局,就像一张张卡片一样,这样每次只会展现一个界面。CardLayout类的常用方法如下:

范例:设置CardLayout

package org.forfan06.layoutdemo;
import java.awt.CardLayout;
import java.awt.Container;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class CardLayoutDemo01{
    public static void main(String args[]){
        JFrame jframe = new JFrame("Welcome to 优快云");     //实例化窗体对象
        Container container = jframe.getContentPane();   //取得窗体容器
        CardLayout card = new CardLayout();    //定义布局管理器
        jframe.setLayout(card);  //设置布局管理器
        container.add(new JLabel("label-A", JLabel.CENTER), "first");
        container.add(new JLabel("label-B", JLabel.CENTER), "second");
        container.add(new JLabel("label-C", JLabel.CENTER), "third");
        container.add(new JLabel("label-D", JLabel.CENTER), "fourth");
        container.add(new JLabel("label-E", JLabel.CENTER), "fifth");
        jframe.pack();  //根据组件自动调整窗体大小
        jframe.setVisible(true);
        card.show(container, "third");
        for(int = 0; i < 5; i++){
            try{
                Thread.sleep(3000);
            }catch(InterruptedException e){
                e.printStackTrace();
            }
            card.next(container);
        }
    }
}
上面程序在显示时首先会显示第3张卡片,之后循环显示每一张卡片。

      18.6.5 绝对定位

       如果不想在窗体中指定布局管理器,也可以通过设置绝对坐标的方式完成。在Component中提供了setBounds()方法,可以定位一个组件的坐标,使用X、Y的坐标表示方式。该方法的定义如下:

public void setBounds(int x, int y, int width, int height)
      在每一个组件中都存在以上方法,通过它可以设置每一个组件的具体位置。

范例:使用绝对定位排版

package org.forfan06.layoutdemo;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class AbsoluteLayoutDemo01{
    public static void main(String args[]){
        JFrame jframe = new JFrame("Welcome to 优快云");
        jframe.setLayout(null);   //使用绝对定位
        JLabel title = new JLabel("www.youkuaiyun.com");
        JButton enter = new JButton("进入");
        JButton help = new JButton("帮助");
        jframe.setSize(200, 90);
        title.setBounds(45, 5, 150, 20);
        enter.setBounds(10, 30, 80, 20);
        help.setBounds(100, 30, 80, 20);
        jframe.add(title);
        jframe.add(enter);
        jframe.add(help);
        jframe.setVisible(true);
    }
}
         使用绝对定位有一点好处: 不管窗体如何改变大小,组件的位置是固定不变的;而之前的各种排版方式,当窗体改变时,组件大小也会跟着改变。

18.7 其他容器

        在Swing开发中,窗体部分除了可以使用JFrame表示之外,还有其他几种常见的窗体:JPanel、JSplitPane、JTabbedPane、JScrollPane、JDesktopPane、JInternalFrame等等,下面分别进行介绍。

      18.7.1 JPanel

       JPanel也是一种经常用到的容器之一,可以使用JPanel完成各种复杂的界面表示。在JPanel中可以加入任意的组件,之后直接将JPanel容器加入到JFrame容器中即可显示。 JPanel常用的方法如下:

范例:JPanel的基本使用

package org.forfan06.jpaneldemo;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.JLabel;
public class JPanelDemo01{
    public static void main(String args[]){
        JFrame jframe = new JFrame("Welcome to 优快云");
        JPanel jpanel = new JPanel();
        
        jpanel.add(new JLabel("label-A"));
        jpanel.add(new JLabel("label-B"));
        jpanel.add(new JLabel("label-C"));
        jpanel.add(new JButton("button-X"));
        jpanel.add(new JButton("button-Y"));
        jpanel.add(new JButton("button-Z"));
        
        jframe.add(jpanel);    //将JPanel加入到窗体
        jframe.pack();   //根据组件自动调整窗体大小
        jframe.setLocation(300, 200);
        jframe.setVisible(true);
    }
}
从运行结果可以发现,所有的组件都是采用顺序的形式加入到JPanel中,最后再将JPanel加入到JFrame中。

=============================================================================

可以将多个组件加入到JPanel中实现复杂的排列。 使用JPanel并结合之前的布局管理器可以更加方便地管理组件,可以使用布局管理器对多个JPanel进行排列。而每个JPanel中也可以分别使用不同的布局管理器管理组件。这样就可以对组件进行复杂的排列

=============================================================================

      18.7.2 JSplitPane

      JSplitPane的主要功能是分割面板,可以将一个窗体分为两个子窗体。可以是水平排列也可以是垂直排列(子窗体间的排列关系)。

      JSplitPane的主要方法及常量如下:

下面使用分割面板的方式完成上下、左右的分割程序,程序的实现思路如下图所示:

范例:实现复杂分割

package org.forfan06.jsplitpanedemo;
import java.awt.Container;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JSplitPane;
public class JSplitPaneDemo01{
    public static void main(String args[]){
        JFrame jframe = new JFrame("Welcome to 优快云");
        Container container = jframe.getContentPane();  //得到窗体容器
        JSplitPane leftSplit = null;   //左右分割的SplitPane
        JSplitPane tbSplit = null;   //上下分割的SplitPane
        
        leftSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, new JLabel("left label"), new JLabel("right label"));   //设置水平分割
        leftSplit.setDividerSize(3);  //设置左右的分割线大小
        
        tbSplit = new JSplitPane(JSplitPane.VERTICAL_SPLIT, leftSplit, new JLabel("bottom label"));  //设置垂直分割
        tbSplit.setDividerSize(10); //设置上下的分割线大小
        
        tbSplit.setOneTouchExpandable(true);  //快速展开/折叠分割条
        container.add(tbSplit);
        jframe.setSize(230, 80);
        jframe.setLocation(300, 200);
        jframe.setVisible(true);
    }
}
从运行结果中可发现,左右的分割面板的分割线长度比较小;而上下的分割面板的分割线长度大一些,并且设置了快速展开/折叠功能。

      18.7.3 JTabbedPane

      JTabbedPane是在一个面板上设置多个选项卡供用户选择。 如果需要查看哪个方面的信息,则直接选择选项卡即可流浪。通过这种方式用户可以方便地管理自己的相关信息。

       JTabbedPane类的常用方法及常量如下图所示:

范例:设置选项卡

package org.forfan06.jtabbeddemo;
import javax.swing.JTabbedPane;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.ImageIcon;
import java.awt.Container;
import java.io.File;
public class JTabbedPaneDemo01{
    public static void main(String args[]){
        JFrame jframe = new JFrame("Welcome to 优快云");
        Container container = jframe.getContentPane();  //得到窗体容器
        JTabbedPane tab = null;
        tab = new JTabbedPane(JTabbedPane.TOP);  //设置标签在顶部显示
        
        JPanel pan1 = new JPanel();
        JPanel pan2 = new JPanel();
        JButton button = new JButton("button");
        JLabel label = new JLabel("label");
        
        pan1.add(button);   //第一个面板加入一个按钮
        pan2.add(label);    //第二个面板加入一个标签
        
        String picPath = "D:" + File.separator + "logo.gif";
        tab.addTab("图片选项", new ImageIcon(picPath), pan1, "图像");
        tab.addTab("文字选项", pan2);          //加入两个组件
        
        container.add(tab);   //加入到容器中
        jframe.setSize(230, 120);
        jframe.setLocation(300, 200);
        jframe.setVisible(true);
    }
}

         以上程序中建立了两个选项卡,并且将选择卡放在窗体顶部。每一个选项卡中都加入了一个JPanel面板。层次关系如下:

 

      18.7.4 JScrollPane

       在一般的图形界面中如果显示的区域不够大,往往会出现滚动条以方便用户浏览,在Swing中JScrollPane的主要功能就是为了显示的内容加入水平滚动条。JScrollPane主要由JViewport和JScrollBar两个部分组成,前者主要是显示一个矩形的区域让用户浏览;而后者主要是形成水平或垂直的滚动条,它们的关系如下图所示。

      但是在开发中用户一般情况下不经常使用这两个类,因为在JScrollPane中已经为开发者提供了足够的功能。下图中列出了JScrollPane常用的方法及常量。

范例:为图片设置滚动条

package org.forfan06.jscrollpanedemo;
import java.awt.Container;
import java.io.File;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
public class JScrollPaneDemo01{
    public static void main(String args[]){
        JFrame jframe = new JFrame("Welcome to 优快云");
        Container container = jframe.getContentPane();  //得到窗体容器
        String picPath = "D:" + File.separator + "csdn.gif";
        Icon icon = new ImageIcon(picPath);
        JPanel pan = new JPanel();
        JLabel label = new JLabel(icon);
        
        pan.add(label);
        JScrollPane scrl = null;
        //垂直滚动条始终显示,水平滚动条根据需要显示
        scrl = new JScrollPane(pan, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        
        container.add(scrl);
        jframe.setSize(230, 120);
        jframe.setLocation(300, 200);
        jframe.setVisible(true);
    }
}
       上面图片因为大小已经超过了容器本身,所以只显示了部分内容。水平滚动条是根据需要来显示的,而垂直滚动条将始终显示,用户可以自由改变窗体大小观察滚动条的显示情况。

      18.7.5 JDesktopPane和JInternalFrame

        在Swing中也可以完成内部窗体的显示,即在一个窗体中可以出现多个子窗体,每一个子窗体都无法超出父窗体的区域。

        JDesktopPane规定了一个父窗体的基本形式,而JInternalFrame规定了各个子窗体;JInternalFrame需要加入到JDesktopPane中。这两个类的常用方法如下所示:

范例:设置内部窗体

package org.forfan06.jinternalframedemo;
import java.awt.BorderLayout;
import java.awt.Container;
import java.io.File;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class JInternalFrameDemo01{
    public static void main(String args[]){
        JFrame jframe = new JFrame("Welcome to 优快云");
        jframe.setLayout(new BorderLayout());
        Container container = jframe.getContentPane();  //得到窗体容器
        JDesktopPane desk = new JDesktopPane();
        container.add(desk, BorderLayout.CENTER);
        container.add(new JLabel("内部窗体"), BorderLayout.SOUTH);
        
        JInternalFrame jif = null;
        String picPath = "D:" + File.separator + "csdn.gif";
        Icon icon = new ImageIcon(picPath);
        JPanel pan = null;
        for(int i = 0; i < 3; i++){
            //实例化一个指定标题、可改变大小、可关闭、可最大化、可图标化的内部窗体
            jif = new JInternalFrame("优快云-" + i, true, true, true, true);
            pan = new JPanel();
            pan.add(new JLabel(icon));
            jif.setLocation(35 - i * 10, 35 - i * 10);
            jif.add(pan);
            
            jif.pack();
            jif.setVisible(true);
            desk.add(jif);
        }
        jframe.setSize(300, 270);
        jframe.setLocation(300, 200);
        jframe.setVisible(true);
    }
}
       上面代码通过循环产生了3个内部窗体,并依次设置好其在窗体中的显示位置,无论现在怎么拖拽都无法将这些内部窗体移动到窗体之外!!!

18.8 不弹起的按钮组件: JToggleButton

        JButton提供了一个按钮的基本实现,但是此按钮每次单击之后都会恢复自动弹起。如果现在希望单击一个按钮后不再自动弹起,而是在第二次单击此按钮时弹起,则就必须使用JToggleButton类。JToggleButton类的常用方法如下图所示:

范例:使用JToggleButton建立按钮

package org.forfan06.jtogglebuttondemo;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JToggleButton;
public class JToggleButtonDemo01{
    public static void main(String args[]){
        JFrame jframe = new JFrame("Welcome to 优快云");
        JToggleButton button1 = new JToggleButton("已选中", true);
        JToggleButton button2 = new JToggleButton("未选中");
        JToggleButton button3 = new JToggleButton("按我");
        jframe.setLayout(new GridLayout(3, 1));
        jframe.add(button1);
        jframe.add(button2);
        jframe.add(button3);
        jframe.setSize(200, 100);
        jframe.setLocation(300, 200);
        jframe.setVisible(true);
    }
}
           程序中的3个按钮,button1因为已经设置为已选中状态,所以程序刚运行就是按下的状态,之后又设置了两个没有被默认选中的按钮,当每次单击之后按钮不会自动弹起。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值