Daily Archives: 02/03/2016

Java Swing – Menu và toolbar

Trong bài này chúng ta sẽ học cách làm menu và toolbar.

Java Swing có sẵn 3 lớp hỗ trợ tạo menu là a JMenuBarJMenu và JMenuItem.

Tạo menu

Chúng ta tạo một thanh menu có 1 item là Exit, click vào item này thì thoát chương trình.

JMenuBar menubar = new JMenuBar();

Đầu tiên chúng ta tạo một đối tượng menubar từ lớp JMenuBar.

ImageIcon icon = new ImageIcon("E:/exit.png");

Tiếp theo là tạo một đối tượng ImageIcon để làm ảnh icon của item.

JMenu file = new JMenu("File");
file.setMnemonic(KeyEvent.VK_F);

Chúng ta dùng lớp JMenu để tạo một menu, sau đó thiết lập phím tắt cho menu này là tổ hợp Alt+F.

JMenuItem eMenuItem = new JMenuItem("Exit", icon);
eMenuItem.setMnemonic(KeyEvent.VK_E);

Chúng ta tạo các item trong một menu từ lớp JMenuItem với tên item và ảnh icon, sau đó chúng ta gán phím tắt cho menu con này là tổ hợp Alt+E.

eMenuItem.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent event) {
        System.exit(0);
    }
});

Bản thân JMenuItem là một lớp kế thừa từ lớp AbstractButton, tức là cũng thuộc một loại button đặc biệt nên chúng ta có thể gắn listener cho đối tượng thuộc lớp này, ở đây chúng ta gọi System.exit() để thoát chương trình.

file.add(eMenuItem);
menubar.add(file);

Chúng ta thêm item vào menu rồi thêm menu đó vào menubar.

setJMenuBar(menubar);

Cuối cùng thiết lập menubar từ phương thức setJMenuBar().

Untitled

Tạo menu con

Trong ví dụ này chúng ta tạo một menu con.

JMenu saveMenu = new JMenu("Save");
...
menuFile.add(saveMenu);

Một menu con cũng chỉ đơn giản là một menu item thôi, bạn chỉ cần tạo nó ra rồi dùng phương thức add() của một menu khác để thêm vào làm menu con.

menuFile.addSeparator();

Ngoài ra ở đây chúng ta còn tạo một separator, đây đơn giản chỉ là một đường kẻ ngang để phân nhóm các item có chung mục đích với nhau lại.

Untitled

Tạo phím tắt cho menu item

Trong Java có 2 kiểu phím tắt là MnemonicAccelerator, trong đó mnemonic là tổ hợp của phím Alt với phím do chúng ta chỉ định, khi bấm vào tổ hợp phím này thì menu hoặc menu item sẽ xổ xuống, trong ví dụ đầu tiên chúng ta đã làm quen với mnemonic, còn Accelerator là kiểu phím tắt mà khi bấm tổ hợp phím này thì menu item sẽ được thực thi, tổ hợp phím trong accelerator là do chúng ta chỉ định.

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import static javax.swing.Action.MNEMONIC_KEY;
import static javax.swing.Action.SMALL_ICON;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.KeyStroke;


public class ShortCutsEx extends JFrame {

    public ShortCutsEx() {
        
        initUI();
    }

    private void initUI() {

        JMenuBar menuBar = new JMenuBar();
 
        ImageIcon newIcon = new ImageIcon("F:/new.png");
        ImageIcon openIcon = new ImageIcon("F:/open.png");
        ImageIcon saveIcon = new ImageIcon("F:/save.png");
        ImageIcon exitIcon = new ImageIcon("F:/exit.png");
 
        JMenu fileMenu = new JMenu("File");
        fileMenu.setMnemonic(KeyEvent.VK_F);
 
        JMenuItem newItem = new JMenuItem("New", newIcon);
        JMenuItem openItem = new JMenuItem("Open", openIcon);
        JMenuItem saveItem = new JMenuItem("Save", saveIcon);
        JMenuItem exitItem = new JMenuItem("Exit", exitIcon);
 
        exitItem.setMnemonic(KeyEvent.VK_E);
        exitItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_W, 
                                ActionEvent.CTRL_MASK));
        exitItem.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                System.exit(0);
            }
        });
 
        fileMenu.add(newItem);
        fileMenu.add(openItem);
        fileMenu.add(saveItem);
        fileMenu.addSeparator();
        fileMenu.add(exitItem);
 
       menuBar.add(fileMenu);
       setJMenuBar(menuBar);
 
        setTitle("Menu Example");
        setSize(300, 300);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);        
    }        

    public static void main(String[] args) {
        
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                
                ShortCutsEx ex = new ShortCutsEx();
                ex.setVisible(true);
            }
        });
    }
}

