Java桌面程序开发第4章 容器与布局
- 格式:ppt
- 大小:1.07 MB
- 文档页数:16
第4章图形用户界面设计本章要点● Java图形用户界面设计的基本知识●布局管理器的应用● Java常用图形用界面设计组件的应用● Java常用组件事件处理的应用4.1 认识AWT包和Swing包用户界面是计算机用户与软件之间的交互接口。
一个功能完善,使用方便的用户界面可以使软件的操作更加简单,使用户与程序之间的交互更加有效。
因此图形用户界面(graphics user interface,GUI)的设计和开发已经成为软件开发中的一项重要的工作。
Java语言提供的开发图形用户界面(GUI)的功能包括AWT(Abstract Window Toolkit)和Swing两部分。
这两部分功能由Java的两个包来完成-awt和swing。
虽然这两个包都是用于图形用户界面的开发,但是它们不是同时被开发出来了。
awt包是最早被开发出来的。
但是使用awt包开发出来的图形用户界面并不完美,在使用上非常的不灵活。
比如awt包所包含的组件,其外观是固定的,无法改变,这就使得开发出来的界面非常死板。
这种设计是站在操作系统的角度开发图形用户界面,主要考虑的是程序与操作系统的兼容性。
这样做的最大问题就是灵活性差,而且程序在运行时还会消耗很多系统资源。
由于awt包的不足表现,SUN公司于1998年针对它存在的问题,对其进行了扩展,开发出了Swing,即swing包。
但是,SUN公司并没有让swing包完成替代awt包,而是让这两个包共同存在,互取所需。
awt包虽然存在缺点,但是仍然有可用之处,比如在图形用户界面中用到的布局管理器、事件处理等依然采用的是awt包的内容。
Java有两个主要类库分别是Java包和Javax包。
在Java包中存放的是Java语言的核心包。
Javax包是Sun公司提供的一个扩展包,它是对原Java包的一些优化处理。
swing包由于是对awt包的扩展和优化,所以是存放在Javax包下的,而awt包是存放在Java包下的。
java布局中的BoxLayout布局,使⽤BoxLayout进⾏Swing布局在⽤户使⽤ Java Swing 进⾏⽤户界⾯开发过程中,会碰到如何对 Java Swing 的控件进⾏布局的问题。
Swing 的控件放置在容器(Container) 中,容器就是能够容纳控件或者其它容器的类,容器的具体例⼦有 Frame、Panel 等等。
容器需要定义⼀个布局管理器来对控件进⾏布局管理,Swing 当中提供的主要的布局管理器有 FlowLayout、BorderLayout、BoxLayout、GridLayout 和 GridBaglayout, 它们的主要特点如表 1 所⽰:表 1. Swing 中的⼀些主要布局管理器的⽐较布局管理器特点FlowLayout把控件按照顺序⼀个接⼀个由左向右的⽔平放置在容器中,⼀⾏放不下,就放到下⼀⾏BorderLayout将整个容器划分成东南西北中五个⽅位来放置控件,放置控件时需要指定控件放置的⽅位BoxLayout可以指定在容器中是否对控件进⾏⽔平或者垂直放置,⽐ FlowLayout 要更为灵活GridLayout将整个容器划分成⼀定的⾏和⼀定的列,可以指定控件放在某⾏某列上GridBagLayout是 Swing 当中最灵活也是最复杂的布局管理器,可对控件在容器中的位置进⾏⽐较灵活的调整本⽂主要关注在 BoxLayout 布局管理器的使⽤上。
我们⾸先对 BoxLayout 作⼀下介绍。
BoxLayout 介绍如前所述,BoxLayout 可以把控件依次进⾏⽔平或者垂直排列布局,这是通过参数 X_AXIS、Y_AXIS 来决定的。
X_AXIS 表⽰⽔平排列,⽽ Y_AXIS 表⽰垂直排列。
BoxLayout 的构造函数有两个参数,⼀个参数定义使⽤该 BoxLayout 的容器,另⼀个参数是指定 BoxLayout 是采⽤⽔平还是垂直排列。
下⾯是⼀个创建 BoxLayout 实例的例⼦:JPanel panel=new JPanel();BoxLayout layout=new BoxLayout(panel, BoxLayout.X_AXIS);panel.setLayout(layoout);在这个例⼦中,⼀个 BoxLayout 布局管理器的实例 layout 被创建,这个实例被设置为 panel 的布局管理器,该布局管理器采⽤了⽔平排列来排列控件。
Java开发桌⾯程序学习(⼆)————fxml布局与控件学习JavaFx项⽬新建完项⽬,我们的项⽬有三个⽂件Main.java 程序⼊⼝类,载⼊界⾯并显⽰Controller.java 事件处理,与fxml绑定Sample.fxml 界⾯sample.fxml需要通过标签fx:controller定义对应的controller<!-- 最外层的那个布局使⽤fx:controller属性即可 --><FlowPane fx:controller="sample.Controller" ..></FlowPane>专业术语舞台(Stage),场景(Scene),容器(Container),布局(Layout )和控件(Controls)之间的关系常⽤容器(布局)Container可以把容器和布局统⼀成⼀个概念Vbox相当于垂直⽅向LinearLayoutHbox相当于垂直⽅向的LinearLayoutFlowPanel相当于LinearLayout,⽅向可以定义⽔平或者垂直,设置⽔平⽅向,第⼀⾏排满之后,会⾃动换⾏排列,设置垂直⽅向,第⼀列排满之后,会⾃动换下⼀列BorderPane上中下左右五个部分AnchorPane相当于Android⾥⾯的约束布局,⽐如让某个控件离右边100px,离下边100pxScrollPane 滑动的布局GridPane 通常⽤于这样的布局:第⼀列上的只读标签的输⼊表单和第⼆列上的输⼊字段,也就是常⽤的⽤户名后⾯加⼀个输⼊框常⽤控件(Control)默认的为原⽣的,JFX前缀则是Jfoenix⾥⾯的⽂本labelJFXPasswordField 密码框JFXTextField 单⾏输⼊框JFXTextArea 多⾏输⼊框按钮JFXButton选择框JFXCheckboxJFXRadioButtonMenuButton 下拉选择图⽚ImageView进度条JFXProcessbarJFXSlider ⽔平调节,类似按下⾳量键出现横线JFXSpinner 圆圈进度条开关JFXToggleButton列表JFXListView菜单MenuBar ⾃带有⿏标滑过变⾊,就像SceneBuilder的菜单栏MenuMenuItemRadioMenuItem 点击之后前⾯会有√,⼀列菜单可以有多个,但是只能选择⼀个RadioMenuItem,RadioMenuItem之间是互斥的,需要使⽤toggleGroup分为同⼀组CheckMenuItem 多选,⼀列菜单有多个,也可以选多个ToggleGroup toggleGroup = new ToggleGroup();RadioMenuItem radioItem1 = new RadioMenuItem("Option 1");radioItem.setOnAction(new EventHandler<ActionEvent>() {@Override public void handle(ActionEvent e) {System.out.println("radio toggled");}});radioItem1.setToggleGroup(toggleGroup);RadioMenuItem radioItem2 = new RadioMenuItem("Option 2");radioItem.setOnAction(new EventHandler<ActionEvent>() {@Override public void handle(ActionEvent e) {System.out.println("radio toggled");}});radioItem2.setToggleGroup(toggleGroup);SeparatorMenuItem 分割线**前⾯需要在添加到MenuBar⾥⾯才能使⽤ **SpiltMenuButton 左边是某个按钮,右边是⼀个下拉箭头,点击左边,就会实现按钮操作,点击右边,在出现的列表中选择某⼀项,就可以改变左边按钮使⽤SceneBuilder⽣成fxml布局由于现有的⼯具不多,只有个界⾯化的⼯具,所以就不过多去研究fxml代码部分了。
Java图形用户界面2—布局管理器在Java中组件的摆放位置和大小是由布局管理器来决定的,容器对布局管理器的特定实例保持着一个引用,当容器要定位一个组件的时候,它将调用布局管理器来决定。
我们在设置组件的大小的时候,也是通过这个完成的。
在Java中给我提供了五种布局管理器。
BoraderLayout边界布局管理器,FlowLayout浮动布局管理器,GridLayout网格布局管理器,CardLayout卡片布局管理器,GridBagLayout布局管理器。
在Java中FlowLayout是Panel容器的默认管理器,其组件的放置规律是从上到下,从左到又。
BoarderLayout是Window、Frame和Dialog的默认布局管理器。
下面我们先说一下BoarderLayout布局管理器。
下面有张图片:通过上面的图片我们可以看出来,BoarderLayout将容器分成了五个区域:North、South、East、West和Center。
每一个区域可以用来放置一个组件。
如果只有一个组件,默认的是放置在Center中。
下面我们看一个例子程序:在上面的程序中,我们可以看到在我们创建Frame后必须设置一些参数,这些参数在程序中注释已经显示其作用了,但是Frame的设置并不只有这些,读者可以自己根据Java帮助文档详细的学习。
在上面程序执行完成之后就是按照第一张图片给的位置摆放这些按钮的,但是这些按钮之间没有空隙,有时候我们想让按钮之间有空隙,我们可以将14行的代码注释取消,表示的产生2个像素的空隙。
FlowLayot布局管理器,是所有的组件浮动的填充在容器中,我们看一个例子:上面程序的运行结果如下图:如果我们改变窗口的大小,相应的组件的位置也会发生改变,读者可以自己试一下。
对于FlowLayout还提供了按钮的对齐方式,例如我们程序中的第15行代码,就是设置了左对齐的方式,如果我们取消注释,这些按钮将会从左边依次摆放。
1.布局对于JFrame窗口,默认布局是BorderLayout布局。
对于JPanel,默认布局是FlowLayout布局。
容器可以使用方法:setLayout(布局对象);来设置自己的布局。
(1)FlowLayout布局FlowLayout类创建的对象称做FlowLayout型布局。
FlowLayout类的一个常用构造方法如下:FlowLayout()该构造方法可以创建一个居中对齐的布局对象。
例如:FlowLayout flow=new FlowLayout();如果一个容器con使用这个布局对象:con.setLayout(flow);那么,con可以使用Container类提供的add方法将组件顺序地添加到容器中,组件按照加入的先后顺序从左向右排列,一行排满之后就转到下一行继续从左至右排列。
FlowLayout布局对象调用flow.setAlignment(FlowLayout.LEFT);来设置组件靠左对齐FlowLayout布局对象调用setHgap(int hgap) 方法和setVgap(int vgap)可以重新设置布局的水平间隙和垂直间隙。
(2)BorderLayout布局BorderLayout 布局是Window型容器的默认布局,例如JFrame、JDialog都是Window类的间接子类,它们的默认布局都是BorderLayout 布局。
容器使用BorderLayout 布局,那么容器空间简单地划分为东、西、南、北、中五个区域。
每加入一个组件都应该指明把这个组件添加在哪个区域中,区域由BorderLayout中的静态常量CENTER、NORTH、SOUTH、WEST、EAST表示.添加到某个区域的组件将占据整个这个区域。
每个区域只能放置一个组件,如果向某个已放置了组件的区域再放置一个组件,那么先前的组件将被后者替换掉。
(3)CardLayout 布局使用CardLayout 的容器可以容纳多个组件,但是实际上同一时刻容器只能从这些组件中选出一个来显示,这个被显示的组件将占据所有的容器空间。
附:实验源程序代码import java.awt.BorderLayout;import java.awt.Font;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JPanel;class Frame1 extends JFrame //设计一个窗体类{JButton jb1, jb2, jb3; //按钮JLabel jl; //标签Frame1() //构造方法{jb1 =new JButton("红色"); //创建按钮对象jb2 = new JButton("绿色") ;jb3 = new JButton("蓝色") ;jl = new JLabel("设定标签颜色") ; //创建标签对象jl.setFont(new Font("隶书", Font.PLAIN, 32)); //标签字体JPanel jp1 = new JPanel(); //面板1JPanel jp2 = new JPanel(); //面板2jp1 .add(jl); //标签放入面板1jp2 .add(jb1); //三个按键放入面板2jp2 .add(jb2);jp2 .add(jb3);setLayout( new BorderLayout() ); //窗体设定为边界布局add(jp1, BorderLayout.NORTH ) ; //标签面板放在窗体上端add(jp2, BorderLayout.CENTER ); //按钮面板放在窗体中间setSize(250,150) ; //设定窗体大小和位置setTitle("实验6-1") ; //设定窗体标题setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setVisible(true) ; //设定窗体可见}}class Experiment9_1{public static void main(String[] args){new Frame1();}}import javax.swing.*;import java.awt.*;class Framel extends JFrame{JButton submit;JLabel lb_id,lb_name,lb_sex,lb_ty,lb_bj,lb_desc;JTextField jtf_id,jtf_name;JRadioButton male,female;JCheckBox ck_ty;JComboBox cb_bj;JTextArea txta_desc;Framel(){lb_id = new JLabel("学号:",JLabel.RIGHT);lb_name = new JLabel("姓名:",JLabel.RIGHT);lb_sex = new JLabel("性别:",JLabel.RIGHT);lb_ty = new JLabel("团员",JLabel.RIGHT);lb_bj = new JLabel("班级",JLabel.RIGHT);lb_desc = new JLabel("简介",JLabel.RIGHT);jtf_id = new JTextField(12);jtf_name = new JTextField(12);male = new JRadioButton("男");female = new JRadioButton("女");ck_ty = new JCheckBox();txta_desc = new JTextArea(5,11);male.setSelected(true);ButtonGroup bg_sex = new ButtonGroup();bg_sex.add(male);bg_sex.add(female);String items[] = {"网络信息1011","软件1011","系统维护1011"};cb_bj = new JComboBox(items);JPanel jtf = new JPanel();JPanel jtf2 = new JPanel();JPanel jtf3 = new JPanel();JPanel jtf4 = new JPanel();JPanel jtf5 = new JPanel();jtf.add(lb_id);jtf.add(jtf_id);jtf2.add(lb_name);jtf2.add(jtf_name);jtf3.add(lb_sex);jtf3.add(male);jtf3.add(female);jtf3.add(lb_ty);jtf3.add(ck_ty);jtf4.add(lb_bj);jtf4.add(cb_bj);jtf5.add(lb_desc);jtf5.add(txta_desc);setLayout(new BoxLayout(this.getContentPane(), BoxLayout.Y_AXIS));add(jtf);add(jtf2);add(jtf3);add(jtf4);add(jtf5);JPanel jp_submit = new JPanel();submit = new JButton("确定");jp_submit.add(submit);add(jp_submit);}}public class Experiment9_2{public static void main(String[] args){Framel f = new Framel();f.setLocation(200,100);f.setVisible(true);f.setTitle("实验6_2");f.setSize(250,300);f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);}}实验三:import java.awt.GridLayout;import javax.swing.BoxLayout;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JPanel;import javax.swing.JTextField;class Frame3 extends JFrame{Frame3(){setLayout(new BoxLayout(this.getContentPane(),BoxLayout.Y_AXIS));JPanel jp1=new JPanel();JPanel jp2=new JPanel();JButton jb[]=new JButton[16];jp1.add(new JTextField(20));add(jp1);jp2.setLayout(new GridLayout(4,4,5,5));for(int i=0;i<10;i++)jb[i]=new JButton(""+i);jb[10] = new JButton(".");jb[11] = new JButton("1/x");jb[12] = new JButton("C");jb[13] = new JButton("√");jb[14] = new JButton("㎡");jb[15] = new JButton("㏒");for(int i=1;i<4;i++)jp2.add(jb[i]);jp2.add(jb[12]);for(int i=4;i<7;i++)jp2.add(jb[i]);jp2.add(jb[13]);for(int i=7;i<10;i++)jp2.add(jb[i]);jp2.add(jb[14]);jp2.add(jb[0]);jp2.add(jb[10]);jp2.add(jb[11]);jp2.add(jb[15]);add(jp2);setVisible(true);pack();setTitle("实验6-3");setLocation(300,400);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);}public static void main(String[] args){new Frame3();}}。