Java窗体中关于默认布局管理器容易踩的坑及解决

软件发布|下载排行|最新软件

当前位置:首页IT学院IT技术

Java窗体中关于默认布局管理器容易踩的坑及解决

灰小猿   2022-12-23 我要评论

Java窗体关于默认布局管理器容易踩的坑

JFrame窗体的默认布局管理器是边界布局管理器,在使用之前应该先使用setLayout(null)取消该布局管理器。

最近在使用Java窗体进行界面布局设置时,遇到这样一个问题,就是无论如何进行控件的布局,结果窗体上就只会布满整一个控件,代码和结果如下这样。

这就很疑惑了,明明给控件设置了坐标以及长宽,为什么在显示的时候还是会布满整个窗体?

之后查阅了很多发现是因为在不指定窗体布局的情况下,Swing组件的布局模式是边界布局管理器(BorderLayout),该布局管理器有一个特点就是在容器中放置一个组件之后,该组件是被放置在窗体中间的,并且整个组件会占据窗体的整个空间,这也就造成了在添加了组件之后,无论如何设置空间位置,空间仍然处于窗体中间并且布满的状态。

了解了这个时候,我使用了setLayout(null)来取消窗体的默认布局管理器,也就是告知窗体不再使用边界布局管理器。

但是意外又来了,在我添加了setLayout(null)之后,发现界面仍然没有变化,如下所示,

这就很奇怪了,明明已经取消了边界布局管理器,为什么在设置了控件之后还是没有效果?

经过仔细研究发现,是显示窗体可见的代码setVisible(true);放在了取消布局管理器代码的前面,这就造成了窗体先显示出来,然后才取消了边界布局,这样导致了setLayout(null)就没有了意义。

最后将setLayout(null)放在了显示窗体可见的代码setVisible(true)之前

问题解决,结果如下:

在这里需要注意的就是:

JFrame窗体的默认布局管理器是边界布局管理器,在使用之前应该先使用setLayout(null)取消该布局管理器,同时,应该在设置好之后,最后再设置setVisible(true)使窗体页面可见,否则设置的属性将无意义。

java的布局管理器

组件

组件是构成图形 用户界面的基本成分和核心元素,组件是具有以下特性的对象:运行时可见,具有位置坐标、尺寸、字体、颜色等属性,可以拥有并管理其他组件,可以获得输入焦点,可以响应事件。

容器

容器(container)是一种特殊组件,它能容纳其他组件,在其可视区域内显示这些组件。容器中各组件的大小位置由容器的布局管理进行控制。一个容器可放置其他容器,使用多层容器可以表达复杂的布局。

窗口和面板

container容器类的子类有:window窗口类和panel面板类。

Container cp = this.getContentPane();

container顶级容器,相当于定义一个顶级容器,把获取的值,附给顶级容器。如果要向顶级容器上添加其他组件或者容器,就需要调用以下方法:

Container contentPane=getContentPane(); 
contentPane.add(组件名);

布局管理

java.awt布局管理器主要有:FlowLayout流、BorderLayout流、GridLayout网格和GridBagLayout网格包。

布局是容器类的特性,每种容器都有一种默认布局,若果一个容器需要改变其默认布局管理器,可以调用Container容器类的setLayout()方法。

流布局管理器:

FlowLayout(流式布局),组件按照加入的先后顺序按照设置的对齐方式(居中、左对齐、右对齐)从左向右排列,一行排满到下一行开始继续排列

构造函数:

名称用途
FlowLayout()构造一个新的 FlowLayout,它是默认居中对齐的,默认的水平和垂直间隙是5个像素
FlowLayout(int align)构造一个新的 FlowLayout,它具有指定的对齐方式,默认的水平和垂直间隙是 5 个像素,五个参数值及含义如下:0或FlowLayout.lEFT ,控件左对齐。1或FlowLayout.CENTER ,居中对齐。2或FlowLayout.RIGHT ,右对齐。3或FlowLayout.LEADING,控件与容器方向开始边对应。4或FlowLayout.TRAILING,控件与容器方向结束边对应。如果是0、1、2、3、4之外的整数,则为左对齐
FlowLayout(int align, int hgap, int vgap)创建一个新的流布局管理器,它具有指定的对齐方式以及指定的水平和垂直间隙。
package qijingliang;

