佈局管理器
爲了跨平臺java引入了佈局管理器來管理界面,JAVA一共有6種佈局管理器,下面是介紹
BorderLayout
界面分東西南北中5個方向,最多隻能顯示5個控件,默認放入中間,下面的程序將panel和panel2放在了中間和南邊。放在中間的空間大小默認有內容大小爲剩餘的部分,不可設置。就如下面的程序,不能設置panel2的大小
this.getContentPane().add(panel,BorderLayout.SOUTH);
this.getContentPane().add(panel2,BorderLayout.CENTER);
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class BorderFrame extends JFrame{
JButton btOK = new JButton("OK");
JButton btNO = new JButton("NO");
JPanel panel = new JPanel(new FlowLayout(FlowLayout.CENTER));
JPanel panel2 = new JPanel(new FlowLayout(FlowLayout.LEFT));
public BorderFrame(){
this.getContentPane().add(panel,BorderLayout.SOUTH);
this.getContentPane().add(panel2,BorderLayout.CENTER);
panel2.setBackground(Color.black);
panel2.setSize(100,200);
this.setBackground(Color.red);
panel.add(btOK);
panel.add(btNO);
panel.setBackground(Color.blue);
this.setSize(300,200);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
BorderFrame frame = new BorderFrame();
}
}
FlowLayout
看作行集,行高不能用setSize設置,由內容決定,可以設置左中右居,還有。就如上面的程序,panel不能設置大小,panel2也不能,之所有有這麼大是因爲發在了BorderLayout有東西填充。若將panel2放在上邊,效果如下
this.getContentPane().add(panel2,BorderLayout.NORTH);
放在左邊效果有如下 :
this.getContentPane().add(panel2,BorderLayout.WEST);
GridLayout
網格管理器,把容器的顯示位置化格子,然後把控件放到等寬等高的格子,
GridLayout layout = new GridLayout(行數,列數);
// 當行數爲0時,增加控件時會保持一個列的情況下隨控件增長;列數爲0時亦是如此。但不能同時爲0
一個對話框例子
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import java.awt.event.*;
public class LoginDialogDemo extends JFrame {
JButton button = new JButton("Click Me");
JPanel panel = new JPanel(new FlowLayout());
public LoginDialogDemo(){
final JFrame frame = this;
// BorderLayout管理器
this.getContentPane().add(panel, BorderLayout.SOUTH);
panel.add(button);
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
showLoginDialog(frame);
}
});
this.setSize(400,200);
this.setTitle("顯示登陸對話框");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
void showLoginDialog(JFrame frame){
// gridLayout自增
JPanel p = new JPanel(new GridLayout(0,1));
JTextField tfUserName = new JTextField();
JPasswordField tfPassword = new JPasswordField();
p.add(new JLabel("Username:"));
p.add(tfUserName);
p.add(new JLabel("Password:"));
p.add(tfPassword);
if(JOptionPane.showConfirmDialog(frame,
p,
"Login",
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.PLAIN_MESSAGE)==
JOptionPane.OK_OPTION){
System.out.println("User Name:"+tfUserName.getText());
System.out.println("Password:"+new String(tfPassword.getName()));
}
}
public static void main(String[] args){
LoginDialogDemo frame = new LoginDialogDemo();
}
}
BoxLayout
允許控件按X/Y抽擺放。
public BoxLayout(Container target,int axis)
// target表示當前管理的容器,若爲this則管理自己所在的容器
import java.awt.TextArea;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class BoxLayoutFrame extends JFrame{
BoxLayoutTest panel = new BoxLayoutTest();
public BoxLayoutFrame(){
this.getContentPane().add(panel);
this.setSize(500,500);
this.setTitle("測試界面佈局");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
BoxLayoutFrame frame = new BoxLayoutFrame();
}
}
class BoxLayoutTest extends JPanel{
BoxLayoutTest(){
//set the layout to a X-axis BoxLayout
setLayout(new BoxLayout(this,BoxLayout.X_AXIS));
//Create three components
JTextField textField = new JTextField(); //單行文本輸入框
// JTextArea構造具有指定行數和列數的新的空 TextArea。
TextArea textArea = new TextArea(4,20);
JButton button = new JButton("this is a Button");
//add the three components to the BoxLayouts
add(new JLabel("TextField:"));
add(textField);
add(new JLabel("TextArea:"));
add(textArea);
add(new JLabel("button:"));
add(button);
}
}
CardLayout
CardLayout佈局,某個界面像放動畫一樣貼換內容。比如實現一個界面內多個
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JButton;
import javax.swing.BoxLayout;
import java.awt.Panel;
import java.awt.event.*;
public class CardLayoutFrame extends JFrame {
JButton btnPrevious = new JButton("Previous");
JButton btnNext = new JButton("Next");
JPanel panelFlow = new JPanel(new FlowLayout());
JPanel panelCard = new JPanel(new CardLayout());
int currentIndex = 0;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
CardLayoutFrame frame = new CardLayoutFrame();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public CardLayoutFrame() {
this.getContentPane().add(panelFlow, BorderLayout.SOUTH);
this.getContentPane().add(panelCard,BorderLayout.CENTER );
panelCard.add(createCard(1), "Card1");
panelCard.add(createCard(2), "Card2");
panelFlow.add(btnPrevious);
panelFlow.add(btnNext);
ActionListener listener = new ActionListener(){
public void actionPerformed(ActionEvent e){
switchCard();
};
};
btnPrevious.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
switchCard();
};
});
btnNext.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
switchCard();
};
});
this.setSize(300,200);
this.setTitle("測試界面佈局");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
// 生產卡片
JPanel createCard(int Index){
JPanel panel = new JPanel(new BorderLayout());
JLabel label = new JLabel("<html><h1 style = color:red>"+
"This is Panel"+ Index+"</h1></html>");
label.setHorizontalAlignment(JLabel.CENTER);
panel.add(label);
return panel;
}
void switchCard(){
CardLayout c1 = (CardLayout) panelCard.getLayout();
if(currentIndex == 0){
currentIndex ++;
c1.show(panelCard, "Card2");
}else{
currentIndex--;
c1.show(panelCard, "Card1");
}
}
}
GridBagLayout
每個加入容器的控件創建一個GridBagConstraints對象,下面分析這個對象的構造函數的參數
public GridBagConstraints(
int gridx,int gridy, //控件的位置,單位爲網格
int gridwidth,int gridheight, // 組件佔幾列幾行
double weightx,double weighty, // 水平和垂直拉伸權值
int anchor, // 停靠方向,默認CENTER,有NORTHEAST,EAST,SOUTHEAST,SOUTH,SOUTHWEST等
int fill, // 拉伸的方向,有NONE,HORIZONTAL,VERTICAL
insets insets(上,左,下,右), // 外部填充,填充的區域是組件與所處格子邊框之間的部分。 當組件不能填滿其格時,通過 insets來指定四周(即上下左右)所留空隙
int ipadx,ipady // 組件間的橫縱向間距
)
一個單例使用實例
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
public class GridBagLayoutFrame extends JFrame {
JButton btnOK = new JButton("OK");
JButton btnCancel = new JButton("Cancel");
JPanel panelFlow = new JPanel(new FlowLayout());
JPanel panelGrid;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
GridBagLayoutFrame frame = new GridBagLayoutFrame();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public GridBagLayoutFrame() {
panelGrid = createPanelGridBag();
this.getContentPane().add(panelFlow, BorderLayout.SOUTH);
this.getContentPane().add(panelGrid,BorderLayout.CENTER);
panelFlow.add(btnOK);
panelFlow.add(btnCancel);
this.setTitle("測試界面");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.pack(); //窗口自適應組件大小
this.setVisible(true);
}
JPanel createPanelGridBag(){
JPanel panelGridBag = new JPanel(new GridBagLayout());
JLabel label1 = new JLabel();
JLabel label2 = new JLabel();
JLabel label3 = new JLabel();
JLabel label4 = new JLabel();
JTextField textField1 = new JTextField();
JTextField textField2 = new JTextField();
JTextField textField3 = new JTextField();
JTextField textField4 = new JTextField();
label1.setText("User Name:");
label2.setText("Telephone:");
label3.setText("Address:");
label4.setText("Company:");
textField1.setText("Your Name");
textField2.setText("88888888");
textField3.setText("Shanghai,China");
textField4.setText("Your company");
// Insets(int top, int left, int bottom, int right)
// 創建並初始化具有指定頂部、左邊、底部、右邊 inset 的新 Insets 對象。
panelGridBag.add(label1,
new GridBagConstraints(0,0,1,1,0.0,0.0,
GridBagConstraints.WEST,GridBagConstraints.NONE,
new Insets(45, 50, 0, 0),20,0
)
);
panelGridBag.add(label2,
new GridBagConstraints(0,1,1,1,0.0,0.0,
GridBagConstraints.WEST,GridBagConstraints.NONE,
new Insets(34,50,0,0),20,0
)
);
panelGridBag.add(label3,
new GridBagConstraints(0,2,1,1,0.0,0.0,
GridBagConstraints.WEST,GridBagConstraints.NONE,
new Insets(28,50,0,0),33,0
)
);
panelGridBag.add(label4,
new GridBagConstraints(0,3,1,1,0.0,0.0,
GridBagConstraints.WEST,GridBagConstraints.NONE,
new Insets(28,50,50,0),26,0
)
);
panelGridBag.add(textField1,
new GridBagConstraints(1,0,1,1,1.0,0.0,
GridBagConstraints.WEST,GridBagConstraints.HORIZONTAL,
new Insets(44,25,0,84),97,0
)
);
panelGridBag.add(textField2,
new GridBagConstraints(1,1,1,1,1.0,0.0,
GridBagConstraints.WEST,GridBagConstraints.HORIZONTAL,
new Insets(31,25,0,84),97,0
)
);
panelGridBag.add(textField3,
new GridBagConstraints(1,2,1,1,1.0,0.0,
GridBagConstraints.WEST,GridBagConstraints.HORIZONTAL,
new Insets(25,25,0,84),97,0
)
);
panelGridBag.add(textField4,
new GridBagConstraints(1,3,1,1,1.0,0.0,
GridBagConstraints.WEST,GridBagConstraints.HORIZONTAL,
new Insets(26,25,50,84),97,0
)
);
return panelGridBag;
}
}
難點: weightx,weighty
在書上看到這兩個值設爲[0,1],然後自個好奇就隨便調了幾個值,結果UI依然不受影響,然後通過查閱才知道其實這兩個值得取值無限制,只要合理即可,每個組件的這兩個值還與其他因素有關。詳細請看論文
java的拉伸作用規則:
1. 跨多個格子且是第一列(行)則作用於最右(下)邊的格子;若非出現在第一行或列且weight爲0,則作用於最右下格子,否則按比例值(某個x或y上所有某個weight佔總weight的值)拉伸。
2. 拉伸值爲0時不一定不能拉伸,只要所在行存在拉伸對象,就能跟着拉伸。
下面給出論文中的一個源碼:
import java.awt.*;
import javax.swing.*;
public class DWPMessGrigBag extends JFrame {
JButton Ding,Wei,Ping,Exit,Help;
JLabel address,family;
JPanel panel;
JTextField textField,mousePosition;
JList familyList,addrList;
JTextArea textArea;
/**
* Create the frame.
*/
public DWPMessGrigBag() {
Ding = new JButton("丁");
Wei = new JButton("衛");
Help = new JButton("幫助");
Ping = new JButton("平");
family = new JLabel("丁家成員");
address = new JLabel("地址信息");
String[] str = {"丁衛平","張燕","丁培桓"};
String[] addstr = {"湖南","桃花","灰山港"};
textField = new JTextField();
textField.setBackground(Color.green);
mousePosition = new JTextField();
Exit = new JButton("退出");
familyList = new JList(str);
familyList.setBackground(Color.yellow);
addrList = new JList (addstr);
addrList.setBackground(Color.green);
textArea = new JTextArea();
textArea.setBackground(Color.lightGray.brighter());
GridBagLayout layout = new GridBagLayout();
this.setLayout(layout);
GridBagConstraints s = new GridBagConstraints();
s.fill = GridBagConstraints.BOTH;
s.gridwidth = 1;
s.weightx = 0;
s.weighty = 0;
layout.setConstraints(Ding,s);
layout.setConstraints(Wei,s);
layout.setConstraints(Ping,s);
s.gridx = 4;
s.gridy = 0;
layout.setConstraints(Help, s);
s.gridx = 0;
s.gridy = 1;
s.gridwidth = 2;
layout.setConstraints(family, s);
s.gridx = 2;
s.gridy = 1;
s.weightx = 13;
layout.setConstraints(textField, s);
s.gridx = 4;
s.gridwidth = 1;
s.weightx = 0;
layout.setConstraints(Exit, s);
s.gridx = 0;
s.gridy = 2;
s.gridwidth = 2;
s.weightx = 0;
s.weighty = 90;
layout.setConstraints(familyList, s);
s.gridx = 2;
s.gridheight = 4;
s.gridwidth = 3;
s.weightx = 31;
s.weighty = 44;
layout.setConstraints(textArea,s);
s.gridx = 0;
s.gridy = 3;
s.gridwidth = 2;
s.weightx = 0;
s.weighty = 0;
s.gridheight = 1;
layout.setConstraints(address, s);
s.gridy = 4;
s.weighty = 30;
layout.setConstraints(addrList, s);
s.weighty = 0;
s.gridy = 5;
layout.setConstraints(mousePosition, s);
this.add(Ding);
this.add(Wei);
this.add(Ping);
this.add(Help);
this.add(family);
this.add(textField);
this.add(Exit);
this.add(familyList);
this.add(textArea);
this.add(address);
this.add(addrList);
this.add(mousePosition);
this.setSize(600,600);
this.setVisible(true);
}
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
DWPMessGrigBag frame = new DWPMessGrigBag();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
參考:
《JAVA編程實踐指南》,邵榮,清華大學出版社
Java學習筆記之卡片式佈局CardLayout
GridBagLayout 以及 GridBagConstraints 用法
GridBagConstrains類成員weightx和weighty的使用方法研究