Bài 41: Layout trong Java Swing – Lập trình Java cơ bản

Đăng bởi : Admin | Lượt xem : 4424 | Chuyên mục : Java

Layout có tính năng tự động hóa sắp xếp các component trên container, bạn tưởng tượng layout giống như một căn nhà có nhiều phòng và các phòng này hoàn toàn có thể tự đổi khác size cũng như vị trí theo một quy luật nào đó và theo đó mà cách đồ vật trong phòng cũng tự biến hóa theo. Đối với người mới khởi đầu lập trình GUI thì layout là một khái niệm khá khó hiểu vì nó không có hình ảnh trực quan như text hay button .

Cũng có những trường hợp chúng ta không cần dùng đến layout. Tuy nhiên nên dùng thì vẫn tốt hơn.

1. FlowLayout

Đây là loại layout đơn thuần nhất, layout này thường được dùng tích hợp với các layout khác. Layout này pháp luật size của các component con là vừa đủ với nội dung hiển thị của component .Mặc định các component sẽ được sắp xếp trên một hàng từ trái sang phải, nếu không vừa đủ một hàng thì chúng sẽ xuống hàng. Các component sẽ cách nhau 5 px và cách viền hành lang cửa số 5 px. Tuy nhiên tất cả chúng ta hoàn toàn có thể đổi khác các thuộc tính này .

FlowLayout()
FlowLayout(int align)
FlowLayout(int align, int hgap, int vgap)

Ở trên là 3 kiểu khởi tạo một FlowLayout, align pháp luật sắp xếp từ trái sang phải hay ngược lại, hgap là khoảng cách giữa các component theo chiều ngang, vgap là khảng cách giữa các component theo chiều dọc .Ví dụ :

import java.awt.Dimension;
 
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
 
 
public class FlowLayoutExample extends JFrame {
 
 
    public FlowLayoutExample() {
 
        initUI();
    }
 
    public final void initUI() {
 
        JPanel panel = new JPanel();
 
        JTextArea area = new JTextArea("text area");
        area.setPreferredSize(new Dimension(100, 100));
 
        JButton button = new JButton("button");
        panel.add(button);
 
        JTree tree = new JTree();
        panel.add(tree);
 
        panel.add(area);
 
        add(panel);
 
        pack();
 
        setTitle("Layout Example");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
    }
 
    public static void main(String[] args) {
 
        SwingUtilities.invokeLater(new Runnable() {
 
            public void run() {
 
                FlowLayoutExample ex = new FlowLayoutExample();
                ex.setVisible(true);
            }
        });
    }
}

Kết quả thu được :

2. GridLayout

Layout này sắp xếp các component theo dạng bảng. Các component sẽ có size bằng nhau .Ví dụ :

import java.awt.GridLayout;
 
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
 
 
public class GridLayoutExample extends JFrame {
 
    public GridLayoutExample() {
 
        initUI();
    }
 
    public final void initUI() {
 
        JPanel panel = new JPanel();
 
        panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        panel.setLayout(new GridLayout(5, 4, 5, 5));
 
        String[] buttons = {
            "Cls", "Bck", "", "Close", 
            "7", "8", "9", "/", 
            "4", "5", "6", "*", 
            "1", "2", "3", "-", 
            "0", ".", "=", "+"
        };
 
        for (int i = 0; i &amplt buttons.length; i++) {
 
            if (i == 2)
                panel.add(new JLabel(buttons[i]));
            else
                panel.add(new JButton(buttons[i]));
        }
 
        add(panel);
 
        setTitle("Layout Example");
        setSize(350, 300);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
    }
 
    public static void main(String[] args) {
 
        SwingUtilities.invokeLater(new Runnable() {
 
            public void run() {
 
                GridLayoutExample ex = new GridLayoutExample();
                ex.setVisible(true);
            }
        });
    }
}

Chúng ta sẽ tạo giao diện máy tính bỏ túi .1 panel. setLayout ( newGridLayout ( 5, 4, 5, 5 ) ) ;Trong phương pháp khởi tạo GridLayout, 2 tham số đầu là số hàng và số cột, hai tham số cuối là khoảng cách giữa các component theo chiều ngang và chiều dọc .Kết quả thu được :

3. BorderLayout

