39.JAVA编程思想之外篇——JAVA图形化设计精简大全一文覆盖

欢迎转载,转载请标明出处:http://blog.csdn.net/notbaron/article/details/51204948

目录

Java图形化界面设计——容器(JFrame)...1

Java基本类(JFC)...1

l     AWTAbstract Window Toolkit(AWT)抽象窗口工具包... 2

l     Swing包... 2

l     AWT和Swing的区别... 6

Swing基本框架...7

图形化设计步骤...8

创建顶层容器...8

创建中间容器、组件...9

将组件加入容器...9

设置容器内组件的位置...9

处理组件所产生的事件...9

组件容器的使用...10

l     1.JFrame 框架窗口的使用... 10

实例1:直接定义Jframe 类的对象创建一个窗口...11

实例2:创建类继承JFrame类创建一个窗口...13

2. JPanel的使用...15

布局管理器所属类包...17

1.容器的默认布局管理器...18

a.FlowLayout(流式布局)...19

b.边界布局管理器...22

c.网格布局...25

d.卡片布局...29

 Java图形化界面设计——容器(JFrame)

Java基本类(JFC)

Java基本类(“JavaFoundationClasses”JFC),是一个图形框架(GraphicalFramework),依据此框架可建构出具有移携性(Portable)的JavaGUI图形式使用者介面。

JFC主要是由AWTAbstractWindow ToolkitAWT)、Swing以及Java 2D三者所构成,若将这些一同搭配运用,则用Java程式语言撰写开发成的使用者介面,无论移转、转移到MicrosoftWindowsWindowsMacOS XLinux等各种不同的作业平台上,都能保有一致性的图像呈现。

上面列出的这些应用程序接口可难会出现在多个软件包中。例如:2D APIJava.awtJava.awt.image软件包中都存在,虽然像Java.awt.geom等一些特殊的软件包也支持2DAPI,但是大量的2D API类都存在于Java.awt软件包中。

l  AWTAbstract Window Toolkit(AWT)抽象窗口工具包

AWT是比较旧的双介面函式库,它依然高度倚赖各作业平台自身所具备的绘图功效机能,且用一个比包容程式(Wrapper)还小的设计还去除、吸收各作业平台间的绘图功能机能差异,以致Java程式在跨平台移携后的绘图呈现不够一致,这使得AWT遭受到众多的批评。这意味着:AWTWidget倚赖作业平台自身原有的Widget功效机能,程式设计师在开发撰写时必须去了解各作业平台在Widget方面的差异性,如此便偏离了Java程式语言最初的宗旨:跨平台一致性。

AWTjava.awt包提供,其提供了支持GUI设计的类和接口,而又AWT提供的组建一般称之为重量级组件,其是由本地方法来实现其功能的。在第二版的Java开发包中,AWT的器件很大程度上被Swing工具包替代。Swing通过自己绘制器件而避免了AWT的种种弊端:Swing调用本地图形子系统中的底层例程,而不是依赖操作系统的高层用户界面模块。 

l  Swing包

为了解决AWT组件的缺陷,特别是跨平台的问题,在JDK1.2版本后提供了新的Swing包,有javax.swing提供,Swing是在AWT的基础上构建的一套新的图形界面组件,所有组建均是由java书写,具有良好的跨平台性,由于Swing没有使用本地方法实现图形功能,因此提出把Swing组件称之为轻量级组件。

PS:Swing组建是在AWT基础上建立的,而不是替代AWT的,AWT是根基,Swing是发展。Swing组件几乎都是轻量组件,那些顶层容器:窗体,小应用程序、窗口和对话框除外。因为轻量组件是在其容器的窗口中绘制的,而不是在自己的窗口中绘制的,所以轻量组件最终必须包含在一个重量容器中。因此,Swing的窗体、小应用程序、窗口和对话框都必须是重量组件,以便提供一个可以在其绘制Swing轻量组件的窗口。

 Swing包括250多个类,其中有些是UI组件,有些是支持类。为了把UI组件和支持类区分开,Swing组件的名字以J开头。下表列出了Swing提供的J组件。用斜体字表示的组件是AWT组件的替代组件。

组件类         描述─────────────────────────────────

JAppletJava.applet.Applet类的扩展,它含有JRootPane的一个实例

JButton 能显示文本和图形的按钮,它是AWT按钮组件的替代组件

JCheckBox 能显示文本和图形的复选框,它是AWT选择组件的替代组件

JCheckBoxMenuItem 一个复选框菜单项,它是AWT的复选框菜单项组件的替代组件

JComboBox 带下拉列表的文本框,它是AWT选择组件的替代组件  JComponent所有轻量J组件的基类

JDesktopPane内部窗体的容器

JDialogSwing对话框的基类,它扩展了AWTDialot类  JEditorPane用于编辑文本的文本窗格

JFrame 扩展java.awt.Frame的外部窗体

JInternalFrameJDesktopPane中出现的内部窗体

JLabel 可显示文本和图标的标签,它是AWT标签组件的替代组件  JLayeredPane能够在不同层上显示组件的容器

