org.nuiton.jaxx.runtime.swing.action.MenuAction Maven / Gradle / Ivy
package org.nuiton.jaxx.runtime.swing.action;
/*-
* #%L
* JAXX :: Runtime
* %%
* Copyright (C) 2008 - 2024 Code Lutin, Ultreia.io
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* .
* #L%
*/
import javax.swing.AbstractButton;
import javax.swing.Action;
import javax.swing.JComponent;
import javax.swing.JPopupMenu;
import javax.swing.KeyStroke;
import javax.swing.MenuElement;
import javax.swing.MenuSelectionManager;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
/**
* Add this contract on any action that should be in a menu.
*
* The keyStroke will be generated (from 'A', 'B', ...), should be more customizable but form the moment KISS approach.
*
* Created on 23/11/2020.
*
* @author Tony Chemit - [email protected]
* @since 3.0
*/
public interface MenuAction extends Action {
static KeyStroke getMenuKeyStroke(JPopupMenu popupMenu) {
return KeyStroke.getKeyStroke("pressed " + (char) ('A' + (popupMenu.getSubElements().length)));
}
static void preparePopup(JPopupMenu popupMenu, JComponent c, boolean selectLast) {
if (popupMenu.isVisible()) {
popupMenu.setVisible(false);
return;
}
popupMenu.setBorderPainted(true);
popupMenu.pack();
Dimension dim = popupMenu.getPreferredSize();
int x = (int) (c.getPreferredSize().getWidth() - dim.getWidth());
int y = c.getHeight();
popupMenu.show(c, x, y);
if (selectLast) {
selectLast(popupMenu);
} else {
selectFirst(popupMenu);
}
}
static void selectFirst(JPopupMenu popupMenu) {
int componentCount = popupMenu.getComponentCount();
if (componentCount == 0) {
return;
}
int index = 0;
Component component = popupMenu.getComponent(index);
while (!(component instanceof MenuElement) || !component.isEnabled()) {
if (index >= componentCount) {
return;
}
component = popupMenu.getComponent(index++);
}
MenuSelectionManager.defaultManager().setSelectedPath(new MenuElement[]{popupMenu, (MenuElement) component});
}
static void selectLast(JPopupMenu popupMenu) {
int componentCount = popupMenu.getComponentCount();
if (componentCount == 0) {
return;
}
int index = componentCount - 1;
Component component = popupMenu.getComponent(index);
while (!(component instanceof MenuElement) || !component.isEnabled()) {
if (index == 0) {
return;
}
component = popupMenu.getComponent(index--);
}
MenuSelectionManager.defaultManager().setSelectedPath(new MenuElement[]{popupMenu, (MenuElement) component});
}
JPopupMenu getPopupMenu();
AbstractButton getEditor();
void setKeyStroke(KeyStroke keyStroke);
default void initUI() {
KeyStroke keyStroke = getMenuKeyStroke();
setKeyStroke(keyStroke);
AbstractButton editor = getEditor();
getPopupMenu().add(editor);
initEditor();
}
default void initEditor() {
AbstractButton editor = getEditor();
editor.setOpaque(true);
editor.setBackground(Color.WHITE);
}
default KeyStroke getMenuKeyStroke() {
return getMenuKeyStroke(getPopupMenu());
}
}