今日內容:JPanel, JButton, BorderLayout
一個拿來儲存其他組件的組件區塊
例如設定一個JPanel用於存放JLabel
import javax.swing.JPanel;
// ...
JPanel panel = new JPanel();
panel.setBackground(Color.blue); // 設定背景顏色
panel.setBounds(0, 0, 250, 250); // 設定邊界,跟JLabel的方式一樣
panel.setLayout(null);
// 括號內設定為null的話需要將label也設定邊界-> label.setBounds(x, y, width, height);
// 或者是可以用BorderLayout(下面會教)-> setLayout(new BorderLayout());
// new BorderLayout()的話需要設定label的位址-> label.setVerticalAlignment ...
// 接下來可以把label加到panel裡面
panel.add(label);
// 最後加到frame裡面
frame.add(panel);
而最終加在panel中的label的bound界線 是由panel界定,而非frame
一個用於點擊時提供反饋的按鈕
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class MyFrame extends JFrame implements ActionListener {
// 創建我的MyFrame class,這樣在main裡面宣告MyFrame物件時就可以全部直接顯示出來
JButton button;
JLabel label;
// JButton跟JLabel設為global,方便操控與管理
MyFrame(){
ImageIcon icon = new ImageIcon("thumbsup.png");
// 在constructor中設定label內容
label = new JLabel();
label.setIcon(icon);
label.setBounds(150, 250, 150, 150);
label.setVisible(false); // 剛開始先設定為看不到label
// 設定button
button = new JButton(); // 按鈕本體
button.setBounds(100, 100, 250, 100); // 設定區域範圍
button.addActionListener(this); // 用於接收使用者點擊(對應到下面的method)
// 由於我們有implements ActionListener,所以傳入this即可
button.setText("Click me"); // 顯示在按鈕上的文字
button.setFocusable(false); // 使文字不因長度而顯示不完全
button.setIcon(icon); // 顯示在按鈕上的圖片
button.setHorizontalTextPosition(JButton.CENTER); // 設定水平位置
button.setVerticalTextPosition(JButton.BOTTOM); // 設定垂直位置
button.setFont(new Font("Comic Sans", Font.BOLD, 25)); // 設定文字型號
button.setIconTextGap(-15); // 設定 文字與圖片 的距離
button.setForeground(Color.cyan); // 設定前景顏色(也就是按鈕上文字的顏色)
button.setBackground(Color.lightGray); // 設定背景顏色
button.setBorder(BorderFactory.createEtchedBorder()); // 設定邊界樣式
// 最後設定frame
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLayout(null);
this.setSize(500, 500);
this.add(button);
this.add(label);
this.setVisible(true);
}
// 由於我們implements ActionListener,需要Override他的method,這個method設定的是當特定的東西被觸發時(在此為button),我們要產生什麼反應
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == button){ // 當點擊按鈕時
System.out.println("Poo"); // Console顯示"Poo" (讓自己確認程式有效)
button.setEnabled(false); // 將按鈕設為不再被使用(讓他點一次就失效)
label.setVisible(true); // 點下按鈕後顯示label
}
}
}
最後設定完MyFrame這個class後,將他加入main
public class Main{
public static void main(String[] args){
MyFrame frame = new MyFrame();
// 或者也可以不需要前面的命名,
// 直接 new MyFrame() 也可以執行所有constructor的東西
}
}
點擊前
點擊後
BorderLayout屬於輔助用的功能,可以將組件放在五個區域:東(E)、南(S)、西(W)、北(N)、中心(C)
import javax.swing.*;
import java.awt.*;
public class Main {
public static void main(String[] args){
JFrame frame = new JFrame(); // 宣告frame
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 500);
frame.setLayout(new BorderLayout(10, 10));
// 這邊設定每個區域中間的間隔有多少(width, height)
frame.setVisible(true);
// 開五個區塊(panel)
JPanel panel1 = new JPanel();
JPanel panel2 = new JPanel();
JPanel panel3 = new JPanel();
JPanel panel4 = new JPanel();
JPanel panel5 = new JPanel();
// 分別上顏色
panel1.setBackground(Color.red);
panel2.setBackground(Color.green);
panel3.setBackground(Color.yellow);
panel4.setBackground(Color.magenta);
panel5.setBackground(Color.blue);
// 這邊是設定偏好大小(width, height),告訴Layout manager我"想要"多少範圍,不過實際會依情況而定
// 然後傳入一個Dimension參數,指定出實際的範圍
panel1.setPreferredSize(new Dimension(100, 100));
panel2.setPreferredSize(new Dimension(100, 100));
panel3.setPreferredSize(new Dimension(100, 100));
panel4.setPreferredSize(new Dimension(100, 100));
panel5.setPreferredSize(new Dimension(100, 100));
// 另外也可以把panel加在panel裡面
panel5.setLayout(new BorderLayout());
JPanel panel6 = new JPanel();
panel6.setBackground(Color.lightGray);
panel6.setPreferredSize(new Dimension(50, 50));
panel5.add(panel6, BorderLayout.NORTH);
// 最後加進frame,並分配至對應的方位
frame.add(panel1, BorderLayout.NORTH);
frame.add(panel2, BorderLayout.EAST);
frame.add(panel3, BorderLayout.SOUTH);
frame.add(panel4, BorderLayout.WEST);
frame.add(panel5, BorderLayout.CENTER);
}
}
最終成果
今天是接觸Java GUI的第二天,除了熟悉昨天學習的JFrame與JLabel以外,新增了JPanel和JButton,並闡明BorderLayout的意義。
這幾天除了正常執行進度以外,也花時間提前搜尋、釐清了一下未來兩周要學習的東西。我發現貪食蛇對於Java GUI只算是一個非常入門級別的Project,不過我仍然會以其為目標,先完成這份屬於我的第一個遊戲,然後如果還有餘力學習更多就繼續鑽研其他可行的Project!
今天也是快樂學習的一天,明天繼續!