Swing和AWT概念
Swing和AWT是javaGUI编程中的工具包,也是java基础类的一部分,主要的功能就包括实现窗口的布局和管理功能,包中含有JTextFiled,JFrame,JButton等多种GUI编程需要使用到的类。最大的特点就是由纯java编写,拥有跨平台的特点。Swing与AWT的区别在于:Swing拥有统一的风格,不依赖于操作系统,AWT依赖于操作系统且风格不统一。
首先先熟悉一下AWT包和Swing包之间的关系,如下图:
监听事件
监听事件就是对一个控件增加对应的功能,系统能够自动的执行相应的方法。监听事件分为很多类,这里讲述两种类型,一种是动作监听事
件,一种是焦点监听事件。使用代码看时最为直观的。
动作监听事件
对一个按钮控件添加动作监听事件(使用addAcitonListener(ActionListener l)方法,参数传递为new ActionListener(),新建一个对象)
后续必须重写void actionPerformed(ActionEvent e)方法,这个方法是自动调用的,和线程的Run方法类似。实现当点击按钮控件时输出该控件的名称。
代码
public void test1(){
JButton btn = new JButton("hello");
Container c = getContentPane();
c.setLayout(new FlowLayout());
btn.setSize(100,50);
c.add(btn);
btn.addActionListener(new ActionListener() {
// 给按钮增加一个监听
@Override
public void actionPerformed(ActionEvent e) {
System.out.println(btn.getText());
// 输出该按钮的名称
}
});
}
窗体显示为:
控制台显示:
焦点监听事件
对一个控件使用焦点监听事件,需要使用addFocusListener(FocusListener l)方法,然后进行重写方法*void focusGained(FocusEvent e)*获得焦点时调用,*void focusLost(FocusEvent e)*失去焦点时调用。与动作监听事件类似。从代码看更加的直观。
代码
实现三个文本框位于一个窗体中,当光标不放置在文本框时显示“失去光标”。
// 使用一个类来实现FocusListener接口,然后重写其方法,方便后续调用
class hello implements FocusListener{
@Override
public void focusGained(FocusEvent e) {
JTextField j = (JTextField) e.getSource();
j.setText("");
}
@Override
public void focusLost(FocusEvent e) {
JTextField j = (JTextField) e.getSource();
j.setText("失去光标");
}
}
主类
public class ActionFocus extends JFrame {
public ActionFocus(){
// 撰写窗体
setDefaultCloseOperation(3);
setSize(300,200);
setLocationRelativeTo(null);
Container c = getContentPane();
c.setLayout(new FlowLayout());
// 撰写文本框三个
JTextField j1 = new JTextField("");
j1.setLocation(20,0);
j1.setColumns(20);
JTextField j2 = new JTextField("");
j2.setLocation(40,0);
j2.setColumns(20);
JTextField j3 = new JTextField("");
j3.setLocation(60,0);
j3.setColumns(20);
// 文本框都增加监听事件
j1.addFocusListener(new hello());
j3.addFocusListener(new hello());
j2.addFocusListener(new hello());
// 容器添加控件
c.add(j1);
c.add(j2);
c.add(j3);
c.validate();
setVisible(true);
}
public static void main(String xx[]){
new ActionFocus();
}
}
效果展示:
当光标放置在第三个文本框时,前两个文本框会显示失去光标。
Swing中常用的组件
(一)常用的组件包括
- JFrame(窗体)
- JDialog(对话框)
- JPanel(面板)
- JButton(按钮)
- JTextField(文件框)
- JTextArea(文本域)
- JLable(标语)
- JComboBox(下拉菜单)
- JList(列表)
- JPassword(密码框)
(二)JFrame、JDialog、JPanel
JFrame、JDialog、JPanel三个类的区别如下图
JPanel是一个面板,JFrame是一个带有扩大按钮的面板,JDialog是没有带有扩大按钮的面板。
JFrame类概念:JFrame是一个带有缩小、放大、关闭按钮的窗体,通常使用实例化一个对象来进行其操作,对其进行详细的操作。或者使用一个类继承该类,在对这个类进行操作,然后主类实现该类达到目的。
JFrame类的常用方法有:
void setTitle(String title):设置窗体的名字(会显示在窗体的上方)。
void setDefaultCloseOperation(int operation):设置关闭的方式,对于该方法存在几个常用的参,JFrame.DO_NOTHING_ON_CLOSE,数值为0,意思为不关闭窗口也不关闭程序;JFrame.DISPOSE_ON_CLOSE,数值为2,意思为释放窗体资源;JFrame.HIDE_ON_CLOSE,数值为1,意思是关闭窗体,但是不关闭程序;JFrame.EXIT_ON_CLOSE,数值为3,意思是关闭窗体也关闭程序。
void setBounds(int x, int y, int width, int height):设置窗体的初始位置和窗体的大小,x,y代表的水平和垂直坐标,width,height代表的是宽度和高度。单位均为像素。
void setVisible(boolean b):设置窗体是否可见,为true时可见,为false时不可见。
void setResizable(boolean resizable):设置窗体是否可修改(拉伸),为true时可以,false不可以。
void setBackground(Color c):设置窗体的背景颜色。
void setContentPane(Container contentPane):给窗体附上容器。
下面展示一个代码:
public class Jframe extends JFrame {
public Jframe (){
setTitle("JFrame窗体");// 设置窗体的名字
/*
EXIT_ON_CLOSE:关闭只会退出程序
DISPOSE_ON_CLOSE:释放窗体资源
DO_NOTHING_ON_CLOSE:不可以关闭程序,同时窗体也不会消失
HIDE_ON_CLOSE:关闭结束窗体,但是程序没有结束
*/
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// setSize(400,400);// 设置窗体的大小
// setLocation(500,500);// 设置窗体初始化的位置
setBounds(300,300,400,400);// 前面两个参数为窗体的位置,后两个参数为窗体的大小
setVisible(true);// 窗体是否可见
setResizable(false);// 窗体是否可拉伸
Container c = getContentPane();// 获取窗体的容器对象
c.setBackground(Color.yellow);// 设置容器的背景颜色
JLabel l = new JLabel("这是第一次的尝试");// 设置标签
c.add(l);// 增加控件
// c.remove(l);// 删除控件
c.validate();// 容器刷新控件
setContentPane(c);// 刷新容器
}
public static void main(String xx[]){
new Jframe();
}
}
成果展示:
这里涉及到Container类(容器),getContenPane()方法的作用就是返回一个当前窗体的Container对象,目的是获取当前的窗体的容器,将容器的控件放置到窗体上去。调用add方法就可以添加控件,而代码中的c.validate()方法就是将容器中的控件进行刷新。
JDialog类
JDialog类是一个只有关闭按钮的对话框。一般在JFrame类的基础之上使用,基本的使用方法和JFrame一致。
下面展示一段代码
public class JDialog extends javax.swing.JDialog {
public JDialog(JFrame j){
super(j,"标题",true);
// 设置阻塞的方式,public JDialog(Frame owner, String title, boolean modal);owner代表父窗体,title代表JDialog的名字
// modal代表是否阻塞窗体
setBounds(100,100,100,100);
Container c = getContentPane();
JLabel i = new JLabel("hello world");
c.add(i);
c.validate();// 刷新控件
}
public static void main(String xx[]){
JFrame j = new JFrame("窗体1");
j.setVisible(true);// 窗体可见
j.setBounds(200,200,300,300);
Container c = j.getContentPane();
JButton jb = new JButton("点击一下");
j.setLayout(new FlowLayout());// 设置流式布局
c.add(jb);
j.setDefaultCloseOperation(3);// 3代表的是EXIT_ON_CLOSE
jb.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
new JDialog(j).setVisible(true);
}
});
}()
}
成果展示:
显示的画面为,首先弹出名字为窗体1的窗体,点击中间的按钮,会弹出来一个名字为“标题”的对话框,显示文字“hello world”,这个期间是无法进行下一步的操作,只可以先进行标题对话框的处理。这里出现了一个新的方法setLayout(new FlowLayout()),意思为给一个容器设置一个布局,为流式布局,这个后面会说。addActionListener()这个方法是设置一个监听,后续也会详细的说明。还有就是在JDialog构造方法中调用一个super(Frame owner, String title, boolean modal)方法,这个方法里的参数,owner代表的是父窗口,title代表的是Dialog窗口的名字,modal代表是否对父窗口进行阻塞,为true则进行阻塞,为false则不阻塞。
JPanel类常用于在窗口和对话框之上进行修饰,这里就不做多的描述了。
(三)JLable
JLable是标签类,在窗体中显示的就是一排文字的效果。
常用的方法如下:
void setFont(Font font):设置标签的字体,参数是一个Font类对象。
void setForeground(Color fg):设置字体的颜色。
void setText(String text):设置标签的默认文本。
下面展示一段代码:
public class Jlabel extends JFrame {
public Jlabel(){
setTitle("JLabel的尝试");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100,100,400,100);
setVisible(true);
Container c = getContentPane();
/* * * 分界线 * * */
JLabel j = new JLabel("hello world");
c.add(j);
j.setText("我是小王子");// 重置文本
j.setFont(new Font("楷体",Font.BOLD,20));// 设置字体样式
j.setForeground(Color.getColor("yellow"));// 标签字体的颜色
}
public static void main(String xx[]){
new Jlabel();
}
}
成果展示:
在一个窗体中显示一个文字标签,“我是小王子”。标签的字体楷体,20号,加粗。
使用JLable实现窗体中出现一张图片(展示具体的方法):
public void getImage(){
JFrame j = new JFrame("图片提示器");
Container c = j.getContentPane();
j.setDefaultCloseOperation(3);
j.setBounds(200,200,500,500);
j.setVisible(true);
JLabel jb = new JLabel();
c.add(jb);
Icon icon = new ImageIcon("D:/javaFileText2/menglin.jpg");
System.out.println(icon.getIconHeight()+":"+icon.getIconWidth()); // 输出图片的长宽
// j.setSize(200,200);// 改变标签的大小,也不会改变图片的大小,只会改变标签的显示大小
jb.setIcon(icon);// 标签加上图片
}
成果展示:
这里就涉及到了一个新的知识点,Icon接口和ImageIcon类(图标类),以后详细的了解之后会再写一次博客解释这个类,目前知识简略的了解一下;实例化图标类的对象传入的参数为图片的地址,分为图片的绝对路径和相对路径;JLable类的void setIcon(Icon icon)方法就是将图标类加入到标签中去。但是值得注意的就是标签上加入图片之后,图片的大小不会随着标签的大小进行改变。如果标签的大小小于图片的大小,那么只会显示部分的图片。
(四)JTextField
JTextField是一个文本框类,可以进行字符的撰写。常用的方法为:
void setFocusable(boolean focusable) :是否增加光标。
void setText(String t):设置文本初始内容。
void setColumns(int columns):设置文本框的列数。
public class JTxtTest extends JFrame {
public JTxtTest(){
setDefaultCloseOperation(3);
setSize(300,200);
setLocationRelativeTo(null);// 将窗体默认出现在屏幕的正中间
Container c = getContentPane();
c.setLayout(new FlowLayout());
JTextField tf = new JTextField("20");
tf.setFocusable(true);
tf.setText("hello");
tf.setColumns(20);
JButton btn = new JButton("打印");
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("信息为:"+tf.getText());
}
});
btn.setBounds(50,50,50,50);
c.add(btn);
c.add(tf);
c.validate();
setVisible(true);
}
public static void main(String xx[]){
new JTxtTest();
}
}
实际效果展示:
这里涉及到一个特殊的方法,增加了监听事件,对JButton控件使用了addActionListener()方法,在按钮被点击之后调用的对应的方法,在上面的文本中有特别的提到。在控制台显示为:
(五)JTextArea
JTextArea类指的是文本域,和JTextField的区别在于前者是一个“域”,后者是一个“框”,“域”可以设置行数和列数,“框”只可以设置列数。二者的区别就在于这里。
常用的方法:
void setText(String str):设置文本内容。
void setRows(int rows):设置文本域的行数。
void setColumns(int clos):设置文本域的列数。
void setFont(Font f):设置文本字体。
void append(String str):追加文本数据。
void insert(String str, int pos):插入字符串,pos代表是第几个字符。
/**
* JTextArea类,实现输入文本框
* 常用方法:
* 1.void insert(String str, int pos):插入字符串,pos代表是第几个字符
* 2.void append(String str):追加字符串
*/
public class JTxtAreaTest extends JFrame {
public JTxtAreaTest(){
setDefaultCloseOperation(3);
setSize(300,200);
setLocationRelativeTo(null);
Container c = getContentPane();
c.setLayout(new FlowLayout());
JTextArea area = new JTextArea();
area.setRows(6);
area.setColumns(10);
area.setFont(new Font("黑体",Font.BOLD,20));
area.setText("hello");
area.append("world");
area.insert("**",2);
JScrollPane pane = new JScrollPane(area);
c.add(pane);
c.validate();
setVisible(true);
}
public static void main(String xx[]){
new JTxtAreaTest();
}
}
显示的画面为:
这里有一个特殊的代码:
JScrollPane pane = new JScrollPane(area);// 创建一个滑轮面板,并且将JTextArea对象初始化给面板
c.add(pane);// 给容器增加滑轮面板对象
容器直接增加滑轮面板对象,而不是添加JTextArea对象,是因为panel已经包括了area。当输入的文本过长时就会显示滑轮:
(六)JPassword
就是密码类,也是相当于一个文本框,但是不同的是,JPassword不会显示输入的数据,只会显示特定的符号。只需要记住一个特殊的方法就可以:
void setEchoChar(char c):设置框中的符号。
char[] getPassword():获取密码框中的数据。
/**
* JPasswordField类:密码输出框
* 重点方法:
* 1.void setColumns(int columns):设置宽度
* 2.void setEchoChar(char c):设置回显字符
* 3.char[] getPassword() :获取输入的密码
**/
public class Jpassword extends JFrame {
public Jpassword(){
setDefaultCloseOperation(3);
setSize(300,200);
setLocationRelativeTo(null);
Container c = getContentPane();
c.setLayout(new FlowLayout());
JPasswordField passwordField = new JPasswordField();
passwordField.setColumns(20);// 设置框的行数
passwordField.setEchoChar('*');// 设置回显字符
passwordField.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println(passwordField.getPassword());
}
});
c.add(passwordField);
setVisible(true);
}
public static void main(String x[]){
new Jpassword();
}
}
输入数据为“hello world”,窗体显示的为:
控制台显示的是:
(七)JList类
概念:是一个列表菜单。
初始化的方式
- 第一种,使用字符串数组,并且赋初始值。再使用JList类使用泛型将字符串数组作为参数传递。
String [] item = new String[]{"hello","world","i'm","tzc","we","are","best","person","forever"};
JList<String> jList = new JList<>(item);
- 第二种,使用字符串数组,并且赋初始值。使用DefaultListModel类使用泛型创建一个模板对象,将字符串数组的数据放入模板对象中,再将该对象添加到JList对象中去。
String item[] = new String[]{"hello","world","i'm","tzc","we","are","best","person","forever"};
DefaultListModel<String> model = new DefaultListModel<>();
for(String temp:item){
model.addElement(temp);
}
m
JList<String>jList = new JList<>();
jList.setModel(model);
jList.setBounds(20,20,30,30);
c.add(jList);
特殊的几个方法:
void setSelectionMode(int selectionMode):设置选择选项的特点。含有以下的参数:
MULTIPLE_INTERVAL_SELECTION:多选,
SINGLE_INTERVAL_SELECTION:只可以连续选择
SINGLE_SELECTION:单选。
void setModel(ListModel model):添加模板。
List getSelectedValuesList():获得选项的List数组。
package cn.istell.packge.demo9.day02;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/** JList类是列表,需要使用到泛型(和JComboBox类)一样
* JScrollPanel类是带有滑轮的面板类
* DefaultListModel是JList专用的模板类
*
**/
public class JListTest extends JFrame {
public JListTest(){
setTitle("列表");
setDefaultCloseOperation(3);
setLayout(null);
setLocationRelativeTo(null);
setSize(240,200);
Container c = getContentPane();
String [] item = new String[]{"hello","world","i'm","tzc","we","are","best","person","forever"};
JList<String> jList = new JList<>(item);
JScrollPane jScrollPane = new JScrollPane(jList);// 增加一个拥有滑轮的面板,将菜单放入滑轮中
jScrollPane.setBounds(20,20,100,100);
/*
第二种初始化的方式:
String item[] = new String[]{"hello","world","i'm","tzc","we","are","best","person","forever"};
DefaultListModel<String> model = new DefaultListModel<>();
for(String temp:item){
model.addElement(temp);
}
m
JList<String>jList = new JList<>();
jList.setModel(model);
jList.setBounds(20,20,30,30);
c.add(jList);
*/
jList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
/*
选择菜单是否可以连续选择:
MULTIPLE_INTERVAL_SELECTION:多选
SINGLE_INTERVAL_SELECTION:只可以连续选择
SINGLE_SELECTION:单选
*/
JButton btn = new JButton("输出");
btn.addActionListener(new ActionListener() {
// 增加一个监听来获取数据的输出
@Override
public void actionPerformed(ActionEvent e) {
java.util.List<String> value = jList.getSelectedValuesList();
// 该方法是读取列表中的数据,并且将其输出为一个泛型数组
for (String temp:value){
System.out.println(temp);
}
}
});
btn.setBounds(140,40,70,70);
c.add(btn);
c.add(jScrollPane);
c.validate();
setVisible(true);
}
public static void main(String xx[]){
new JListTest();
}
}
效果为:
选择选项获得的数据显示在控制台,获得的是:
(八)JComboBox
概念:该类的作用是一个下拉菜单。
初始化方法:
- 第一种,创建JComboBox对象,一个一个添加数据进行列表。
JComboBox<String> comboBox = new JComboBox<>();
comboBox.addItem("hello");
comboBox.addItem("world");
comboBox.setBounds(100,100,100,50);
container.add(comboBox);
- 第二种,创建字符串数组,将数据保存在字符串数组中,在创建JComboBox对象时将字符串数组作为参数传递。
String [] items = new String[]{"hello","world"};
JComboBox<String> comboBox1 = new JComboBox<>(items);
comboBox1.setBounds(200,100,100,50);
container.add(comboBox1);
- 第三种,创建字符串数组,将数据保存在字符串数组中,创建ComboBoxModel类模板对象,创建JComboBox对象,将模板传入。
JComboBox<String> comboBox2 = new JComboBox<>();
String [] items1 = new String[]{"hello","world"};
ComboBoxModel<String> comboBoxModel = new DefaultComboBoxModel<>(items1);
comboBox2.setModel(comboBoxModel);
comboBox2.setBounds(300,100,100,50);
container.add(comboBox2);
常用的方法为:
void setEditable(boolean aFlag):列表是否可以进行编辑。
int getSelectedIndex():返回选项的地址。
int getSelectedItem():返回选项的内容。
下面展示一个代码
package cn.istell.packge.demo9.day02;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/* JComboBox下拉菜单选项
拥有三种构造方法:
(一)
1.创建JComboBox类创建对象
2.使用addItem()方法添加数据
(二)
1.创建一个数组保存好数据
2.创建JComboBox类创建对象并且将数组导入
(三)
1.创建JComboBox对象
2.创建数组进行导入数据
3.创建ComboBoxModel类对象,并且初始化时将数组导入
*/
public class JcomboBox extends JFrame {
public static void main(String xx[]){
new JcomboBox();
}
public JcomboBox(){
setBounds(100,100,500,500);
setDefaultCloseOperation(3);
Container container = getContentPane();
container.setLayout(null);
// 第一种方式
JComboBox<String> comboBox = new JComboBox<>();
comboBox.addItem("hello");
comboBox.addItem("world");
comboBox.setBounds(100,100,100,50);
container.add(comboBox);
// 第二种方式
String [] items = new String[]{"hello","world"};
JComboBox<String> comboBox1 = new JComboBox<>(items);
comboBox1.setBounds(200,100,100,50);
container.add(comboBox1);
// 第三种方式
JComboBox<String> comboBox2 = new JComboBox<>();
String [] items1 = new String[]{"hello","world"};
ComboBoxModel<String> comboBoxModel = new DefaultComboBoxModel<>(items1);
comboBox2.setModel(comboBoxModel);
comboBox2.setBounds(300,100,100,50);
container.add(comboBox2);
// 对第一个下拉菜单增加一个监听
comboBox.setEditable(true);
// 设置是否可以进行修改菜单选项,一旦修改菜单选项,那么对应的地址在数组中就是-1
JButton btn = new JButton("输出");
btn.setBounds(100,200,100,50);
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("地址为:"+comboBox.getSelectedIndex());
System.out.println("选择的选项为:"+comboBox.getSelectedItem());
}
});
container.add(btn);
setVisible(true);
container.validate();
}
}
效果为:
选择一个选项,点击输出按钮,会在控制台进行输出:
JComboBox是一个下拉菜单,但是JList是一个列表
窗体的布局
窗体的布局基本分为四种情况,流式布局(FlowLayout)、固定布局(null)、网格布局(GridLayout)、网格组布局(GridBagLayout)、边界布局(BorderLayout)。
(一)固定布局
固定布局就是在setLayout()方法中传入参数“null”。固定布局的特点就是,加入的控件不会随着窗体的变化而变化。只会显示在设置好固定的位置。下面展示一个代码更加直观的感受:
public class GuDing extends JFrame {
public GuDing(){
setVisible(true);
Container c = getContentPane();
setBounds(100,100,200,150);
JButton j1 = new JButton("hello");
JButton j2 = new JButton("world");
// 如果不添加坐标那么就无法显示数据
j1.setBounds(10,30,80,30);
j2.setBounds(60,70,100,20);
c.add(j1);
c.add(j2);
// 参数null代表的就是固定布局
c.setLayout(null);
setDefaultCloseOperation(3);
}
public static void main(String x[]){
new GuDing();
}
}
缩放时的状态是:
拉伸窗体时的状态是:
所处的“hello”控件和“world”控件的位置都没有变化。这就是固定布局。
(二)流式布局
流式布局的特点就是,默认居中对齐,控件从左往右排列。下面展示一段代码:
public class LiuBuJu extends JFrame{
public LiuBuJu(){
setTitle("流式布局");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100,100,400,200);
Container c = getContentPane();
setVisible(true);
c.setLayout(new FlowLayout());
// c.setLayout(new FlowLayout(FlowLayout.RIGHT,20,20)); // 设置默认的对齐方式,后面的参数代表水平间距和垂直间距
for (int i = 0; i < 10; i++) {
c.add(new JButton("按钮"+i));
}
c.validate();// 进行刷新容器的控件
}
public static void main(String x[]){
new LiuBuJu();
}
}
这里值得注意的就是在设置布局的时候可以设置布局的对齐方式,水平间距,垂直间距。或者可以写为:
FlowLayout fl = new FlowLayout();
fl.setAlign(FlowLayout.RIGHT);
c.setLayout(f1);
默认的窗格为(居中对齐):
当进行拉伸的时候为:
控件会随着窗体的变化而进行变化,但是始终不变的是排列方式,设置的是居中对齐和从左到右的对齐方式,所以当拉伸时,控件会随着窗体的变化而进行变化。
(三)边界布局
边界布局的特点就是将整个窗体划分为五个区域,分别是CENTER、WEST、EAST、NORTH、SOUTH。代表中间、西、东、北、南五个方位。边界布局的控件会随着窗体的变化而进行变化。
public class BianJian extends JFrame{
public BianJian(){
setTitle("边界布局");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100,100,400,200);
Container c = getContentPane();
setVisible(true);
c.setLayout(new BorderLayout());
JButton j1 = new JButton("中"),
j2 = new JButton("北"),
j3 = new JButton("东"),
j4 = new JButton("西"),
j5 = new JButton("南");
c.add(j1,BorderLayout.CENTER);
c.add(j2,BorderLayout.NORTH);
c.add(j3,BorderLayout.EAST);
c.add(j4,BorderLayout.WEST);
c.add(j5,BorderLayout.SOUTH);
// c.add(new JButton("重写覆盖"),BorderLayout.CENTER); // 覆盖中间位置的控件
c.validate();
}
public static void main(String xx[]){
new BianJian();
}
}
成果展示:
明确的看到就是分为了五个区域。代码中发现存在不同的地方就是容器中使用add()方法时,多了一个参数BorderLayout.方位,这个就是将控件放置在边界布局的哪个位置。
(四)网格布局
网格布局的特点就是将整个窗口划分为了几行几列,以表格的形式进行布局控件,网格布局拥有坐标,行和列的起始坐标为0。网格布局的控件会随着窗体的变化进行变化,下面展示一个代码更好的理解网格布局。
public class WangGe extends JFrame{
public WangGe(){
setTitle("流式布局");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100,100,400,200);
Container c = getContentPane();
setVisible(true);
c.setLayout(new GridLayout(4,5));// 设置为4行5列的网格
// c.setLayout(new GridLayout(4,5,20,20)); // 参数后两个代表水平间距和垂直间距
for (int i = 0; i < 20; i++) {
c.add(new JButton("按钮"+i));
}
// c.add(new JButton("hello")); // 当熟料超过设置的行、列数时,会自动的增加列数,而不是行数
c.validate();
}
public static void main(String xx[]){
new WangGe();
}
}
出现的效果是:
按钮0的坐标就是“0-0”,按钮1就是“0-1”,按钮5就是“1-0”,以此类推。
(伍)网格组布局
网格组布局管理器就是在网格布局的基础上进行了功能的增加(可以进行控件的设置更加细节化),需要使用到其他的类来辅助进行布局。
GridBagConstraints类
该类的作用就是实现一个对象进行修饰控件的属性,在容器面板添加控件的时候将其一同添加进入到容器当中去,使其含有对象的部分属性。
该类存在多个属性:
gridx 和 gridy:设置组件位于网格的哪个位置,起始位置都是0出发。
gridweight 和 gridheight:设置组件占据几个单元格。
ipadx 和 ipady:设置初始时的大小。
insets:设置初始时组件和边界的距离,Insets是一个类。
weightx 和 weighty:设置单元格的最大距离。
fill:设置组件填充模式,含有属性值、none默认水平居中、HORIZONTAL水平拉伸、VERTICAL垂直拉伸、BOTH全方位拉伸。
anchor:设置组件位于单元格的位置,含有属性值、NORTH、EAST、SOUTH、WEST、CENTER。
展示一组代码进行直观的感受
初始化窗体为:
JFrame j = new JFrame("网格组布局");
Container c = j.getContentPane();
// 初始化窗体
public GridBag(){
j.setSize(800,600);
j.setDefaultCloseOperation(3);
c.setLayout(new GridBagLayout());
j.setVisible(true);
j.setLocationRelativeTo(null);// 显示初始化窗体时的默认位置
}
gridx和gridy的属性展示为:
// girdx和girdy属性
public void init(){
for (int i = 0; i < 9; i++) {
// 设置为9行9列
GridBagConstraints g1 = new GridBagConstraints();
g1.gridx = i;
g1.gridy = 0;
c.add(new JButton("按钮"),g1);
GridBagConstraints g2 = new GridBagConstraints();
g2.gridx = 0;
g2.gridy = i;
c.add(new JButton("按钮"),g2);
}
c.validate();
}
显示的是如下图,gridx和gridy的作用就是在这个用于定位控件的坐标:
9行9列的网格组布局。但是不同于网格布局的是,显示出来的效果并没有紧凑的贴着窗体进行布局,而是在窗体的中间进行布局。当窗体的大小很小的时候,添加上去的控件也会显示不全面。当窗体的高度改为500像素时,出现的画面是这样:
左侧的按钮名称没有显示全面。这是网格组布局的一个问题。
gridHeight和girdWidth展示
// gridwidth和gridhigth属性
public void init2(){
GridBagConstraints g1 = new GridBagConstraints();
g1.gridx = 1;
g1.gridy = 1;
g1.gridheight = 2;// 占用两行
g1.gridwidth = 2;// 占用两列
c.add(new JButton("按钮"),g1);
c.validate();
}
显示的画面为如下图,可以明显的看到,这里的一个按钮占据了两列两行,gridHeight和gridWidth的作用就是设置该控件的占据的网格控件。
fiil属性
fill属性的作用就是设置控件的填充方式,存在属性值:none默认水平居中、HORIZONTAL水平拉伸、VERTICAL垂直拉伸、BOTH全方位拉伸。
public void init4(){
GridBagConstraints g1 = new GridBagConstraints();
g1.gridx = 5;
g1.gridy = 1;
g1.gridheight = 2;
g1.gridwidth = 2;
/*
其中还包括
none默认水平居中
HORIZONTAL水平拉伸
VERTICAL垂直拉伸
BOTH全方位拉伸
*/
g1.fill = GridBagConstraints.VERTICAL;
c.add(new JButton("按钮"),g1);
c.validate();
}
实际效果为:
按钮占据两行两列,但是将垂直的位置进行了拉伸。
anchor属性
public void init3(){
GridBagConstraints g1 = new GridBagConstraints();
g1.gridy = 3;
g1.gridx = 3;
g1.gridwidth = 2;
g1.gridheight = 2;
g1.anchor = GridBagConstraints.NORTH;
/*
其中还包括EAST,WEST,SOUTH,NORTH,CENTER其他五个方向
*/
c.add(new JButton("按钮"),g1);// 按钮位于北方
g1.fill = GridBagConstraints.BOTH;
JPanel jb = new JPanel();
jb.setBackground(Color.yellow);
c.add(jb,g1);
c.validate();
}
anchor属性的作用就是在控件所占据的单元格里,让控件居什么对齐,默认时居中对齐。拥有五个属性值(EAST,WEST,SOUTH,NORTH,CENTER)。单词的字面意思就是所指的方向,但是在进行添加的时候需要使用到GridBagConstraints.方向进行添加数据。效果如下图:
在这个代码中特殊的一点就是设置了黄色的背景,使用的代码是:
JPanel jb = new JPanel();// JPanel代表面板
jb.setBackground(Color.yellow);// 给面板增加背景颜色
c.add(jb,g1);// 在容器中加入该面板,也加入约束(GridBagConstraints对象)
inserts属性
inserts的意思是设置初始化的控件距离网格单元的距离,分为top、bottom、right、left四个方向的间距。设置时,通常会将整体的单元格一起进行设置。附上代码进行直观的了解:
public void init5(){
GridBagConstraints g1 = new GridBagConstraints();
g1.gridy = 2;
g1.gridx = 2;
g1.gridwidth = 1;
g1.gridheight = 2;
g1.insets = new Insets(5,5,10,10);
c.add(new JButton("按钮"),g1);
c.validate();
}
实际效果如下图:
ipadx和ipady属性
设置控件初始化的大小,如果为负数那么就是进行缩小,正数则是放大。
public void init6(){
GridBagConstraints g1 = new GridBagConstraints();
g1.gridy = 4;
g1.gridx = 2;
g1.ipadx = -10;
g1.ipady = -20;
c.add(new JButton("hello"),g1);
c.validate();
}
实际效果展示:
Weightx和Weighty属性
设置单元格的长度和宽度
public void init7(){
GridBagConstraints g1 = new GridBagConstraints();
g1.gridx = 4;
g1.gridy = 7;
g1.weightx = 10;
g1.weighty = 10;
c.add(new JButton("&"),g1);
c.validate();
}
可以看到横向的单元格和竖直的单元格都发生了变化,weightx和weighty会竖直和水平的单元格都进行改变。