JList 显示选项列表的组件,它是AWT列表组件的替代组件  JMenu 菜单条中显示的一个菜单,它是AWT菜单组件的替代组件  JMenuBar 用于显示菜单的菜单条,它是AWT菜单条组件的替代组件  JMenuItem 菜单项,它是AWT菜单项组件的替代组件  JOptionPane 显示标准的对话框,如:消息和问题对话框

JPanel 通用容器,它是AWT面板和画布组件的替代组件  JPasswordfieldJTextField的扩展,使输入的字符不可见  JPopupMenu 弹出式菜单,它是AWT弹出式菜单组件的替代组件  JProgressBar进度指示器

JRadioButton 单选按钮,它是AWT复选框组件的替代组件  JRootPane顶层容器,它包含一个玻璃窗格,一个层窗格,一个内容窗格和一个可选的菜单条

JScrollBar 滚动条,它是AWT滚动条组件的替代组件  JScrollPane 滚动窗格,它是AWT滚动窗格组件的替代组件  JSeparator水平或垂直分隔条

JSlider滑杆

JSplitPane有两个分隔区的容器,这两个分隔区可以水平排列或者垂直排列且分隔区的大小能自动调整

JTabbedPane带选项卡的窗格

JTable表格

JTableHeader表格头

JTextArea 用于输入多行文本的文本域,它是AWT文本域组件的替代组件

JTestComponent 文本组件的基类,它替代AWTTextComponent

JTextField 单行文本域,它替代AWT的单行文本域组件

JTextPane 简单的文本编辑器

JToggleButton两种状态的按钮,它是JCheckBoxJRadioButton组件的基类

JToolBar工具条

JToolTip当光标停留在一个组件上时,该组件上显示的一行文字

JTree用于按钮层次组织数据的结构控件

JViesport用于浏览可滚动组件的视口

JWindow 外部窗口,它是java.awt.Window的扩展

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━  注:斜体字表示的是AWT的替代组件

l  AWT和Swing的区别

      当利用 AWT来构件图形用户界面的时候,实际上是在利用操作系统所提供的图形库。由于不同操作系统的图形库所提供的功能是不一样的,在一个平台上存在的功能在另外一个平台上则可能不存在。为了实现Java语言所宣称的"一次编译,到处运行"的概念,AWT不得不通过牺牲功能来实现其平台无关性,也就是说,AWT所提供的图形功能是各种通用型操作系统所提供的图形功能的交集。由于AWT是依靠本地方法来实现其功能的,我们通常把AWT控件称为重量级控件。 

Swing 是在AWT的基础上构建的一套新的图形界面系统,它提供了AWT所能够提供的所有功能,并且用纯粹的Java代码对AWT的功能进行了大幅度的扩充。并不是所有的操作系统都提供了对树形控件的支持,Swing利用了AWT中所提供的基本作图方法对树形控件进行模拟。由于Swing控件是用100%Java代码来实现的,因此在一个平台上设计的树形控件可以在其他平台上使用。由于在Swing中没有使用本地方法来实现图形功能,我们通常把Swing控件称为轻量级控件。 

AWTSwing之间的基本区别:AWT是基于本地方法的C/C++程序,其运行速度比较快;Swing是基于AWTJava程序,其运行速度比较慢。对于一个嵌入式应用来说,目标平台的硬件资源往往非常有限,而应用程序的运行速度又是项目中至关重要的因素。在这种矛盾的情况下,简单而高效的AWT当然成了嵌入式Java的第一选择。而在普通的基于PC或者是工作站的标准Java应用中,硬件资源对应用程序所造成的限制往往不是项目中的关键因素,所以在标准版的Java中则提倡使用Swing,也就是通过牺牲速度来实现应用程序的功能。

 AWT 是抽象窗口组件工具包,是 java最早的用于编写图形节目应用程序的开发包。Swing是为了解决 AWT存在的问题而新开发的包,它以AWT为基础的。

Swing基本框架

如下1


可以看出Swing是继承自AWT的。 

图形化设计步骤

 图形化界面程序一个程序过程是:打开一个程序出现一个窗口或对话框,其中一般有菜单、工具栏、文本框、按钮、单选框、复选框等控件(组件也就是控件),用户录入相关数据,点按相关菜单、按钮,程序对数据进行相关处理,并将处理后的数据显示或者保存起来,最后关闭程序。

java编程的相关设计步骤来分解上面的的程序运行过程如下2所示:

 

创建顶层容器

顶层容器图形化界面显示的基础,其它所有的组件(控件)都是直接或间接显示在顶层容器中的。在java中顶层容器有三种,分别是JFrame(框架窗口,即通常的窗口)、JDialog(对话框)、JApplet(用于设计嵌入在网页中的java小程序)

创建中间容器、组件

对应于程序中出现的菜单、工具栏(中间容器)、文本框、按钮、单选框、复选框等控件。

有很多Swing组件可以使用,见前面的SwingUI组件表。

将组件加入容器

java中创建组件后,还需要将组件放入相应的容器,才能在顶层容器,如窗口中显示出组件。

