iT邦幫忙

2025 iThome 鐵人賽

DAY 13
0

今日內容:JPanel, JButton, BorderLayout


JPanel

一個拿來儲存其他組件的組件區塊
例如設定一個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


JButton

一個用於點擊時提供反饋的按鈕

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的東西
    }
}

點擊前
image

點擊後
image


BorderLayout

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);
    
    }
}

最終成果
image


結語

今天是接觸Java GUI的第二天,除了熟悉昨天學習的JFrame與JLabel以外,新增了JPanel和JButton,並闡明BorderLayout的意義。
這幾天除了正常執行進度以外,也花時間提前搜尋、釐清了一下未來兩周要學習的東西。我發現貪食蛇對於Java GUI只算是一個非常入門級別的Project,不過我仍然會以其為目標,先完成這份屬於我的第一個遊戲,然後如果還有餘力學習更多就繼續鑽研其他可行的Project!
今天也是快樂學習的一天,明天繼續!/images/emoticon/emoticon61.gif


上一篇
Day 12:Java GUI (一)
下一篇
Day 14:Java GUI (三)
系列文
30天從基礎學起Java,直到做出我的第一個遊戲23
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言