import java.awt.FlowLayout;
import java.awt.Font;

import javax.swing.JButton;
import javax.swing.JFrame;

public class FlowLayoutDemo extends 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"));
    }
    public static void main(String[] args){
        FlowLayoutDemo window=new FlowLayoutDemo();
        window.setTitle("流式布局");
        window.pack();
        window.setVisible(true);
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.setLocationRelativeTo(null);//让窗体居中显示
    }
}


注意:FlowLayout布局管理器中组件的相对位置随窗口大小而变化。

网格布局:

GrideLayout布局管理器将容器划分为大小相等的若干行乘若干列的网格,组件大小随容器大小而变化.

构造方法摘要:

  • GridLayout(): 创建具有默认值的网格布局,即每个组件占据一行一列。
  • GridLayout(int rows, int cols) :创建具有指定行数和列数的网格布局。Rows为行数,cols为列数。
  • GridLayout(int rows, int cols, int hgap, int vgap) :创建具有指定行数、列数以及组件水平、纵向一定间距的网格布局。
package qijingliang;

import java.awt.BorderLayout;
import java.awt.GridLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;

public class GridFrame extends JFrame{
    //定义面板,并设置为网格布局,4行4列,组件水平、垂直间距均为3
    JPanel panel=new JPanel(new GridLayout(4,4,3,3));
    JTextArea t=new JTextArea();//定义文本框
    String str[]={"7","8","9","/","4","5","6","*","1","2","3","-","0",".","=","+"};
    public GridFrame(String s){
        super(s);
        setLayout(new BorderLayout());//定义窗体布局为边界布局
        JButton btn[];//声明数组按钮
        btn=new JButton[str.length];//创建按钮数组
        //循环定义按钮,并添加到面板中
        for(int i=0;i<str.length;i++){
            btn[i]=new JButton(str[i]);
            panel.add(btn[i]);
        }
        //将文本框放置在窗体NORTH位置
        getContentPane().add(t, BorderLayout.NORTH);
        //将面板放置在窗体CENTER位置
        getContentPane().add(panel, BorderLayout.CENTER);
        setVisible(true);
        setSize(500, 400);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);//让窗体居中显示
    }
    public static void main(String[] args){
        GridFrame gl=new GridFrame("网格布局计算器");
    }
}

setDefaultCloseOperation()参数得使用说明

  • System.exit(0)是退出整个程序,如果有多个窗口,全部都销毁退出。
  • setDefaultCloseOperation()是设置用户在此窗体上发起 “close” 时默认执行的操作。必须指定以下选项之一:
  • DO_NOTHING_ON_CLOSE(在 WindowConstants 中定义):不执行任何操作;要求程序在已注册的 WindowListener 对象的 windowClosing 方法中处理该操作。
  • HIDE_ON_CLOSE(在 WindowConstants 中定义):调用任意已注册的 WindowListener 对象后自动隐藏该窗体。
  • DISPOSE_ON_CLOSE(在 WindowConstants 中定义):调用任意已注册 WindowListener 的对象后自动隐藏并释放该窗体。
  • EXIT_ON_CLOSE(在 JFrame 中定义):使用 System exit 方法退出应用程序。仅在应用程序中使用。

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

也就是说没有设置的话,默认点关闭时只是隐藏窗体,在后台进程中还可以看到,如果有多个窗口,只是销毁调用dispose的窗口,其他窗口仍然存在,整个应用程序还是处于运行状态。

setLocationRelativeTo

  • public void setLocationRelativeTo(Component c)设置窗口相对于指定组件的位置。

如果组件当前未显示,或者 c 为 null,则此窗口将置于屏幕的中央。

(容易出现的问题:(调用居中后,窗体跑到右下角去了)对于一个新的JFrame来讲,基本可以认为是0x0大小的,你在填充内容前调用这个函数,等于是把窗口的左上角放在了屏幕中央。然后你后面再添加了别的子组件之后pack或者setSize,JFrame窗口变大,但是左上角还在屏幕中央。 )

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。

Copyright 2022 版权所有 软件发布 访问手机版

声明:所有软件和文章来自软件开发商或者作者 如有异议 请与本站联系 联系我们