设置容器内组件的位置

组件添加到容器中,还必须设置好组件的显示位置,一般有两种方法来设置组建的显示位置,一是按照与容器的相对距离(以像素为单位),精确固定控件的位置;二是用布局管理器来管理组件在容器内的位置。

处理组件所产生的事件

即用户执行选择菜单、单击按钮等操作时,就要执行相应的命令,进行相关的程序处理,这就需要设置组件的事件。

 组件容器的使用

顶层容器是容纳其它组件的基础,即设计图形化程序必须要有顶层容器。

Java中间容器是可以包含其它相应组件的容器,但是中间容器和组件一样,不能单独存在,必须依附于顶层容器。

常见的中间容器有:

•   JPanel:最灵活、最常用的中间容器。

•   JScrollPane:与JPanel类似,但还可在大的组件或可扩展组件周围提供滚动条。

•   JTabbedPane:包含多个组件,但一次只显示一个组件。用户可在组件之间方便地切换。

•   JToolBar:按行或列排列一组组件(通常是按钮)。

l  1.JFrame 框架窗口的使用

如下3


以上是JFrame的常用方法即说明,下面举例说明。

 实例1:直接定义Jframe 类的对象创建一个窗口

import javax.swing.*;//使用Swing类,必须引入Swing

publicclassJFrameDemo1 {

    publicstaticvoid main(Stringargs[]) {

        // 定义一个窗体对象f,窗体名称为"一个简单窗口"

        JFramef =new JFrame("一个窗口");

        /*

         *设置窗体左上角与显示屏左上角的坐标,离显示屏上边缘300像素,离显示屏左边缘300像素

         */

        f.setLocation(300, 300); // f.setLocationRelativeTo(null);本语句实现窗口居屏幕中央

        f.setSize(300, 200); // 设置窗体的大小为300*200像素大小

        f.setResizable(false);//设置窗体是否可以调整大小,参数为布尔值

        // 设置窗体可见,没有该语句,窗体将不可见,此语句必须有,否则没有界面就没有如何意义了

        f.setVisible(true);

        // 用户单击窗口的关闭按钮时程序执行的操作

        f.setDefaultCloseOperation(f.EXIT_ON_CLOSE);

    }

}

 程序运行结果如下4所示:


setDefaultCloseOperation(intoperation):设置用户在此窗体上发起"close"时默认执行的操作。方法中的参数解释如下:

“0”DO_NOTHING_ON_CLOSE

(在 WindowConstants 中定义):不执行任何操作;要求程序在已注册的WindowListener 对象的 windowClosing 方法中处理该操作。

比如实例程序代码中更改为f.setDefaultCloseOperation(f.DO_NOTHING_ON_CLOSE);或者f.setDefaultCloseOperation(0),然后查看效果,可以发现窗口无法关闭,下面是相同用法,不再解释了。

“1”HIDE_ON_CLOSE

调用任意已注册的 WindowListener 对象后自动隐藏该窗体。此时没有关闭程序,只是将程序界面隐藏了。

可以打开任务管理器,可以看到一个叫“java.exe”的进程(如果调试运行了多个java程序,则会看到多个“java.exe”的进程),如果此时用EditPlus测试程序,会发现当单击窗口的关闭按钮关闭窗口后,却无法再次对程序进行调试,因为程序线程没有关闭,在任务管理器中关闭java.exe(如果有多个“java.exe”的进程,则先都关闭掉,再来测试该问题)基础后,EditPlus才可以重新编译改程序。

“2”DISPOSE_ON_CLOSE

调用任意已注册 WindowListener 的对象后自动隐藏并释放该窗体。但继续运行应用程序,释放了窗体中占用的资源。

“3”EXIT_ON_CLOSE(在 JFrame 中定义)

使用 System exit 方法退出应用程序。仅在应用程序中使用。结束了应用程序。 

默认情况下,该值被设置为 HIDE_ON_CLOSE

当注释掉实例中的f.setDefaultCloseOperation(f.EXIT_ON_CLOSE);语句时,起到的效果和f.setDefaultCloseOperation(f.HIDE_ON_CLOSE);或者f.setDefaultCloseOperation(1);一样。

 实例2:创建类继承JFrame类创建一个窗口

import javax.swing.*;

 

//创建子类MyFrame继承父类JFrame

classMyFrameextends JFrame {

    // 定义构造函数,带有四个参数,用于设置窗口位置和大小

    MyFrame(intx,inty,inth,intw) {

        super("一个窗口");//重写父类方法,为窗口定义标题

        /*

         *以下的方法调用前面没有添加对象名,也不可能添加,要创建的对象名称是什么都不知道,也就不可能添加。但是创建对象后,对象自动获取这些初始值。

         */

        setLocation(x,y);

        setSize(h,w);

        setResizable(false);

        setVisible(true);

        setDefaultCloseOperation(EXIT_ON_CLOSE);

    }

}

 

publicclassJFrameDemo2 {

    publicstaticvoid main(Stringargs[]) {

        // 实例化类对象,提示设置参数

        MyFramef=newMyFrame(300, 300, 300, 200);

    }

} 

