fr.ird.observe.client.action.UIActionSupport Maven / Gradle / Ivy
/*
* #%L
* ObServe Toolkit :: Common Client
* %%
* Copyright (C) 2008 - 2017 IRD, Ultreia.io
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* .
* #L%
*/
package fr.ird.observe.client.action;
import com.google.common.collect.ImmutableMap;
import fr.ird.observe.client.MainUI;
import fr.ird.observe.client.ObserveKeyStrokes;
import fr.ird.observe.client.form.FormUI;
import io.ultreia.java4all.lang.GetterProducer;
import io.ultreia.java4all.lang.SetterProducer;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.beans.PropertyChangeListener;
import java.util.Objects;
import java.util.function.BiConsumer;
import java.util.function.Function;
import javax.swing.AbstractButton;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.Icon;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JOptionPane;
import javax.swing.KeyStroke;
import javax.swing.event.SwingPropertyChangeSupport;
import org.nuiton.jaxx.runtime.JAXXObject;
import org.nuiton.jaxx.runtime.swing.SwingUtil;
import static org.nuiton.i18n.I18n.t;
/**
* Pour implanter les actions communes.
*
* @author Tony Chemit - [email protected]
* @since 1.4
*/
public abstract class UIActionSupport implements Action, GetterProducer, SetterProducer {
public static final String EDITOR = "editor";
private static final String ENABLED = "enabled";
public static final String CLIENT_PROPERTY_UI = "ui";
private static final ImmutableMap> GETTERS =
ImmutableMap.>builder()
.put(ACTION_COMMAND_KEY, UIActionSupport::getActionCommandKey)
.put(NAME, UIActionSupport::getText)
.put(SHORT_DESCRIPTION, UIActionSupport::getTooltipText)
.put(ACCELERATOR_KEY, UIActionSupport::getAcceleratorKey)
.put(SMALL_ICON, UIActionSupport::getIcon)
.put(MNEMONIC_KEY, UIActionSupport::getMnemonic)
.put(EDITOR, UIActionSupport::getEditor)
.build();
private static final ImmutableMap> SETTERS =
ImmutableMap.>builder()
.put(ACTION_COMMAND_KEY, (e, v) -> e.setName((String) v))
.put(NAME, (e, v) -> e.setText((String) v))
.put(SHORT_DESCRIPTION, (e, v) -> e.setTooltipText((String) v))
.put(ACCELERATOR_KEY, (e, v) -> e.setKeyStroke((KeyStroke) v))
.put(SMALL_ICON, (e, v) -> e.setIcon((Icon) v))
.put(MNEMONIC_KEY, (e, v) -> e.setMnemonic((char) v))
.build();
private final MainUI mainUI;
private String name;
private String text;
private String tooltipText;
private KeyStroke keyStroke;
private char mnemonic;
private Icon icon;
private JComponent editor;
private boolean enabled;
private SwingPropertyChangeSupport changeSupport;
public interface Update {
void updateAction(JAXXObject ui, AbstractButton editor);
}
@SuppressWarnings("unchecked")
@Override
public O get(String propertyName) {
Function getter = (Function) GETTERS.get(propertyName);
Objects.requireNonNull(getter, String.format("Can't find a getter for property: %s on %s", propertyName, getClass().getName()));
return getter.apply(this);
}
@SuppressWarnings("unchecked")
@Override
public void set(String propertyName, O o) {
BiConsumer setter = (BiConsumer) SETTERS.get(propertyName);
Objects.requireNonNull(setter, String.format("Can't find a setter for property: %s on %s", propertyName, getClass().getName()));
setter.accept(this, o);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getText() {
return text;
}
public String getTooltipText() {
return tooltipText;
}
public KeyStroke getKeyStroke() {
return keyStroke;
}
public char getMnemonic() {
return mnemonic;
}
public Icon getIcon() {
return icon;
}
public void setKeyStroke(KeyStroke keyStroke) {
this.keyStroke = keyStroke;
}
public void setText(String text) {
this.text = text;
}
public void setTooltipText(String tooltipText) {
this.tooltipText = tooltipText;
}
@Override
public Object getValue(String key) {
return get(key);
}
@Override
public void putValue(String key, Object value) {
set(key, value);
}
public void setIcon(Icon icon) {
this.icon = icon;
}
public void setMnemonic(char mnemonic) {
this.mnemonic = mnemonic;
}
protected UIActionSupport(MainUI mainUI, String actionCommandKey, String label, String shortDescription, String actionIcon, KeyStroke acceleratorKey) {
this(mainUI, actionCommandKey, label, shortDescription, actionIcon, acceleratorKey, true);
}
protected UIActionSupport(MainUI mainUI, String actionCommandKey, String label, String shortDescription, String actionIcon, char acceleratorKey) {
// super(t(label), SwingUtil.getUIManagerActionIcon(actionIcon));
this.name = actionCommandKey;
this.text = t(label);
this.mainUI = mainUI;
if (actionIcon != null) {
icon = SwingUtil.getUIManagerActionIcon(actionIcon);
}
this.mnemonic = acceleratorKey;
ObserveKeyStrokes.addKeyStore(this, KeyStroke.getKeyStroke(acceleratorKey, InputEvent.ALT_MASK), label, shortDescription);
}
protected UIActionSupport(MainUI mainUI, String actionCommandKey, String label, String shortDescription, String actionIcon, KeyStroke acceleratorKey, boolean addKeyStroke) {
// super(t(label), SwingUtil.getUIManagerActionIcon(actionIcon));
this.name = actionCommandKey;
this.mainUI = mainUI;
this.text = t(label);
if (actionIcon != null) {
icon = SwingUtil.getUIManagerActionIcon(actionIcon);
}
if (addKeyStroke) {
ObserveKeyStrokes.addKeyStore(this, acceleratorKey, label, shortDescription);
} else if (acceleratorKey != null) {
keyStroke = acceleratorKey;
}
}
public KeyStroke getAcceleratorKey() {
return keyStroke;
}
public String getActionCommandKey() {
return name;
}
public MainUI getMainUI() {
return mainUI;
}
public JComponent getEditor() {
return editor;
}
public void initAction(JComponent ui, AbstractButton editor) {
editor.setAction(this);
editor.putClientProperty(CLIENT_PROPERTY_UI, ui);
//FIXME Attention on introduit un état dans l'action et si l'action est utilisée plusieurs fois dans un même écran
//FIXME cela va introduire des effets de bord
this.editor = editor;
ObserveKeyStrokes.addKeyStroke2(getMainUI(), editor, getAcceleratorKey());
register(ui.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW), ui.getActionMap());
}
public void initForMainUi(AbstractButton editor) {
initForMainUi(editor, getMainUI().getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW), getMainUI().getRootPane().getActionMap());
getMainUI().registerAction(editor);
}
public void initForMainUi(AbstractButton editor, InputMap inputMap, ActionMap actionMap) {
String text = editor.getText();
String tip = editor.getToolTipText();
editor.setAction(this);
if (text != null && editor.getText() == null) {
editor.setText(text);
}
if (tip != null && editor.getToolTipText() == null) {
editor.setToolTipText(tip);
}
editor.putClientProperty(CLIENT_PROPERTY_UI, getMainUI());
//FIXME Attention on introduit un état dans l'action et si l'action est utilisée plusieurs fois dans un même écran
//FIXME cela va introduire des effets de bord
this.editor = editor;
register(inputMap, actionMap);
}
public void register(InputMap inputMap, ActionMap actionMap) {
KeyStroke keyStroke = getAcceleratorKey();
if (keyStroke != null) {
String actionCommandKey = getActionCommandKey();
register(this, inputMap, actionMap, keyStroke, actionCommandKey);
}
}
public static void register(Action action, InputMap inputMap, ActionMap actionMap, KeyStroke keyStroke, String actionCommandKey) {
if (keyStroke != null) {
inputMap.put(keyStroke, actionCommandKey);
actionMap.put(actionCommandKey, action);
}
}
protected UIActionContext getActionContext() {
return mainUI.getActionContext();
}
@Override
public synchronized void addPropertyChangeListener(PropertyChangeListener listener) {
if (changeSupport == null) {
changeSupport = new SwingPropertyChangeSupport(this);
}
changeSupport.addPropertyChangeListener(listener);
}
@Override
public synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
if (changeSupport == null) {
return;
}
changeSupport.removePropertyChangeListener(listener);
}
public synchronized PropertyChangeListener[] getPropertyChangeListeners() {
if (changeSupport == null) {
return new PropertyChangeListener[0];
}
return changeSupport.getPropertyChangeListeners();
}
protected FormUI getContentUI(ActionEvent e) {
JComponent c = (JComponent) e.getSource();
FormUI ui;
//FIXME On devrait peut-être toujours se baser sur le contentui manager
//FIXME et ne plus rien attacher aux editeurs ?
if (c instanceof FormUI) {
ui = (FormUI) c;
} else if (c.getParent() instanceof FormUI) {
ui = (FormUI) c.getParent();
} else {
ui = (FormUI) c.getClientProperty(CLIENT_PROPERTY_UI);
}
if (ui == null) {
ui = getMainUI().getContentUIManager().getSelectedContentUI();
}
return ui;
}
protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
if (changeSupport == null ||
(oldValue != null && newValue != null && oldValue.equals(newValue))) {
return;
}
changeSupport.firePropertyChange(propertyName, oldValue, newValue);
}
@Override
public boolean isEnabled() {
return enabled;
}
@Override
public void setEnabled(boolean enabled) {
boolean oldValue = isEnabled();
this.enabled = enabled;
firePropertyChange(ENABLED, oldValue, enabled);
}
public void displayInfo(String text) {
getMainUI().displayInfo(text);
}
public void displayInfo(String title, String text) {
getMainUI().displayInfo(title, text);
}
public void displayWarning(String title, String text) {
getMainUI().displayWarning(title, text);
}
public int askUser(String title, String message, int typeMessage, Object[] options, int defaultOption) {
return getMainUI().askUser(title, message, typeMessage, options, defaultOption);
}
public int askUser(String title, Object message, int typeMessage, Object[] options, int defaultOption) {
return getMainUI().askUser(title, message, typeMessage, options, defaultOption);
}
public int askUser(JOptionPane pane, String title, Object[] options) {
return getMainUI().askUser(pane, title, options);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy