package org.jtheque.views.utils; import org.jtheque.features.CoreFeature; import org.jtheque.features.Feature; import org.jtheque.features.Menu; import org.jtheque.i18n.Internationalizable; import org.jtheque.i18n.LanguageService; import org.jtheque.ui.Controller; import org.jtheque.ui.utils.actions.ActionFactory; import org.jtheque.ui.utils.actions.JThequeAction; import org.jtheque.utils.collections.CollectionUtils; import javax.swing.Action; import javax.swing.KeyStroke; import java.awt.Toolkit; import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Map; import static org.jtheque.features.Features.newActionFeature; import static org.jtheque.features.Features.newSeparatedActionFeature; /* * Copyright JTheque (Baptiste Wicht) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * An abstract menu. This class provide several a method to specify features for each of the core features. This methods * are only called once and the result are kept in cache for the next call of the Menu methods. On the same way, this * class provide a method to specify the main features. This method are also cached. * * @author Baptiste Wicht */ public abstract class AbstractMenu implements Menu { private final Map<String, List<Feature>> cache = CollectionUtils.newHashMap(5); private final Collection<Internationalizable> internationalizables = CollectionUtils.newList(); //Public methods @Override public final List<Feature> getSubFeatures(CoreFeature feature) { switch (feature) { case FILE: loadSubFeatures(CoreFeature.FILE, getFileMenuSubFeatures()); break; case EDIT: loadSubFeatures(CoreFeature.EDIT, getEditMenuSubFeatures()); break; case ADVANCED: loadSubFeatures(CoreFeature.ADVANCED, getAdvancedMenuSubFeatures()); break; case HELP: loadSubFeatures(CoreFeature.HELP, getHelpMenuSubFeatures()); break; } return cache.get(feature.name()); } /** * Load the sub features of the given core feature. * * @param feature The core feature. * @param subFeatures The sub features to add to the given core feature. */ private void loadSubFeatures(CoreFeature feature, List<Feature> subFeatures) { if (!cache.containsKey(feature.name())) { cache.put(feature.name(), subFeatures); } } @Override public final List<Feature> getMainFeatures() { if (!cache.containsKey("MAIN")) { cache.put("MAIN", getMenuMainFeatures()); } return cache.get("MAIN"); } //Methods to override /** * Return the main features of this menu. This method will only be called once and the result will be cached. * * @return A List containing all the main features of this menu. */ protected List<Feature> getMenuMainFeatures() { return CollectionUtils.emptyList(); } /** * Return all the sub features of the "File" menu. This method will only be called once and the result will be * cached. * * @return A List containing all the sub features of "File" menu. */ protected List<Feature> getFileMenuSubFeatures() { return CollectionUtils.emptyList(); } /** * Return all the sub features of the "Edit" menu. This method will only be called once and the result will be * cached. * * @return A List containing all the sub features of "Edit" menu. */ protected List<Feature> getEditMenuSubFeatures() { return CollectionUtils.emptyList(); } /** * Return all the sub features of the "Advanced" menu. This method will only be called once and the result will be * cached. * * @return A List containing all the sub features of "Advanced" menu. */ protected List<Feature> getAdvancedMenuSubFeatures() { return CollectionUtils.emptyList(); } /** * Return all the sub features of the "Help" menu. This method will only be called once and the result will be * cached. * * @return A List containing all the sub features of "Help" menu. */ protected List<Feature> getHelpMenuSubFeatures() { return CollectionUtils.emptyList(); } //Utility methods /** * Create a separated (it seems with a line separator) feature. * * @param position The position of the feature. * @param action The action. * @param image The image name. * * @return The created separated feature. */ protected Feature createSeparatedSubFeature(int position, JThequeAction action, String image) { internationalizables.add(action); return newSeparatedActionFeature(position, action, image); } /** * Create a separated (it seems with a line separator) feature. * * @param position The position of the feature. * @param action The action. * @param image The image name. * @param accelerator The menu accelerator. * * @return The created separated feature. */ protected Feature createSeparatedSubFeature(int position, JThequeAction action, String image, int accelerator) { Feature feature = createSeparatedSubFeature(position, action, image); feature.getAction().putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(accelerator, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); return feature; } /** * Create a separated (it seems with a line separator) feature. * * @param position The position of the feature. * @param action The action of the feature. * * @return The created separated feature. */ protected Feature createSeparatedSubFeature(int position, JThequeAction action) { internationalizables.add(action); return newSeparatedActionFeature(position, action); } /** * Create a feature. * * @param position The position of the feature. * @param action The action. * @param image The image name. * * @return The created feature. */ protected Feature createSubFeature(int position, JThequeAction action, String image) { internationalizables.add(action); return newActionFeature(position, action, image); } /** * Create a feature. * * @param position The position of the feature. * @param action The action of the feature. * * @return The created feature. */ protected Feature createSubFeature(int position, JThequeAction action) { internationalizables.add(action); return newActionFeature(position, action); } /** * Transform all the features into a List of features. * * @param features The features to put in the list. * * @return A List of features containing all the features in parameters. */ protected static List<Feature> features(Feature... features) { return Arrays.asList(features); } //Utility action methods /** * Create an action linked to the controller. * * @param key The i18n key of the action. * @param controller The controller to bind the action to. * * @return The JThequeAction for this controller binding. */ public static JThequeAction createControllerAction(String key, Controller<?> controller) { return ActionFactory.createAction(key, controller); } @Override public void refreshText(LanguageService languageService) { for (Internationalizable internationalizable : internationalizables) { internationalizable.refreshText(languageService); } } }