实际编程过程中,一般很少将文本框、按钮等组件直接放在顶层容器中进行布局,大多数时候是通过布局管理器结合中间容器对组件进行布局设置。 

1将组件添加到JFrame中方式之一:

frame.getContentPane().add(childComponent)

getContentPane()方法获得JFrame的内容面板,再对其加入组件,一般只使用该方式添加组件。

2JFrame中添加组件的两种方式之二:

把组件添加到Jpanel之类的中间容器中,用setContentPane()方法把该容器置为JFrame的内容面板:

    JpanelcontentPane=new Jpanel( );

      ……//把其它组件添加到Jpanel;

frame.setContentPane(contentPane); 

注意:用setContentPane()方法不允许设置窗体布局,其只显示最后添加的组件,且该组件将布满整个窗口,而不管原先组件的大小设置,相当于只允许添加一次组件作为JFrame的内容面板。所以一般不实用该方法进行添加组件(可能是我不知道吧)。

2. JPanel的使用

5


JPaneljava图形化界面中最常使用的容器。

实例:在窗体中添加一个蓝色的面板

import javax.swing.*;

import java.awt.*;//引入AWT包,因为要使用到颜色类

class PanelDemo {

    publicstaticvoid main(String[]args)throws Exception {

        JFramef =new JFrame("一个Java窗口");

        f.setSize(300, 200);

        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        f.setVisible(true);

        f.setResizable(false);

        f.setLocationRelativeTo(null);

        f.setLayout(null); // 设置窗体布局为空布局

        JPanelp =new JPanel();//实例化一个面板

        // 设置面板背景色为蓝色,如果不引入AWT包,程序将出错,可以试试看

        p.setBackground(Color.BLUE);

        p.setSize(100, 100); // 设置面板对象大小

        f.getContentPane().add(p); // 将面板添加到窗体中

        // 如果使用下面添加面板的方法,面板将布满整个窗口,可以试试看

        // f. setContentPane(p);

    }

}

 实例2:面板的嵌套

import java.awt.*;

import javax.swing.*;

class  TwoPanel extends JFrame {

  public TwoPanel( Stringtitle){

  super(title);

}

 public static void main(Stringargs[]) {

   TwoPanel fr=newTwoPanel("Two Panel测试");

   JPanel pan1 = newJPanel();

   JPanel pan2 = newJPanel();

  fr.setLayout(null);     

  fr.getContentPane().setBackground(Color.green);  //设置窗口的颜色

   fr.setSize(250,250);

  pan1.setLayout(null);                 //设置面板为空布局

   pan1.setBackground(Color.red);

   pan1.setSize(150,150);

  pan2.setBackground(Color.yellow);

   pan2.setSize(50,50);

  pan1.add(pan2);   //将面板pan2添加到pan1

        //pan1添加到窗体中,因为pan2被添加到pan1中,所以pan1pan2都被显示在窗体中

  fr.getContentPane().add(pan1); 

   fr.setVisible(true);

fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

 }

}

如下6

   

Java虽然可以以像素为单位对组件进行精确的定位,但是其在不同的系统中将会有一定的显示差异,使得显示效果不尽相同,为此java提供了布局管理器,以使编写的图形界面具有良好的平台无关性。

         注意:所有的布局管理器均是针对容器来使用的,包括顶层容器和中间容器。

 

布局管理器所属类包

所属类包

布局管理器名称

说明

Java.awt

FlowLayout(流式布局)

组件按照加入的先后顺序按照设置的对齐方式从左向右排列,一行排满到下一行开始继续排列

BorderLayout(边界布局)

容器划分为东、西、南、北、中五个区域,每个区域只能放置一个组件。

GridLayout(网格布局)

容器的空间划分成M×N列的网格区域,每个区域只能放置一个组件。

CardLayout(卡片布局)

如同一叠牌,每个牌对应一个组件,但每次只能显示其中的一张牌。适用于在一个空间中防止多个组件的情况

GridBagLayout(网格包布局)

GridLayout的升级版,组件仍然是按照行、列放置,但是每个组件可以占据多个网格

Java.swing

BoxLayout(箱式布局)

允许在容器中纵向或者横向防止多个控件

SprigLayout(弹簧布局)

根据一组约束条件放置控件

空布局

不使用布局管理器,按照控件自身提供的大小、位置信息放置控件

 1.容器的默认布局管理器

各容器都有默认的布局管理,见下表:

容器

默认布局方式

顶层容器

JFrame

BorderLayout(边界布局)

JDialog

BorderLayout(边界布局)

JApplet

FlowLayout(流式布局)

中间容器

JPanel

FlowLayout(流式布局)

 

a.FlowLayout(流式布局)

使用FlowLayout布局方式的容器中组件按照加入的先后顺序按照设置的对齐方式(居中、左对齐、右对齐)从左向右排列,一行排满(即组件超过容器宽度后)到下一行开始继续排列。

流式布局特征如下:

组件按照设置的对齐方式进行排列

