Java cơ bản – Phần 5: Lập trình giao diện với Java Swing

Khái niệm :

Swing là thư viện các đối tượng để lập trình giao diện đồ hoạ trong Java. Trước đây thư viện AWT là thư viện tiêu chuẩn cho lập trình giao diện, sau này Swing được phát triển kế thừa một số lớp của AWT, hoạt động nhẹ hơn và độc lập với nền tảng thiết bị, và bổ sung thêm nhiều lớp hiển thị mạnh mẽ hơn.

Mỗi thành phần trong Swing được gọi là component. Component được chia làm 2 loại:

  • Loại khung chứa: là những component định nghĩa khung chứa các component khác bên trong. Các component loại này ko thực hiện chức năng hiển thị nội dung, mà chỉ định nghĩa kích thước, nền, cách sắp xếp và hiển thị các component bên trong. Các component khung chứa thường dùng như JFrame, JPanel, JDialog, …
  • Loại hiển thị: là những component đơn vị thực hiện chức năng hiển thị nội dung. Các component hiển thị thường dùng như JLabel, JButton, JList, JTextField, …

Cách tổ chức code khi lập trình giao diện :

Các bạn xem các ví dụ mẫu trên mạng thấy rằng ngta đều tống hết code vào trong 1 file. Điều này giúp bạn dễ nhìn, dễ tiếp cận ở những ví dụ đầu, nhưng cách làm này ko tốt cho sự phát triển về sau, khi mà số lượng component tăng. Sau đây là cách tổ chức code mà mình thường làm:

| src
|– gui
| — | — panel
| — | — | — MainPanel.java
| — | — Gui.java
| — | — ICommon.java
| — logic
| — | — Logic.java
| — main
| — | — Main.java

trong đó “ICommon” là interface định nghĩa 3 phương thức initComponent(), addComponent() và addEvent(). Sau này các Panel và Frame sẽ implement interface này để chúng ta thuận tiện cài đặt và thêm các component bên trong, tránh viết lộn xộn.

public interface ICommon {
  void initComp();
  void addComp();
  void addEvent();
}

“Gui” là lớp định nghĩa Frame và thêm Panel vào trong Frame đó.

public class Gui extends JFrame implements ICommon {
  private MainPanel mainPanel;

  public Gui {
    initComp();
    addComp();
    addEvent();
  }

  @Override
  public void initComp() {
    // cài đặt ban đầu cho Frame
    setSize(500, 400);
    setLayout(new CardLayout());
    setLocationRelativeTo(null);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
  }

  @Override
  public void addComp() {
    // thêm Panel vào Frame
    mainPanel = new MainPanel();
    add(mainPanel);
  }

  @Override
  public void addEvent() {
    // thêm sự kiện
  }
}

“MainPanel” là lớp định nghĩa Panel trong Frame và thêm các component hiển thị trong nó.

public class MainPanel extends JPanel implements ICommon {
  private JButton btnCount;
  private JLabel lbCount;
  private int count;

  public MainPanel {
    count = 0;
    initComp();
    addComp();
    addEvent();
  }

  @Override
  public void initComp() {
    // cài đặt ban đầu cho Panel
    setLayout(null);
  }

  @Override
  public void addComp() {
    // cài đặt và thêm Button btnCount vào Panel
    btnCount = new JButton();
    btnCount.setText("Click");
    btnCount.setSize(100, 50);
    btnCount.setLocation(10, 10);
    add(btnCount);

    // cài đặt và thêm Label lbCount vào Panel
    lbCount = new JLabel();
    lbCount.setText(count + "");
    lbCount.setSize(100, 50);
    lbCount.setLocation(120, 10);
    add(lbCount);
  }

  @Override
  public void addEvent() {
    btnCount.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        count++;
        lbCount.setText(count);
      }
    });
  }
}

Còn “Main” chỉ đơn giản là chứa phương thức main() để tạo đối tượng Frame.

public class Main {
  public static void main(String[] args) {
    Gui gui = new Gui();
    gui.setVisible(true);
  }
}

Cách sử dụng một số component :

Các component đều có các phương thức cơ bản sau:

setSize(width, height) : cài đặt kích thước.

setLocation(x, y) : cài đặt vị trí (lấy vị trí góc trên bên trái làm gốc).

setBound(x, y, width, height) : là phương thức ghép chung cả setLocation và setSize.

