Java窗體中關(guān)于默認(rèn)布局管理器容易踩的坑及解決
Java窗體關(guān)于默認(rèn)布局管理器容易踩的坑
JFrame窗體的默認(rèn)布局管理器是邊界布局管理器,在使用之前應(yīng)該先使用setLayout(null)取消該布局管理器。
最近在使用Java窗體進(jìn)行界面布局設(shè)置時,遇到這樣一個問題,就是無論如何進(jìn)行控件的布局,結(jié)果窗體上就只會布滿整一個控件,代碼和結(jié)果如下這樣。
這就很疑惑了,明明給控件設(shè)置了坐標(biāo)以及長寬,為什么在顯示的時候還是會布滿整個窗體?
之后查閱了很多發(fā)現(xiàn)是因為在不指定窗體布局的情況下,Swing組件的布局模式是邊界布局管理器(BorderLayout),該布局管理器有一個特點就是在容器中放置一個組件之后,該組件是被放置在窗體中間的,并且整個組件會占據(jù)窗體的整個空間,這也就造成了在添加了組件之后,無論如何設(shè)置空間位置,空間仍然處于窗體中間并且布滿的狀態(tài)。
了解了這個時候,我使用了setLayout(null)來取消窗體的默認(rèn)布局管理器,也就是告知窗體不再使用邊界布局管理器。
但是意外又來了,在我添加了setLayout(null)之后,發(fā)現(xiàn)界面仍然沒有變化,如下所示,
這就很奇怪了,明明已經(jīng)取消了邊界布局管理器,為什么在設(shè)置了控件之后還是沒有效果?
經(jīng)過仔細(xì)研究發(fā)現(xiàn),是顯示窗體可見的代碼setVisible(true);放在了取消布局管理器代碼的前面,這就造成了窗體先顯示出來,然后才取消了邊界布局,這樣導(dǎo)致了setLayout(null)就沒有了意義。
最后將setLayout(null)放在了顯示窗體可見的代碼setVisible(true)之前
問題解決,結(jié)果如下:
在這里需要注意的就是:
JFrame窗體的默認(rèn)布局管理器是邊界布局管理器,在使用之前應(yīng)該先使用setLayout(null)取消該布局管理器,同時,應(yīng)該在設(shè)置好之后,最后再設(shè)置setVisible(true)使窗體頁面可見,否則設(shè)置的屬性將無意義。
java的布局管理器
組件
組件是構(gòu)成圖形 用戶界面的基本成分和核心元素,組件是具有以下特性的對象:運行時可見,具有位置坐標(biāo)、尺寸、字體、顏色等屬性,可以擁有并管理其他組件,可以獲得輸入焦點,可以響應(yīng)事件。
容器
容器(container)是一種特殊組件,它能容納其他組件,在其可視區(qū)域內(nèi)顯示這些組件。容器中各組件的大小位置由容器的布局管理進(jìn)行控制。一個容器可放置其他容器,使用多層容器可以表達(dá)復(fù)雜的布局。
窗口和面板
container容器類的子類有:window窗口類和panel面板類。
Container cp = this.getContentPane();
container頂級容器,相當(dāng)于定義一個頂級容器,把獲取的值,附給頂級容器。如果要向頂級容器上添加其他組件或者容器,就需要調(diào)用以下方法:
Container contentPane=getContentPane();? contentPane.add(組件名);
布局管理
java.awt布局管理器主要有:FlowLayout流、BorderLayout流、GridLayout網(wǎng)格和GridBagLayout網(wǎng)格包。
布局是容器類的特性,每種容器都有一種默認(rèn)布局,若果一個容器需要改變其默認(rèn)布局管理器,可以調(diào)用Container容器類的setLayout()方法。
流布局管理器:
FlowLayout(流式布局),組件按照加入的先后順序按照設(shè)置的對齊方式(居中、左對齊、右對齊)從左向右排列,一行排滿到下一行開始繼續(xù)排列
構(gòu)造函數(shù):
名稱 | 用途 |
---|---|
FlowLayout() | 構(gòu)造一個新的 FlowLayout,它是默認(rèn)居中對齊的,默認(rèn)的水平和垂直間隙是5個像素 |
FlowLayout(int align) | 構(gòu)造一個新的 FlowLayout,它具有指定的對齊方式,默認(rèn)的水平和垂直間隙是 5 個像素,五個參數(shù)值及含義如下:0或FlowLayout.lEFT ,控件左對齊。1或FlowLayout.CENTER ,居中對齊。2或FlowLayout.RIGHT ,右對齊。3或FlowLayout.LEADING,控件與容器方向開始邊對應(yīng)。4或FlowLayout.TRAILING,控件與容器方向結(jié)束邊對應(yīng)。如果是0、1、2、3、4之外的整數(shù),則為左對齊 |
FlowLayout(int align, int hgap, int vgap) | 創(chuàng)建一個新的流布局管理器,它具有指定的對齊方式以及指定的水平和垂直間隙。 |
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());//設(shè)置窗體為流式布局,無參數(shù)默認(rèn)為居中對齊 setFont(new Font("Helvetica", Font.PLAIN, 14));//設(shè)置窗體中顯示的字體樣式 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布局管理器中組件的相對位置隨窗口大小而變化。
網(wǎng)格布局:
GrideLayout布局管理器將容器劃分為大小相等的若干行乘若干列的網(wǎng)格,組件大小隨容器大小而變化.
構(gòu)造方法摘要:
GridLayout()
: 創(chuàng)建具有默認(rèn)值的網(wǎng)格布局,即每個組件占據(jù)一行一列。GridLayout(int rows, int cols)
:創(chuàng)建具有指定行數(shù)和列數(shù)的網(wǎng)格布局。Rows為行數(shù),cols為列數(shù)。GridLayout(int rows, int cols, int hgap, int vgap)
:創(chuàng)建具有指定行數(shù)、列數(shù)以及組件水平、縱向一定間距的網(wǎng)格布局。
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{ //定義面板,并設(shè)置為網(wǎng)格布局,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[];//聲明數(shù)組按鈕 btn=new JButton[str.length];//創(chuàng)建按鈕數(shù)組 //循環(huán)定義按鈕,并添加到面板中 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("網(wǎng)格布局計算器"); } }
setDefaultCloseOperation()參數(shù)得使用說明
System.exit(0)
是退出整個程序,如果有多個窗口,全部都銷毀退出。setDefaultCloseOperation()
是設(shè)置用戶在此窗體上發(fā)起 “close” 時默認(rèn)執(zhí)行的操作。必須指定以下選項之一:DO_NOTHING_ON_CLOSE
(在 WindowConstants 中定義):不執(zhí)行任何操作;要求程序在已注冊的 WindowListener 對象的 windowClosing 方法中處理該操作。HIDE_ON_CLOSE
(在 WindowConstants 中定義):調(diào)用任意已注冊的 WindowListener 對象后自動隱藏該窗體。DISPOSE_ON_CLOSE
(在 WindowConstants 中定義):調(diào)用任意已注冊 WindowListener 的對象后自動隱藏并釋放該窗體。EXIT_ON_CLOSE
(在 JFrame 中定義):使用 System exit 方法退出應(yīng)用程序。僅在應(yīng)用程序中使用。
默認(rèn)情況下,該值被設(shè)置為 HIDE_ON_CLOSE
也就是說沒有設(shè)置的話,默認(rèn)點關(guān)閉時只是隱藏窗體,在后臺進(jìn)程中還可以看到,如果有多個窗口,只是銷毀調(diào)用dispose的窗口,其他窗口仍然存在,整個應(yīng)用程序還是處于運行狀態(tài)。
setLocationRelativeTo
public void setLocationRelativeTo(Component c)
設(shè)置窗口相對于指定組件的位置。
如果組件當(dāng)前未顯示,或者 c 為 null,則此窗口將置于屏幕的中央。
(容易出現(xiàn)的問題:(調(diào)用居中后,窗體跑到右下角去了)對于一個新的JFrame來講,基本可以認(rèn)為是0x0大小的,你在填充內(nèi)容前調(diào)用這個函數(shù),等于是把窗口的左上角放在了屏幕中央。然后你后面再添加了別的子組件之后pack或者setSize,JFrame窗口變大,但是左上角還在屏幕中央。 )
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java編程刪除鏈表中重復(fù)的節(jié)點問題解決思路及源碼分享
這篇文章主要介紹了Java編程刪除鏈表中重復(fù)的節(jié)點問題解決思路及源碼分享,具有一定參考價值,這里分享給大家,供需要的朋友了解。2017-10-10利用MyBatis進(jìn)行不同條件的like模糊查詢的方法
這篇文章主要介紹了利用MyBatis進(jìn)行不同條件的like模糊查詢,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-08-08Spring Boot中使用Spring-data-jpa的配置方法詳解
今天小編就為大家分享一篇關(guān)于Spring Boot中使用Spring-data-jpa的配置方法詳解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-03-03使用IDEA配置Tomcat和連接MySQL數(shù)據(jù)庫(JDBC)詳細(xì)步驟
這篇文章主要介紹了使用IDEA配置Tomcat和連接MySQL數(shù)據(jù)庫(JDBC)詳細(xì)步驟,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-12-12