不管对齐方式如何,组件均按照从左到右的方式进行排列,一行排满,转到下一行。(比如按照右对齐排列,第一个组件在第一行最右边,添加第二个组件时,第一个组件向左平移,第二个组件变成该行最右边的组件,这就是从左向右方式进行排列)

 

流式布局FlowLayout类的常用构造函数和方法

构造函数

名称

用途

FlowLayout()    

构造一个新的 FlowLayout,它是默认居中对齐的,默认的水平和垂直间隙是5个像素

FlowLayout(int align)

构造一个新的 FlowLayout,它具有指定的对齐方式,默认的水平和垂直间隙是 5个像素

五个参数值及含义如下:

0FlowLayout.lEFT,控件左对齐

1FlowLayout.CENTER,居中对齐

2FlowLayout.RIGHT,右对齐

3FlowLayout.LEADING,控件与容器方向开始边对应

4FlowLayout.TRAILING,控件与容器方向结束边对应

如果是01234之外的整数,则为左对齐

FlowLayout(int align, int hgap, int vgap)     

创建一个新的流布局管理器,它具有指定的对齐方式以及指定的水平和垂直间隙。

方法

名称

用途

Void setAlignment(int align)

设置此布局的对齐方式。

void setHgap(int hgap)

设置组件之间以及组件与 Container的边之间的水平间隙。

void setVgap(int vgap)

设置组件之间以及组件与 Container的边之间的垂直间隙。

 FlowLayout布局应用代码段

1)        设置FlowLayout布局

JFrame  fr=new JFrame( );

FlowLayout  flow=new FlowLayout( );

fr.setLayout(flow);

上面的语句可以简化成:
fr.setLayout(new FlowLayout());

2)        设置框架fr为组件左对齐的FlowLayout布局 

fr.setLayout(newFlowLayout(FlowLayout.LEFT));

3)        设置框架fr为组件左对齐的FlowLayout布局,并且组件的水平间距为20像素,垂直间距为40像素。

fr.setLayout(new FlowLayout(FlowLayout.LEFT,20,40));

实例:对齐方式

// FlowLayoutDemo.java

import javax.swing.*;

import java.awt.*;

publicclassFlowLayoutDemoextends JFrame {

    public FlowLayoutDemo() {

        // 设置窗体为流式布局,无参数默认为居中对齐

        setLayout(new FlowLayout());

        // 设置窗体中显示的字体样式

        setFont(new Font("Helvetica",Font.PLAIN,14));

        // 将按钮添加到窗体中

        getContentPane().add(new JButton("Button 1"));

        getContentPane().add(new JButton("Button 2"));

        getContentPane().add(new JButton("Button3"));

        getContentPane().add(new JButton("Button 4"));

    }

 

    publicstaticvoid main(Stringargs[]) {

        FlowLayoutDemowindow=newFlowLayoutDemo();

        window.setTitle("流式布局");

        // 该代码依据放置的组件设定窗口的大小使之正好能容纳你放置的所有组件

        window.pack();

        window.setVisible(true);

        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        window.setLocationRelativeTo(null);//让窗体居中显示

    }

}

如下7


修改程序代码体会界面布局效果:

setLayout(newFlowLayout());

将上面源程序中的代码更改如下,然后做出如下更改:

setLayout(newFlowLayout(0));  //组件左对齐

setLayout(newFlowLayout(FlowLayout.RIGHT,10,15)); //组件右对齐,组件间水平间距为10像素,垂直间距为15像素

b.边界布局管理器

把容器的的布局分为五个位置:CENTEREASTWESTNORTHSOUTH。依次对应为:上北(NORTH)、下南(SOUTH)、左西(WEST)、右东(EAST),中(CENTER),如下8所示。


特征:

可以把组件放在这五个位置的任意一个,如果未指定位置,则缺省的位置是CENTER

南、北位置控件各占据一行,控件宽度将自动布满整行。东、西和中间位置占据一行;若东、西、南、北位置无控件,则中间控件将自动布满整个屏幕。若东、西、南、北位置中无论哪个位置没有控件,则中间位置控件将自动占据没有控件的位置。

是窗口、框架的内容窗格和对话框等的缺省布局。

 1 常见的构建函数和方法

构造方法摘要

BorderLayout(): 构造一个组件之间没有间距(默认间距为0像素)的新边框布局。

 

BorderLayout(int hgap, int vgap) :  构造一个具有指定组件(hgap为横向间距,vgap为纵向间距)间距的边框布局。

 

方法摘要

int

getHgap()           返回组件之间的水平间距。

int

getVgap()           返回组件之间的垂直间距。

void

removeLayoutComponent(Component comp) 从此边框布局中移除指定组件。

void

setHgap(int hgap)          设置组件之间的水平间距。

void

setVgap(int vgap)           设置组件之间的垂直间距。

 实例:

import javax.swing.*;

import java.awt.*;

 