Trong ví dụ này chúng ta tạo phím tắt theo cả 2 kiểu.

JMenu fileMenu = new JMenu("File");
fileMenu.setMnemonic(KeyEvent.VK_F);

Đầu tiên chúng ta thiết lập mnemonic cho menu File với tổ hợp phím Alt+F.

exitItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_W,
    ActionEvent.CTRL_MASK));

Để thiết lập phím tắt accelerator thì chúng ta dùng phương thức setAccelerator().

Untitled

Tạo check box item

Chúng ta có thể tạo menu item là check box. Java Swing cung cấp lớp JCheckBoxMenuItem để hỗ trợ làm việc này.

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import javax.swing.BorderFactory;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;

public class CheckBoxMenuItemEx extends JFrame {

    private JLabel statusbar;

    public CheckBoxMenuItemEx() {

        initUI();
    }

    private void initUI() {

        JMenuBar menubar = new JMenuBar();
        JMenu fileMenu = new JMenu("File");
        fileMenu.setMnemonic(KeyEvent.VK_F);
 
        JMenu viewMenu = new JMenu("View");
        viewMenu.setMnemonic(KeyEvent.VK_V);
 
        JCheckBoxMenuItem showStatusBar = new JCheckBoxMenuItem("Show statusbar");
        showStatusBar.setMnemonic(KeyEvent.VK_S);
        showStatusBar.setDisplayedMnemonicIndex(5);
        showStatusBar.setSelected(true);
 
        showStatusBar.addItemListener(new ItemListener() {

            @Override
            public void itemStateChanged(ItemEvent e) { 
                statusbar.setVisible(e.getStateChange() == ItemEvent.SELECTED);
            }
        });
 
        viewMenu.add(showStatusBar);
        menubar.add(fileMenu);
        menubar.add(viewMenu);
 
        setJMenuBar(menubar);
    }

    public static void main(String[] args) {

        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                CheckBoxMenuItemEx ex = new CheckBoxMenuItemEx();
                ex.setVisible(true);
            }
        });
    }
}

Chúng ta sẽ tạo một check box có chức năng ẩn/hiện thanh trạng thái.

statusbar = new JLabel("Ready");
statusbar.setBorder(BorderFactory.createEtchedBorder());
add(statusbar, BorderLayout.SOUTH);   

Để tạo status bar thì chúng ta tạo một đối tượng JLabel rồi dùng phương thức JFrame.add() để thêm label này vào phía dưới cửa sổ chỉ định bằng lớp BorderLayout, ngoài ra ở đây chúng ta dùng thêm phương thức setBorder() để tạo viền xung quanh label.

JCheckBoxMenuItem showStatusBar = new JCheckBoxMenuItem("Show statubar");
showStatusBar.setMnemonic(KeyEvent.VK_S);
showStatusBar.setDisplayedMnemonicIndex(5);

Chúng ta thiết lập mnemonic cho check box, ngoài ra chúng ta chỉ định cho kí tự được gạch chân thông qua phương thức setDisplayedMnemonicIndex() vì trong đoạn text của check box có nhiều kí tự S.

showStatusBar.setSelected(true);

Chúng ta thiết lập cho check box mặc định là đã được check.

showStatusBar.addItemListener(new ItemListener() {

    @Override
    public void itemStateChanged(ItemEvent e) {        
        statusbar.setVisible(e.getStateChange() == ItemEvent.SELECTED)        
    }

});

Chúng ta tạo một listener cho check box để lắng nghe sự kiện thay đổi trạng thái check và thiết lập ẩn/hiện cho status bar.

Untitled

Tạo popup menu

Popup menu hay còn được gọi là menu ngữ cảnh là loại menu chỉ hiển thị khi chúng ta click chuột lên vùng trống của cửa sổ. Java Swing cung cấp lớp JPopupMenu để hỗ trợ tạo popupmenu.

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;

public class PopupMenuEx extends JFrame {

    private JPopupMenu popupMenu;

    public PopupMenuEx() {

        initUI();
    }

