Java : Masquer un JMenuBar avec le raccourci Ctrl+H

Partager cet article

Temps estimé pour la lecture de cet article : 17 min

Salut à tous !

Après la customisation d’un JTabbedPane ou des composants JButton et JPanel. Aujourd’hui, j’aimerais faire un article sur le JMenuBar du paquet Swing de Java.

En tant qu’utilisateur j’aime personnaliser mon interface a mon envie, comme par exemple pouvoir masquer le menu du logiciel grâce à un raccourci. Pour ce faire quoi de plus logique que d’utiliser un accélérateur. Prenons un exemple de projet tout bête, avec une classe pour la fenêtre, une pour le menu, un contrôleur à ce menu et une classe pour lancer le tout.

Le launcher

On créé une instance de la fenêtre et on créé le contrôleur du menu.

public class Launcher {
	public static void main(String[] args) {
		Window w = new Window();
		MenuController mc = new MenuController(w);
	}
}

La fenêtre

On créé un menu dans la fenêtre et on set le menu à la fenêtre grâce à la fonction setJMenuBar(). On Centre la fenêtre grâce au setLocationRelativeTo(null).

import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JRootPane;
import javax.swing.KeyStroke;

public class Window extends JFrame {

	private static final long serialVersionUID = 1L;
	private Menu m;

	public Window() {
		m = new Menu();
		this.setTitle("JMenu and KeyStroke");
		this.setSize(400, 500);
		this.setLocationRelativeTo(null);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setVisible(true);
		this.setJMenuBar(m);
	}
	
	public Menu getMenu() {
		return m;
	}

}

Le Menu

On créé un JMenu et on lui ajoute deux objets. Le fameuse option pour cacher le menu, à laquelle on ajoute l’accélérateur Ctrl+h.

import java.awt.event.KeyEvent;

import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.KeyStroke;

public class Menu extends JMenuBar {

	private static final long serialVersionUID = 1L;
	private JMenuItem hide = new JMenuItem();
	private JMenuItem quit = new JMenuItem();

	public Menu() {
		JMenu menu = new JMenu("Fichier");

		hide.setText("Masquer le menu");
		hide.setEnabled(true);
		hide.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_H,KeyEvent.CTRL_MASK));
		menu.add(hide);

		quit.setText("Quitter");
		quit.setEnabled(true);
		quit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q,KeyEvent.CTRL_MASK));
		menu.add(quit);

		add(menu);
	}

	public JMenuItem getQuit() {
		return quit;
	}

	public JMenuItem getHide() {
		return hide;
	}

}

La classe MenuController

On récupère le menu grâce au getter de la classe fenêtre et on essaye d’affecter le comportement que l’on souhaite au JMenuBar.

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class MenuController implements ActionListener {

    protected Window w;
    protected Menu m;

    public MenuController(Window w) {
        this.w = w;
        this.m = w.getMenu();
        m.getQuit().addActionListener(this);
        m.getHide().addActionListener(this);
    }

    public void actionPerformed(ActionEvent e) {
        String item = e.getActionCommand();
        if (item.equals("Quitter"))
            System.exit(0);
        if(item.equals("Masquer le menu")) {
            if(m.isVisible() == true)
                m.setVisible(false);
            else
                m.setVisible(true);
        }
    }    
}

Résultat

Ce qui nous donne, ce magnifique menu :

Java - JMenu résultat

Java – JMenu résultat

Si vous lancez le projet, vous aurez la grande surprise de vous apercevoir qu’on peut en effet, masquer le menu grâce à l’accélérateur prévu à cet effet, mais une fois que vous allez masquer votre menu, vous allez perdre vos accélérateurs, un peu dommage non ? Heureusement, il existe bien sûr une solution pour régler ce problème. On peut utiliser un keybinding sur l’élément parent ! On peut ajouter un keybinding (raccourci clavier en français) sur n’importe quel composant. Ici pour pouvoir cacher le menu, on va donc créer un raccourci sur l’élément parent, ici la fenêtre. On fait ça en deux étapes :

  • Avec la fonction registerKeyStroke(), on créé le kesystroke ctrl + h. On applique ce raccourci au composant et on lui ajoute une action.
  • Il nous reste plus qu’à définir ce que va faire l’action hideMenu, que l’on créé plus bas en créant une instance d’AbstractAction.

Résumé du code final

On a donc au final :

import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JRootPane;
import javax.swing.KeyStroke;

public class Window extends JFrame {

	private static final long serialVersionUID = 1L;
	private Menu m;

	public Window() {
		m = new Menu();
		this.setTitle("JMenu and KeyStroke");
		this.setSize(400, 500);
		this.setLocationRelativeTo(null);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setVisible(true);
		this.setJMenuBar(m);

		registerKeyStroke();
	}
	
	private void registerKeyStroke() {
		JRootPane rootPane = this.getRootPane();
		KeyStroke ctrlh = KeyStroke.getKeyStroke(KeyEvent.VK_H, InputEvent.CTRL_MASK);
		rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(ctrlh, "hideMenu");
		rootPane.getActionMap().put("hideMenu", hideMenu);
	}
	
	private Action hideMenu = new AbstractAction() {
		public void actionPerformed(ActionEvent e) {
			if (m.isVisible() == true) {
				m.setVisible(false);
			} else {
				m.setVisible(true);
			}	
		}
	};

	public Menu getMenu() {
		return m;
	}

}

Et tadda, vous pouvez maintenant masquer votre JMenu grâce au raccourci ctrl+h !

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.