publicclassBorderLayoutDemoextends JFrame {

    public BorderLayoutDemo() {//构造函数,初始化对象值

        // 设置为边界布局,组件间横向、纵向间距均为5像素

        setLayout(new BorderLayout(5, 5));

        setFont(new Font("Helvetica",Font.PLAIN,14));

        getContentPane().add("North",newJButton("North"));//将按钮添加到窗口中

        getContentPane().add("South",newJButton("South"));

        getContentPane().add("East",new JButton("East"));

        getContentPane().add("West",new JButton("West"));

        getContentPane().add("Center",newJButton("Center"));

    }

 

    publicstaticvoid main(Stringargs[]) {

        BorderLayoutDemof =new BorderLayoutDemo();

        f.setTitle("边界布局");

        f.pack();

        f.setVisible(true);

        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        f.setLocationRelativeTo(null);//让窗体居中显示

    }

}

程序执行结果如下9所示:

c.网格布局

使容器中的各组件呈M×N列的网格状分布。

网格每列宽度相同,等于容器的宽度除以网格的列数。

网格每行高度相同,等于容器的高度除以网格的行数。

各组件的排列方式为:从上到下,从左到右。

组件放入容器的次序决定了它在容器中的位置。

容器大小改变时,组件的相对位置不变,大小会改变。

设置网格布局行数和列数时,行数或者列数可以有一个为零。若rows0cols3,则列数固定为3,行数不限,每行只能放3个控件或容器。若cols0rows3,则行数固定为3,列数不限,且每行必定有控件,若组件个数不能整除行数,则除去最后一行外的所有行组件个数为:Math.ceil(组件个数/rows)

Math.ceil(double x):传回不小于x的最小整数值。比如行数为3,组件数为13,则Math.ceil(13/3)=5,即第一行,第二行组件数各为5个,剩下的组件放在最后一行。

若组件数超过网格设定的个数,则布局管理器会自动增加网格个数,原则是保持行数不变。

 构造方法摘要

GridLayout() 创建具有默认值的网格布局,即每个组件占据一行一列。

GridLayout(int rows, int cols) :

创建具有指定行数和列数的网格布局。Rows为行数,cols为列数。

GridLayout(int rows, int cols, int hgap, int vgap) :

创建具有指定行数、列数以及组件水平、纵向一定间距的网格布局。

 方法摘要

int

getColumns()  :获取此布局中的列数。

int

getHgap():获取组件之间的水平间距。

int

getRows() :获取此布局中的行数。

int

getVgap()  :获取组件之间的垂直间距。

void

removeLayoutComponent(Component comp) :从布局移除指定组件。

void

setColumns(int cols)  :将此布局中的列数设置为指定值。

void

setHgap(int hgap):将组件之间的水平间距设置为指定值。

void

setRows(int rows):将此布局中的行数设置为指定值。

void

setVgap(int vgap) :将组件之间的垂直间距设置为指定值。

String

toString():返回此网格布局的值的字符串表示形式。

 实例:

//GridLayoutDemo.java

import javax.swing.*;

import java.awt.*;

 

publicclassGridLayoutDemoextends JFrame {

    public GridLayoutDemo() {

        setLayout(new GridLayout(0, 2));//设置为网格布局,未指定行数

        setFont(new Font("Helvetica",Font.PLAIN,14));

        getContentPane().add(new JButton("Button 1"));

        getContentPane().add(new JButton("Button 2"));

        getContentPane().add(new JButton("Button 3"));

        getContentPane().add(new JButton("Button 4"));

        getContentPane().add(new JButton("Button 5"));

    }

 

    publicstaticvoid main(Stringargs[]) {

        GridLayoutDemof =new GridLayoutDemo();

        f.setTitle("GridWindow Application");

        f.pack();

        f.setVisible(true);

        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        f.setLocationRelativeTo(null);//让窗体居中显示

    }

}

程序结果如下10所示:

 

布局一个简单的计算器

思路:对窗体应用边界布局,在NORTH上放置一个文本框,在CENTER上放置一个面板,面板上放置计算器的相应按钮

import java.awt.*;

import javax.swing.*;

 

classGridFrameextends JFrame {

    // 定义面板,并设置为网格布局,44列,组件水平、垂直间距均为3

    JPanelp =new JPanel(new GridLayout(4, 4, 3,3));

    JTextAreat =new JTextArea();//定义文本框

    // 定义字符串数组,为按钮的显示文本赋值

    // 注意字符元素的顺序与循环添加按钮保持一致

    Stringstr[]= {"7","8","9","/","4","5","6","*","1","2","3","-","0",".","=","+"};

 

    public GridFrame(Strings) {

        super(s);//为窗体名称赋值

        setLayout(new BorderLayout());//定义窗体布局为边界布局

        JButtonbtn[];//声明按钮数组

        btn = new JButton[str.length];//创建按钮数组

        // 循环定义按钮,并添加到面板中

        for (inti = 0;i <str.length;i++) {

            btn[i] = new JButton(str[i]);

            p.add(btn[i]);

        }

        // 将文本框放置在窗体NORTH位置

        getContentPane().add(t, BorderLayout.NORTH);

        // 将面板放置在窗体CENTER位置

        getContentPane().add(p, BorderLayout.CENTER);

        setVisible(true);

        setSize(250,200);

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        setLocationRelativeTo(null);//让窗体居中显示

    }

 

    publicstaticvoid main(String[]args) {

        GridFramegl=newGridFrame("网格布局计算机!");

    }

}

 程序执行结果如下11

 

              通过字符串数组和循环添加按钮的方法,以后添加菜单以及事件处理均采用这种方法,这种方法的好处在于,如果需要修改按钮顺序,直接修改字符串就可以了。而不需要改动添加按钮的代码。

 d.卡片布局