    private void initUI() {

        popupMenu = new JPopupMenu();
 
        JMenuItem maxItem = new JMenuItem("Maximize");
        maxItem.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                if(getExtendedState() != JFrame.MAXIMIZED_BOTH)
                    setExtendedState(JFrame.MAXIMIZED_BOTH);
            } 
        });
    
        popupMenu.add(maxItem);
 
        JMenuItem quitItem = new JMenuItem("Quit");
        quitItem.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
            System.exit(0);
            }
        });
 
        popupMenu.add(quitItem);
 
        addMouseListener(new MouseAdapter()
        {
            @Override
            public void mouseReleased(MouseEvent e)
            {
                if(e.getButton() == MouseEvent.BUTTON3)
                popupMenu.show(e.getComponent(), e.getX(), e.getY());
            }
        });

        setTitle("Menu Example");
        setSize(300, 200);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }   

    public static void main(String[] args) {

        EventQueue.invokeLater(new Runnable() {
            
            @Override
            public void run() {
                PopupMenuEx pm = new PopupMenuEx();
                pm.setVisible(true);
            }
        });
    }
}

Trong ví dụ này chúng ta tạo popup menu có 2 item là maximizequit. Chức năng maximize sẽ phóng to cửa sổ.

popupMenu = new JPopupMenu();

Đầu tiên chúng ta tạo một đối tượng JPopupMenu.

JMenuItem maxItem = new JMenuItem("Maximize");
maxItem.addActionListener(new ActionListener() {
    
    @Override
    public void actionPerformed(ActionEvent e) {

        if (getExtendedState() != JFrame.MAXIMIZED_BOTH) {
            setExtendedState(JFrame.MAXIMIZED_BOTH);
        }

    }
});

Chúng ta tạo item maximize mà tạo listener cho item này. Phương thức JFrame.setExtendedState(JFrame.MAXIMIZED_BOTH) sẽ phóng to cửa sổ lên mức tối đa, ngoài ra còn có các kiểu co dãn cửa sổ khác là NORMAL, ICONIFIEDMAXIMIZED_HORIZ, và MAXIMIZED_VERT.

popupMenu.add(maxItem);

Sau đó chúng ta thêm item vào menu như thường.

addMouseListener(new MouseAdapter() {

    @Override
    public void mouseReleased(MouseEvent e) {

        if (e.getButton() == MouseEvent.BUTTON3) {
            popupMenu.show(e.getComponent(), e.getX(), e.getY());
        }
    }
});

Chúng ta dùng phương thức show() để hiển thị popup menu tại vị trí mà chúng ta muốn, ở đây mình tạo một listener cho cửa sổ chính và xử lý sự kiện thả chuột (sau khi nhấn chuột rồi thả ra thì phương thức mouseReleased() sẽ được gọi, chúng ta có thể lấy tọa độ của chuột cũng như các thông tin khác trong tham số MouseEvent).

Untitled

Tạo toolbar

Nếu như menu gộp nhóm các nút chức năng lại với nhau thì toolbar hiển thị các nút chức năng một cách độc lập để người dùng có thể thao tác một cách nhanh nhất. Java Swing cung cấp lớp JToolbar hỗ trợ tạo toolbar.

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JToolBar;


public class ToolbarEx extends JFrame {

    public ToolbarEx() {
        
        initUI();
    }

    private void initUI() {
        
        JMenuBar menubar = new JMenuBar();
        JMenu fileMenu = new JMenu("File");
        menubar.add(fileMenu);
        setJMenuBar(menubar);
 
        JToolBar toolbar = new JToolBar();
 
        ImageIcon icon = new ImageIcon("F:/exit.png");
 
        JButton exitButton = new JButton(icon);
        toolbar.add(exitButton);
 
        exitButton.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                System.exit(0);
            }
        });
 
        add(toolbar, BorderLayout.NORTH);
 
        setTitle("Menu Example");
        setSize(300, 300);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);        
    }

    public static void main(String[] args) {
        
        EventQueue.invokeLater(new Runnable() {
            
            @Override
            public void run() {
                ToolbarEx ex = new ToolbarEx();
                ex.setVisible(true);
            }
        });
    }
}

Chúng ta sẽ tạo một toolbar có một button.

JToolBar toolbar = new JToolBar();

Đầu tiên là tạo một đối tượng JToolbar.

JButton exitButton = new JButton(icon);
toolbar.add(exitButton);

Tiếp theo chúng ta tạo một đối tượng JButton rồi thêm vào toolbar.

add(toolbar, BorderLayout.NORTH);

Chúng ta hiển thị toolbar lên cửa sổ với phương thức add(), tham số BorderLayout.NORTH hiển thị toolbar ở phía trên cửa sổ.

Untitled