setBackground(color) : cài đặt màu nền. Có 2 cách truyền tham số màu: hoặc là dùng màu được quy ước sẵn trong lớp Color, ví dụ như “Color.white”, hoặc tạo một đối tượng Color, ví dụ “new Color(255, 0, 0)”. Có nhiều cách truyền tham số để khởi tạo đối tượng Color, các bạn tham khảo thêm.

setForeground(color) : cài đặt màu chữ.

setVisible(boolean) : cài đặt ẩn hay hiện. Thường thì chỉ Frame hay Window bắt buộc phải thiết lập “setVisible(true)”, còn các component khác thì mặc định thiết lập này true rồi.

JFrame :

setTitle("Title") : cài đặt tên tiêu đề.

setLocationRelativeTo(null) : đặt cho cửa sổ xuất hiện ở giữa màn hình.

setResizable(false) : cài đặt ko cho phép kéo thả thay đổi kích thước cửa sổ.

setDefaultCloseOperation(DO_NOTHING_ON_CLOSE) : lựa chọn ko làm gì khi bạn nhấn nút đóng cửa sổ (nút chéo đỏ). Bạn có thể đặt giá trị “EXIT_ON_CLOSE” để thoát chương trình khi nhấn nút đóng, tuy nhiên cách này ko nên dùng vì ko phải lúc nào nó cũng thoát hoàn toàn. Cách tốt nhất là chúng ta viết xử lý sự kiện riêng (mình sẽ trình bày sau).

setLayout(layout) : cài đặt cách bố trí các component trong container. Về các loại Layout mình sẽ trình bày sau.

add(component) : sau khi khởi tạo component thì chúng ta thêm component đó vào container, ví dụ “add(mainPanel)”. Lưu ý phải thêm vào khung chứa thì component đó mới được hiển thị.

JPanel :

setLayout(layout) : tương tự JFrame.

add(component) : tương tự JFrame.

JLabel :

setText("Số lần bấm: " + count) : đặt nội dung text cần hiển thị.

setFont(new Font("VNI", Font.PLAIN, 24)) : cài đặt font.

setOpaque(true) : mặc định màu nền của Label là trong suốt, đó là bạn phải cài đặt tính đục bằng true thì phương thức cài đặt màu nền setBackground mới có hiệu lực.

setHorizontalAlignment(JLabel.CENTER) : căn text vào giữa Label theo hàng ngang.
setVerticalAlignment(JLabel.CENTER) : căn text vào giữa Label theo hàng dọc.
Bạn có thể truyền giá trị JLabel.RIGHT để căn sang lề phải.

JButton :

setText("Bấm vào đây") : đặt nội dung text cần hiển thị.

setFont(font) : tương tự.

JTextField :

setText() : tương tự.

setFont() : tương tự.

setEnabled(false) : ngăn ko cho chỉnh sửa nội dung text từ bên ngoài.

JTextArea :

setText() : tương tự.

setFont() : tương tự.

setEnabled() : tương tự.

setLineWrap(true) : cài đặt xuống dòng khi tràn chiều dài khung text, tuy nhiên nó ko cắt nguyên vẹn từ xuống dòng mới đâu.

setWrapStyleWord(true) : cho phép cắt nguyên vẹn từ xuống dòng mới.

JList :

JList là một component hiển thị danh sách các đối tượng, cho phép người dùng chọn được item.

Bản thân JList chỉ là thành phần hiển thị. Để nạp dữ liệu cho JList hiển thị, cần có đối tượng model để chứa dữ liệu đó là DefaultListModel. Thông thường để truyền dữ liệu vào model cần có mảng dữ liệu, mảng đó là kết quả của các quá trình tìm kiếm, sắp xếp. Con đường dữ liệu được hiển thị ra JList như sau:

ArrayList –> DefaultListModel –> JList

Ngoài ra JList thường phải đặt trong một loại component khung chứa là JScrollPane, vì JList ko hỗ trợ thanh cuộn, thanh cuộn là do JScrollPane cung cấp.

private DefaultListModel lstModelStudent;
private JList lstStudent;
private JScrollPane scroll;
....
lstStudent = new JList();
scroll = new JScrollPane(lstStudent);
add(scroll);
updateDataListModelStudent();
....
private void updateDataListModelStudent() {
  ArrayList listStudent = manager.getListStudent();
  lstModelStudent = new DefaultListModel();
  for (Student item : listStudent) {
    lstModelStudent.addElement(item);
  }
  lstStudent.setModel(lstModelStudent);
}