能够让多个组件共享同一个显示空间,共享空间的组件之间的关系就像一叠牌,组件叠在一起,初始时显示该空间中第一个添加的组件,通过CardLayout类提供的方法可以切换该空间中显示的组件。

 1  CardLayout类的常用构造函数及方法

如下12 


使用CardLayout类提供的方法可以切换显示该空间中的组件

1      定义使用卡片布局的容器

例如:PanelcardPanel=new Panel();

2      定义卡片对象:CardLayout 布局对象名称=new CardLayout();

例如:CardLayoutcard=new CardLayout();

3      设置使用卡片布局的容器为卡片布局:

格式:容器名称.setLayout(布局对象名称);

例如:cardPanel.setLayout(card);

4      设置容器中显示的组件

例如:for(int i = 0; i < 5; i++) {

                           cardPanel.add(newJButton("按钮"+i));

                  }

5      定义响应事件代码,让容器显示相应的组件

格式:

布局对象名称.next(容器名称)  显示容器中当前组件之后的一个组件,若当前组件为最后添加的组件,则显示第一个组件,即卡片组件显示是循环的。

布局对象名称.first(容器名称)  显示容器中第一个组件

布局对象名称.last(容器名称)  显示容器中最后一个组件

布局对象名称.previous(容器名称)  显示容器中当前组件之前的一个组件,若当前组件为第一个添加的组件,则显示最后一个组件,即卡片组件显示是循环的。

例如:

card.next(cardPanel);

card.previous(cardPanel);

        card.first(cardPanel);      

        card.last(cardPanel);      

 卡片的切换

窗体默认边界布局,一个面板以卡片布局,面板上添加五个按钮,该面板添加到CENTER位置,另一个面板添加两个按钮,两个按钮添加事件来切换显示CENTER位置中的面板的组件 

import java.awt.*;

import javax.swing.*;

import java.awt.event.*;//引入事件包

//定义类时实现监听接口

publicclasscardlayoutextends JFrameimplements ActionListener {

    JButtonnextbutton;

    JButtonpreButton;

    PanelcardPanel=newPanel();

    PanelcontrolpaPanel=newPanel();

    // 定义卡片布局对象

    CardLayoutcard=newCardLayout();

    // 定义构造函数

    public cardlayout() {

        super("卡片布局管理器");

        setSize(300,200);

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        setLocationRelativeTo(null);

        setVisible(true);

        // 设置cardPanel面板对象为卡片布局

        cardPanel.setLayout(card);

        // 循环,在cardPanel面板对象中添加五个按钮

        // 因为cardPanel面板对象为卡片布局,因此只显示最先添加的组件

        for (inti = 0;i < 5;i++) {

            cardPanel.add(new JButton("按钮" +i));

        }

        // 实例化按钮对象

        nextbutton = new JButton("下一张卡片");

        preButton = new JButton("上一张卡片");

        // 为按钮对象注册监听器

        nextbutton.addActionListener(this);

        preButton.addActionListener(this);

        controlpaPanel.add(preButton);

        controlpaPanel.add(nextbutton);

        // 定义容器对象为当前窗体容器对象

        Containercontainer= getContentPane();

        // cardPanel面板放置在窗口边界布局的中间,窗口默认为边界布局

        container.add(cardPanel, BorderLayout.CENTER);

        // controlpaPanel面板放置在窗口边界布局的南边,

        container.add(controlpaPanel, BorderLayout.SOUTH);

    }

    // 实现按钮的监听触发时的处理

    publicvoidactionPerformed(ActionEvente) {

        // 如果用户单击nextbutton,执行的语句

        if (e.getSource() ==nextbutton) {

            // 切换cardPanel面板中当前组件之后的一个组件

            // 若当前组件为最后添加的组件,则显示第一个组件,即卡片组件显示是循环的。

            card.next(cardPanel);

        }

        if (e.getSource() ==preButton) {

            // 切换cardPanel面板中当前组件之前的一个组件

            // 若当前组件为第一个添加的组件,则显示最后一个组件,即卡片组件显示是循环的。

            card.previous(cardPanel);

        }

    }

    publicstaticvoid main(String[]args) {

        cardlayoutkapian=newcardlayout();

    }

}

程序显示结果如下图所示,单击上一张下一张等按钮可以上面的面板中显示不同的按钮来。如下13


1      定义使用卡片布局的容器

例如:PanelcardPanel=new Panel();

2      定义卡片对象:CardLayout布局对象名称=newCardLayout();

例如:CardLayoutcard=new CardLayout();