BorderLayout sắp xếp các component theo vùng, ở đây có 5 vùng là Đông (EAST), Tây (WEST), Nam (SOUTH), Bắc (NORTH), và Chính giữa (CENTER). Nhưng mỗi vùng chỉ được chứa một component, do đó khi muốn đưa nhiều component vào một vùng thì chúng ta đặt một layout khác vào vùng đó rồi đặt các component vào layout mới đó. Khác với các layout khác, kích thước của các component trong mỗi vùng là do chúng ta thiết lập chứ không phải do layout tự co dãn, ngoại trừ vùng CENTER sẽ có kích thước thay đổi tùy thuộc vào 4 vùng còn lại.

Ví dụ:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Insets;
 
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JTextArea;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
 
 
public class BorderLayoutExample extends JFrame {
 
 
    public BorderLayoutExample() {
 
        initUI();
    }
 
    public final void initUI() {
 
        // Create menu bar
        JMenuBar menubar = new JMenuBar();
        JMenu file = new JMenu("File");
  
        menubar.add(file);
        setJMenuBar(menubar);
  
        // Create horizontal toolbar (NORTH)
        JToolBar horizontalToolbar = new JToolBar();
        horizontalToolbar.setFloatable(false);
  
        ImageIcon exitIcon = new ImageIcon("F:/exit.png");
        JButton exitButton = new JButton(exitIcon);
        exitButton.setBorder(new EmptyBorder(0, 0, 0, 0));
        horizontalToolbar.add(exitButton);
  
        add(horizontalToolbar, BorderLayout.NORTH);
  
        // Create vertical toolbar (WEST)
        JToolBar verticalToolbar = new JToolBar(JToolBar.VERTICAL);
        verticalToolbar.setFloatable(false);
        verticalToolbar.setMargin(new Insets(10, 5, 5, 5));
  
        ImageIcon driveIcon = new ImageIcon("F:/drive.png");
        ImageIcon computerIcon = new ImageIcon("F:/computer.png");
        ImageIcon printerIcon = new ImageIcon("F:/printer.png");
  
        JButton driveButton = new JButton(driveIcon);
        driveButton.setBorder(new EmptyBorder(3, 0, 3, 0));
  
        JButton computerButton = new JButton(computerIcon);
        computerButton.setBorder(new EmptyBorder(3, 0, 3, 0));
  
        JButton printerButton = new JButton(printerIcon);
        printerButton.setBorder(new EmptyBorder(3, 0, 3, 0));
  
        verticalToolbar.add(driveButton);
        verticalToolbar.add(computerButton);
        verticalToolbar.add(printerButton);
  
        add(verticalToolbar, BorderLayout.WEST);
  
        // Craete Text area (CENTER)
        add(new JTextArea(), BorderLayout.CENTER);
  
        // Create Status bar (SOUTH)
        JLabel statusbar = new JLabel("Statusbar");
        statusbar.setPreferredSize(new Dimension(-1, 22));
        statusbar.setBorder(LineBorder.createGrayLineBorder());
        add(statusbar, BorderLayout.SOUTH);
   
        setSize(350, 300);
        setTitle("Layout Example");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
    }
 
    public static void main(String[] args) {
 
        SwingUtilities.invokeLater(new Runnable() {
 
            public void run() {
                BorderLayoutExample ex = new BorderLayoutExample();
                ex.setVisible(true);
            }
        });
    }
}

Trong ví dụ này tất cả chúng ta sẽ tạo một giao diện giống như các ứng dụng thường thấy gồm có 1 thanh menu, 1 toolbar nằm ngang ( NORTH ), 1 toolbar nằm dọc ( WEST ), 1 text area ( CENTER ), 1 status bar ( SOUTH ) .Mặc định JFrame dùng sẵn BorderLayout nên tất cả chúng ta không cần phải thiết lập lại .

4. BoxLayout

BoxLayout được cho phép tất cả chúng ta tạo các giao diện phức tạp. Layout này sắp xếp các component theo chiều ngang hoặc chiều dọc, tức là giống với FlowLayout, chỉ khác ở chỗ là BoxLayout được cho phép các component hoàn toàn có thể tự đổi khác kích cỡ dựa vào kích cỡ hành lang cửa số chính. Ngoài ra bạn còn hoàn toàn có thể lồng một BoxLayout vào một BoxLayout khác .BoxLayout thường đi cùng với một lớp khác nữa là lớp Box, lớp này có tính năng tạo các khoảng trống để “ đẩy ” các component về các vị trí khác nhau. Các loại khoảng trống mà Box hoàn toàn có thể tạo ra là Glue, Strut và RigidArea. Mình sẽ lý giải ngay bên dưới .Trong ví dụ này tất cả chúng ta sẽ tạo 2 button nằm ở góc dưới bên phải hành lang cửa số .

