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