3      设置使用卡片布局的容器为卡片布局:

格式:容器名称.setLayout(卡片对象名称);

例如:cardPanel.setLayout(card);

4      设置容器中显示的组件,同时为组件命名对应的卡片名称

格式容器名称. Add(卡片名称,组件名称)

例如:for(int i = 0; i < 4; i++) {

                           cardPanel.add(“0”,newJButton("按钮"+i));

                  }

5      定义响应事件代码,让容器显示相应的组件

格式:卡片对象名称.show(容器名称,卡片名称)

例如:card.show(cardPanel,”0”);

使用CardLayout类的show方法显示组件。

窗体默认边界布局,一个面板以卡片布局,面板上添加4个按钮,该面板添加到CENTER位置,另一个面板添加4个按钮,这4个按钮添加事件来切换显示CENTER位置中的面板的组件按钮。

import java.awt.*;

import javax.swing.*;

import java.awt.event.*;//引入事件包

//定义类时实现监听接口

publicclasscardlayout1extends JFrameimplements ActionListener{

         JButton b0,b1,b2,b3;

   Panel cardPanel=new Panel();

   Panel controlpaPanel=new Panel();

         //定义卡片布局对象

   CardLayout card=new CardLayout();

         //定义字符数组,为卡片命名

         String cardName[]={"0","1","2","3"};

         //定义构造函数

         public cardlayout1() {

                   super("卡片布局管理器");

                   setSize(400,200);

                  setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                   setLocationRelativeTo(null);

                   setVisible(true);

                    //设置cardPanel面板对象为卡片布局

                   cardPanel.setLayout(card);   

                    //循环,在cardPanel面板对象中添加4个按钮

                   //因为cardPanel面板对象为卡片布局,因此初始时显示最先添加的组件

                   for (inti = 0;i< 4;i++) {

                            //面板中添加的每个按钮对应设置一个卡片名

                            cardPanel.add(cardName[i],new JButton("按钮"+i));

                   }

                   //实例化按钮对象

                   b0=new JButton("0");

                   b1=new JButton("1");

                   b2=new JButton("2");

                   b3=new JButton("3");

                    //为按钮对象注册监听器

                   b0.addActionListener(this);

                   b1.addActionListener(this);

                   b2.addActionListener(this);

                   b3.addActionListener(this);

                   controlpaPanel.add(b0);

                   controlpaPanel.add(b1);

                   controlpaPanel.add(b2);

                   controlpaPanel.add(b3);

                   //定义容器对象为当前窗体容器对象

                   Container container=getContentPane();

                    // cardPanel面板放置在窗口边界布局的中间,窗口默认为边界布局

                   container.add(cardPanel,BorderLayout.CENTER);

                   // controlpaPanel面板放置在窗口边界布局的南边,

                   container.add(controlpaPanel,BorderLayout.SOUTH);

         }

         //实现按钮的监听触发时的处理

         publicvoid actionPerformed(ActionEvente){

                   //用户单击b0按钮时执行的语句

                   if(e.getSource()==b0){

                            //通过show()方法中的卡片名称,显示容器中的组件。

                            card.show(cardPanel,cardName[0]);    

                   }

                   if(e.getSource()==b1){

                            card.show(cardPanel,cardName[1]);    

                   }

                   if(e.getSource()==b2){

                            card.show(cardPanel,cardName[2]);    

                   }

                   if(e.getSource()==b3){

                            card.show(cardPanel,cardName[3]);    

                   }

         }

         publicstaticvoid main(String[]args) {

                   cardlayout1 kapian=new cardlayout1();

                 

         }

 }

 程序执行结果如下14


  一般容器都有默认布局方式,但是有时候需要精确指定各个组建的大小和位置,就需要用到空布局。

         操作方法:

1)      首先利用setLayout(null)语句将容器的布局设置为null布局(空布局)。

2)      再调用组件的setBounds(int x, int y, int width,int height)方法设置组件在容器中的大小和位置,单位均为像素。

x为控件左边缘离窗体左边缘的距离

y为控件上边缘离窗体上边缘的距离

width为控件宽度

height为控件高度 

实例:使用空布局精确定位组件的位置

importjava.awt.*;

import javax.swing.*;

 

publicclassNullLayoutDemo {

    JFramefr;

    JButtona,b;

 

    NullLayoutDemo(){

        fr = new JFrame();

        fr.setBounds(100, 100,250, 150);

        // 设置窗体为空布局

        fr.setLayout(null);

        a = new JButton("按钮a");

        b = new JButton("按钮b");

        fr.getContentPane().add(a);

        // 设置按钮a的精确位置

        a.setBounds(30, 30, 80,25);

        fr.getContentPane().add(b);

        b.setBounds(150, 40, 80,25);

        fr.setTitle("NullLayoutDemo");

        fr.setVisible(true);

        fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        fr.setLocationRelativeTo(null);//让窗体居中显示

    }

    publicstaticvoid main(Stringargs[]) {

        new NullLayoutDemo();

    }

} 

程序运行结果如下15

 

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