import java.awt.Dimension;
 
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
 
 
public class TwoButtonsExample extends JFrame {
 
    public TwoButtonsExample() {
 
        initUI();
    }
 
    public final void initUI() {
 
        JPanel basic = new JPanel();
        basic.setLayout(new BoxLayout(basic, BoxLayout.Y_AXIS));
        add(basic);
 
        basic.add(Box.createVerticalGlue());
 
        JPanel bottom = new JPanel();
        bottom.setAlignmentX(Component.RIGHT_ALIGNMENT);
        bottom.setLayout(new BoxLayout(bottom, BoxLayout.X_AXIS));
 
        JButton ok = new JButton("OK");
        JButton close = new JButton("Close");
 
        bottom.add(ok);
        bottom.add(Box.createRigidArea(new Dimension(5, 0)));
        bottom.add(close);
        bottom.add(Box.createRigidArea(new Dimension(15, 0)));
 
        basic.add(bottom);
        basic.add(Box.createRigidArea(new Dimension(0, 15)));
 
        setTitle("Layout Example");
        setSize(300, 150);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
    }
 
    public static void main(String[] args) {
 
        SwingUtilities.invokeLater(new Runnable() {
 
            public void run() {
                TwoButtonsExample ex = new TwoButtonsExample();
                ex.setVisible(true);
            }
        });
    }
}

Kết quả thu được sẽ giống với minh họa sau :Chúng ta tạo 2 panel, một panel chính sắp xếp các component theo chiều dọc, một panel thứ 2 sắp xếp các component theo chiều ngang, panel thứ 2 sẽ chứa 2 button căn lề phải. Để panel thứ 2 hoàn toàn có thể nằm phía dưới cùng của hành lang cửa số ( hay phía dưới cùng của panel chính ) thì tất cả chúng ta dùng đến Glue .

1basic.setLayout(newBoxLayout(basic, BoxLayout.Y_AXIS));

Đầu tiên tất cả chúng ta tạo panel chính với BoxLayout theo chiều dọc .

1basic.add(Box.createVerticalGlue());

Chúng ta tạo khoảng chừng trống glue bằng phương pháp createVerticalGlue ( ). Cơ chế hoạt động giải trí ở đây rất đơn thuần. Ví dụ bạn đặt một button, sau đó gọi phương pháp tạo glue, thì một vùng trống sẽ được thêm vào phía sau button ( ở dưới button hoặc bên phải button tùy vào layout ngang hay dọc ) .

123JPanel bottom = newJPanel();
bottom.setAlignmentX(Component.RIGHT_ALIGNMENT);
bottom.setLayout(newBoxLayout(bottom, BoxLayout.X_AXIS));

Tiếp theo tất cả chúng ta tạo panel thứ hai và thiết lập cho các component con trượt qua lề bên phải bằng phương pháp setAlignmentX ( ), panel này dùng BoxLayout theo chiều ngang .

1bottom.add(Box.createRigidArea(newDimension(5, 0)));

Chúng ta thêm một khoảng chừng trống nhỏ giữa 2 button. Nhưng ở đây tất cả chúng ta không dùng glue và dùng rigid. Sự khác nhau của glue với rigid là size của glue tự động hóa biến hóa tùy theo các component, còn kích cỡ của rigid là do tất cả chúng ta pháp luật .

1basic.add(bottom);

Sau khi đã thiết kế giao diện cho panel thứ hai thì chúng ta đặt panel đó vào panel chính.

1basic.add(Box.createRigidArea(newDimension(0, 15)));

Đồng thời tất cả chúng ta cũng tạo một khoảng chừng trống rigid giữa panel thứ 2 với cạnh đáy của hành lang cửa số .Kết quả thu được :Như vậy, trải qua bài học kinh nghiệm này, mình đã trình làng đến các bạn những layout cơ bản trong Java Swing. Cảm ơn các bạn đã đọc .