JList ko có khả năng hiển thị nhiều trường (thuộc tính) của đối tượng trên cùng một hàng. Muốn hiển thị được nhiều trường, bạn chuyển qua dùng component JTable.

JTable :

Tương tự JList, con đường hiển thị dữ liệu ra màn hình như sau:

ArrayList –> DefaultTableModel –> JTable

private static final String COLUMN_NAME = {"Mã HS", "Tên", "Tuổi"};
private DefaultTableModel tbModelStudent;
private JTable tbStudent;
private JScrollPane scroll;
....
tbStudent = new JTable();
scroll = new JScrollPane(tbStudent);
add(scroll);
updateDataTableModelStudent();
....
private void updateDataTableModelStudent() {
  ArrayList listStudent = manager.getListStudent();
  tbModelStudent = new DefaultTableModel(COLUMN_NAME, 0);
  for (Student item : listStudent) {
    String[] arr = new String[3];
    arr[0] = item.getId();
    arr[1] = item.getName();
    arr[2] = item.getAge();
    tbModelStudent.addRow(arr);
  }
  tbStudent.setModel(tbModelStudent);
}

JTable chỉ có khả năng hiển thị dữ liệu dạng String, nên với dữ liệu kiểu số hay boolean thì các bạn nhớ chuyển đổi thành chuỗi nhé.

JComboBox :

Tương tự JList, chỉ khác là nó hiển thị danh sách dạng sổ xuống và có thuộc tính lựa chọn.

ArrayList –> DefaultComboBoxModel –> JComboBox

private DefaultComboBoxModel cbbModelStudent;
private JComboBox cbbStudent;
....
cbbStudent = new JComboBox();
add(cbbStudent);
updateDataComboBoxModelStudent();
....
private void updateDataComboBoxModelStudent() {
  ArrayList listStudent = manager.getListStudent();
  cbbModelStudent = new DefaultComboBoxModel();
  for (Student item : listStudent) {
    cbbModelStudent.addElement(item);
  }
  cbbStudent.setModel(cbbModelStudent);
}

JComboBox ko cần JScrollPane làm khung.

getSelectedIndex() : trả về chỉ số của lựa chọn.

JCheckBox :

Một số phương thức tương tự như Label.

JRadioButton :

JProgressBar :

setMaximum() : đặt giá trị cực đại của thanh tiến trình. Lưu ý giá trị cực đại cực tiểu này ko liên quan gì đến kích thước width, height của đối tượng JProgressBar.

setMinimum() : đặt giá trị cực tiểu.

setValue() : đặt giá trị hiện tại.

setStringPainted(true) : khi đặt tham số true, chữ thông báo tiến trình sẽ hiển thị ở giữa thanh tiến trình. Mặc định chữ là phần trăm tiến độ.

Xử lý sự kiện:

Đóng cửa sổ (đóng Frame) :

WindowListener wd = new WindowAdapter() {
  @Override
  public void windowClosing(WindowEvent e) {
    int kq = JOptionPane.showConfirmDialog(Gui.this, "Bạn có muốn thoát không?", "Thông báo", JOptionPane.YES_NO_OPTION);
    if (kq == JOptionPane.YES_OPTION) {
      dispose();
    }
  }
};
addWindowListener(wd);

Click chuột vào Label :

label.addMouseListener(new MouseAdapter() {
  @Override
  public void mouseReleased(MouseEvent e) {
    if (e.getButton() == MouseEvent.BUTTON1) {
      label.setText("Chuột trái click");
    } else if (e.getButton() == MouseEvent.BUTTON3) {
      label.setText("Chuột phải click");
    }
  }
});

Nhấn Button :

button.addActionListener(new ActionListener() {
  @Override
  public void actionPerformed(ActionEvent e) {
    // blabla
  }
});

Chọn, bỏ chọn CheckBox :

checkBox.addItemListener(new ItemListener() {
  @Override
  public void itemStateChanged(ItemEvent e) {
    if (checkBox.isSelected()) {
      lbCheck.setText("This CheckBox has checked");
    } else {
      lbCheck.setText("This CheckBox has unchecked");
    }
  }
});

Advertisement

Share this:

Thích bài này:

Thích

Đang tải…