iT邦幫忙

2025 iThome 鐵人賽

DAY 14
1

今日內容:FlowLayout、GridLayout、JLayeredPane、Open new window


FlowLayout

這個Layout系統會將組件以適當大小排成一列,如果一列排不下就自動換到下一列

import java.awt.*;
import javax.swing.*;

public class Main {
    public static void main(String[] args){
        // 設定frame
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(500,500);
        
        // FlowLayout(位置-LEADING CENTER TRAILING, 水平距離, 垂直距離)
        frame.setLayout(new FlowLayout(FlowLayout.CENTER, 10, 10));

        // 可以直接在frame中加入new JButton()
        frame.add(new JButton("1"));
        frame.add(new JButton("2"));
        frame.add(new JButton("3"));
        frame.add(new JButton("4"));
        frame.add(new JButton("5"));
        frame.add(new JButton("6"));
        frame.add(new JButton("7"));
        frame.add(new JButton("8"));
        frame.add(new JButton("9"));

        frame.setVisible(true);
    }
}

image

或者是也可以將JButton加在JPanel裡面,再加入JFrame

import java.awt.*;
import javax.swing.*;

public class Main {
    public static void main(String[] args){
        // 設定frame
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(500,500);
        frame.setLayout(new FlowLayout(FlowLayout.CENTER, 10, 10));

        // 設定panel
        JPanel panel = new JPanel();
        panel.setPreferredSize(new Dimension(250, 250));
        panel.setBackground(Color.lightGray);
        panel.setLayout(new FlowLayout()); // 其實panel預設就是FlowLayout

        // 將button加入panel
        panel.add(new JButton("1"));
        panel.add(new JButton("2"));
        panel.add(new JButton("3"));
        panel.add(new JButton("4"));
        panel.add(new JButton("5"));
        panel.add(new JButton("6"));
        panel.add(new JButton("7"));
        panel.add(new JButton("8"));
        panel.add(new JButton("9"));
        
        // 將panel加入frame
        frame.add(panel);

        frame.setVisible(true);
    }
}

image


GridLayout

這個Layout系統則是將組件以網格形式排序,每個格子大小相同,且會盡可能填滿大小(greedy)

import java.awt.*;
import javax.swing.*;

public class Main {
    public static void main(String[] args){
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(500,500);
        
        // GridLayout(列(row)數量, 行(column)數量, 水平距離, 垂直距離)
        frame.setLayout(new GridLayout(3,3,10,10));

        frame.add(new JButton("1"));
        frame.add(new JButton("2"));
        frame.add(new JButton("3"));
        frame.add(new JButton("4"));
        frame.add(new JButton("5"));
        frame.add(new JButton("6"));
        frame.add(new JButton("7"));
        frame.add(new JButton("8"));
        frame.add(new JButton("9"));

        frame.setVisible(true);
    }
}

image


JLayeredPane

可以將組件儲存在第三個維度(z軸),使其可以疊加

import java.awt.*;
import javax.swing.*;

public class Main {
    public static void main(String[] args){
        // 設置三個label
        JLabel label1 = new JLabel();
        label1.setOpaque(true); 
        label1.setBackground(Color.RED);
        label1.setBounds(50, 50, 200, 200);

        JLabel label2 = new JLabel();
        label2.setOpaque(true);
        label2.setBackground(Color.GREEN);
        label2.setBounds(100, 100, 200, 200);

        JLabel label3 = new JLabel();
        label3.setOpaque(true);
        label3.setBackground(Color.BLUE);
        label3.setBounds(150, 150, 200, 200);

        // 宣告出layeredPane
        JLayeredPane layeredPane = new JLayeredPane();
        layeredPane.setBounds(0, 0, 500, 500);

        // 將label加入layeredPane
        // .add(組件, 圖層(Default, Drag...)
        // 或.add(組件, 數字(Integer.valueOf(value), 0最小)),用數字呈現會比較直觀
        layeredPane.add(label1, Integer.valueOf(0));
        layeredPane.add(label2, Integer.valueOf(2));
        layeredPane.add(label3, Integer.valueOf(1));

        // 將layeredPane加入frame
        JFrame frame = new JFrame();
        frame.add(layeredPane);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(500,500);
        frame.setLayout(null);
        frame.setVisible(true);
    }
}

最終成果(layer2 Green 的數值是2,在最上面)
image


Open new window

是結合前面的JFrame跟JButton的一個練習,在第一個frame中的button遇到點擊時,ActionListener會觸發並開啟第二個frame

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JButton;

public class LaunchPage implements ActionListener{
    JFrame frame = new JFrame();
    JButton button = new JButton("New Window");

    LaunchPage(){
        button.setBounds(150, 150, 150, 50);
        button.setFocusable(false);
        button.addActionListener(this);

        frame.add(button);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(500, 500);
        frame.setLayout(null);
        frame.setVisible(true);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if(e.getSource() == button){
            frame.dispose(); // 關閉第一個frame
            NewWindow myWindow = new NewWindow(); // 開啟第二個frame
        }
    }
}
import javax.swing.JFrame;
import javax.swing.JLabel;
import java.awt.Font;

public class NewWindow {
    JFrame frame = new JFrame();
    JLabel label = new JLabel("Hello!");

    NewWindow(){
        label.setBounds(0, 0, 100, 50);
        label.setFont(new Font(null, Font.PLAIN, 25));

        frame.add(label);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(500, 500);
        frame.setLayout(null);
        frame.setVisible(true);
    }
}

public class Main {
    public static void main(String[] args){
        LaunchPage launchPage = new LaunchPage();
    }
}

第一個frame
image
第二個frame(點擊後開啟 且第一個被關閉)
image

補充
也可以在第二個frame加button,看要關掉當前視窗或者是再開一個新的也可以
如果actionPerformed裡面的不是開啟newWindow,而是再開LaunchPage的話,就可以變成無限套娃


結語

今天是接觸Java GUI的第三天,不知道是學習的項目變多了還是因為連續的學習,我可以很明顯地感覺到這幾天的學習進度比起前幾天稍慢了,不過在我的鐵人挑戰結束當天也是開學的日子,因此我需要好好調整心態與作息,努力完成這個項目並準備正常作息。
今天也是快樂學習的一天,明天繼續!/images/emoticon/emoticon31.gif


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

尚未有邦友留言

立即登入留言