Package org.openscience.jchempaint

Source Code of org.openscience.jchempaint.JChemPaintMenuHelper

package org.openscience.jchempaint;

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Image;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.MissingResourceException;
import java.util.Properties;

import javax.swing.ImageIcon;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JComponent;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.KeyStroke;
import javax.swing.event.MenuEvent;
import javax.swing.event.MenuListener;

import org.openscience.cdk.config.XMLIsotopeFactory;
import org.openscience.cdk.interfaces.IIsotope;
import org.openscience.cdk.tools.ILoggingTool;
import org.openscience.cdk.tools.LoggingToolFactory;
import org.openscience.jchempaint.action.JCPAction;


/**
* A class containing various helper methods used in JChemPaintMenuBar and JChemPaintPopupMenu.
*
*/
public class JChemPaintMenuHelper {

    private static ILoggingTool logger =
        LoggingToolFactory.createLoggingTool(JChemPaintMenuHelper.class);
    private JCPAction jcpaction;
    private static List<String> usedKeys;


    /**
     * Constructor for JChemPaintMenuHelper
     */
    public JChemPaintMenuHelper(){
        usedKeys = new ArrayList<String>();
    }


    /**
     *  Return the JCPAction instance associated with this JCPPanel.
     *
     *  @return    The jCPAction value
     */
    private JCPAction getJCPAction() {
        if (jcpaction == null) {
            jcpaction = new JCPAction();
        }
        return jcpaction;
    }

    /**
     *  Returns the definition of the subitems of a menu as in the properties files.
     *
     * @param  key       The key for which subitems to return
     * @param  guiString The string identifying the gui to build (i. e. the properties file to use)
     * @return         The resource string
     */
    public String getMenuResourceString(String key, String guiString) {
        String str;
        try {
            str = JCPPropertyHandler.getInstance(true).getGUIDefinition(guiString).getString(key);
        } catch (MissingResourceException mre) {
            str = null;
        }
        return str;
    }

    /**
     *  Creates a JMenu given by a String with all the MenuItems specified in the
     *  properties file.
     *
     * @param  key       The String used to identify the Menu
     * @param  jcpPanel  Description of the Parameter
     * @param  isPopup   Tells if this menu will be a popup one or not
     * @param  guiString The string identifying the gui to build (i. e. the properties file to use)
     * @param  blacklist       A list of menuitesm/buttons which should be ignored when building gui.
     * @return           The created JMenu
     */
    protected JComponent createMenu(AbstractJChemPaintPanel jcpPanel, String key, boolean isPopup, String guiString, List<String> blacklist) {
        logger.debug("Creating menu: ", key);
        JMenu menu = new JMenu(jcpPanel.getMenuTextMaker().getText(key));
        menu.setName(key);
        return createMenu(jcpPanel, key, isPopup, guiString, menu, blacklist);
    }


    /**
     *  Creates a JMenu given by a String with all the MenuItems specified in the
     *  properties file.
     *
     * @param  key       The String used to identify the Menu
     * @param  jcpPanel  Description of the Parameter
     * @param  isPopup   Tells if this menu will be a popup one or not
     * @param  guiString The string identifying the gui to build (i. e. the properties file to use)
     * @param  menu     The menu to add the new menu to (must either be JMenu or JPopupMenu)
     * @param  blacklist       A list of menuitesm/buttons which should be ignored when building gui.
     * @return           The created JMenu
     */
    protected JComponent createMenu(final AbstractJChemPaintPanel jcpPanel, String key, boolean isPopup, String guiString, final JComponent menu, List<String> blacklist) {
      // Blacklist entire menu
      if (blacklist.contains(key)){
        return null;
      }

      String[] itemKeys = StringHelper.tokenize(getMenuResourceString(key, guiString));
        for (int i = 0; i < itemKeys.length; i++) {
          if (!blacklist.contains(itemKeys[i]) && !blacklist.contains(itemKeys[i].substring(1))){
              if (itemKeys[i].equals("-")) {
                  if(menu instanceof JMenu)
                      ((JMenu)menu).addSeparator();
                  else
                      ((JPopupMenu)menu).addSeparator();
              }
              else if (itemKeys[i].startsWith("@")) {
                  JComponent me = createMenu(jcpPanel, itemKeys[i].substring(1), isPopup, guiString, blacklist);
                  menu.add(me);
              }
              else {
                  JMenuItem mi = createMenuItem(jcpPanel, itemKeys[i], isPopup);
                  menu.add(mi);
              }
          }
        }
        if(key.equals("atomMenu")){
            jcpPanel.atomMenu=(JMenu)menu;
            jcpPanel.enOrDisableMenus((JMenu)menu, false);
        }
        if(key.equals("bondMenu")){
            jcpPanel.bondMenu=(JMenu)menu;
            jcpPanel.enOrDisableMenus((JMenu)menu, false);
        }

        if(key.equals("isotopeChange")){
            ((JMenu)menu).addMenuListener(new MenuListener(){
                public void menuCanceled(MenuEvent arg0) {
                }

                public void menuDeselected(MenuEvent arg0) {
                }

                public void menuSelected(MenuEvent arg0) {
                    menu.removeAll();
                    //the following condition is nasty, but necessary, since depending on if model and/or selection
                    //is empty, various commands return null
                    if((SwingPopupModule.lastAtomPopupedFor!=null && SwingPopupModule.lastAtomPopupedFor.getSymbol()!=null)
                            || (jcpPanel.getRenderPanel().getRenderer().getRenderer2DModel().getSelection()!=null &&
                                    jcpPanel.getRenderPanel().getRenderer().getRenderer2DModel().getSelection().getConnectedAtomContainer()!=null &&
                                    jcpPanel.getRenderPanel().getRenderer().getRenderer2DModel().getSelection().getConnectedAtomContainer().getAtomCount()>0)){
                        try {
                            String symbol;
                            if(jcpPanel.getRenderPanel().getRenderer().getRenderer2DModel().getSelection().getConnectedAtomContainer()!=null && jcpPanel.getRenderPanel().getRenderer().getRenderer2DModel().getSelection().getConnectedAtomContainer().getAtomCount()>0)
                                symbol = jcpPanel.getRenderPanel().getRenderer().getRenderer2DModel().getSelection().getConnectedAtomContainer().getAtom(0).getSymbol();
                            else
                                symbol = SwingPopupModule.lastAtomPopupedFor.getSymbol();
                            IIsotope[] isotopes = XMLIsotopeFactory.getInstance(jcpPanel.getChemModel().getBuilder()).getIsotopes(symbol);
                            for(int i=0;i<isotopes.length;i++){
                                String cmd=isotopes[i].getSymbol()+isotopes[i].getMassNumber();
                                JMenuItem mi = new JMenuItem(cmd);
                                mi.setName(cmd);
                                usedKeys.add(cmd);
                                String astr="org.openscience.jchempaint.action.ChangeIsotopeAction@specific"+isotopes[i].getMassNumber();
                                mi.setActionCommand(astr);
                                JCPAction action = getJCPAction().getAction(jcpPanel, astr, false);
                                if (action != null) {
                                    // sync some action properties with menu
                                    mi.setEnabled(action.isEnabled());
                                    mi.addActionListener(action);
                                    logger.debug("Coupled action to new menu item...");
                                }
                                menu.add(mi);
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        }             
                    }else{
                        menu.add(new JChemPaintMenuHelper().createMenuItem(jcpPanel, "majorPlusThree", false));
                        menu.add(new JChemPaintMenuHelper().createMenuItem(jcpPanel, "majorPlusTwo", false));
                        menu.add(new JChemPaintMenuHelper().createMenuItem(jcpPanel, "majorPlusOne", false));
                        menu.add(new JChemPaintMenuHelper().createMenuItem(jcpPanel, "major", false));
                        menu.add(new JChemPaintMenuHelper().createMenuItem(jcpPanel, "majorMinusOne", false));
                        menu.add(new JChemPaintMenuHelper().createMenuItem(jcpPanel, "majorMinusTwo", false));
                        menu.add(new JChemPaintMenuHelper().createMenuItem(jcpPanel, "majorMinusThree", false));
                        jcpPanel.enOrDisableMenus((JMenu)menu, jcpPanel.getRenderPanel().getRenderer().getRenderer2DModel().getSelection()==null || !jcpPanel.getRenderPanel().getRenderer().getRenderer2DModel().getSelection().isFilled() && jcpPanel.getRenderPanel().getRenderer().getRenderer2DModel().getHighlightedAtom()==null ? false : true);
                    }
                }
            });
        }
        //we make large menus two columns
        JPopupMenu p;
        if(menu instanceof JMenu)
            p = ((JMenu)menu).getPopupMenu();
        else
            p = (JChemPaintPopupMenu)menu;
        if(p.getComponents().length>30){
            Dimension d = p.getPreferredSize();
            d = new Dimension((int)(d.width * 2.5), (int)(d.height * 0.7));
            p.setPreferredSize(d);
            p.setLayout(new FlowLayout());
        }
        if(menu instanceof JMenu)
            jcpPanel.menus.add((JMenu)menu);
        else if(menu instanceof JChemPaintPopupMenu)
            jcpPanel.popupmenuitems.put(key, (JChemPaintPopupMenu)menu);
        return menu;
    }


    /**
     *  Creates a JMenuItem given by a String and adds the right ActionListener to
     *  it.
     *
     * @param  cmd         String The String to identify the MenuItem
     * @param  jcpPanel    Description of the Parameter
     * @param  isPopupMenu Tells if this menu will be a popup one or not
     * @return             JMenuItem The created JMenuItem
     */
    protected JMenuItem createMenuItem(AbstractJChemPaintPanel jcpPanel, String cmd, boolean isPopupMenu) {
        logger.debug("Creating menu item: ", cmd);
        boolean isCheckBox=false;
        if (cmd.endsWith("+")){
            isCheckBox=true;
            cmd=cmd.substring(0, cmd.length() - 1);
        }
        boolean isChecked=false;
        if (cmd.endsWith("+")){
            isChecked=true;
            cmd=cmd.substring(0, cmd.length() - 1);
        }

        Properties userProps = JCPPropertyHandler.getInstance(true).getJCPProperties();
        if (userProps.containsKey(cmd + ".value")) {
            isChecked = Boolean.parseBoolean(userProps.getProperty(cmd + ".value"));
        }
       
        String translation = "***" + cmd + "***";
        try {
            translation = jcpPanel.getMenuTextMaker().getText(cmd);
            logger.debug("Found translation: ", translation);
        } catch (MissingResourceException mre) {
            logger.error("Could not find translation for: " + cmd);
        }
        JMenuItem mi = null;
        if (isCheckBox) {
            mi = new JCheckBoxMenuItem(translation);
            mi.setSelected(isChecked);
        }
        else {
            mi = new JMenuItem(translation);
        }
        JCPPropertyHandler jcpph = JCPPropertyHandler.getInstance(true);
        URL url = jcpph.getResource(cmd + JCPAction.imageSuffix);
        if (url != null)
        {
            ImageIcon image = new ImageIcon(url);
            Image img = image.getImage();
            Image newimg = img.getScaledInstance(16, 16, java.awt.Image.SCALE_SMOOTH);
            mi.setIcon(new ImageIcon(newimg));
            URL disabledurl = jcpph.getResource(cmd + JCPAction.disabled_imageSuffix);
            if (disabledurl != null){
                ImageIcon disabledimage = new ImageIcon(disabledurl);
                if (image != null){
                    Image disabledimg = disabledimage.getImage();
                    Image disablednewimg = disabledimg.getScaledInstance(16, 16, java.awt.Image.SCALE_SMOOTH);
                    mi.setDisabledIcon(new ImageIcon(disablednewimg));
                }
            }
        }
        //this is to avoid to get a menu with the same name twice
        if(usedKeys.contains(cmd))
            mi.setName(cmd+"2");
        else
            mi.setName(cmd);
        usedKeys.add(cmd);
        logger.debug("Created new menu item...");
        String astr = JCPPropertyHandler.getInstance(true).getResourceString(cmd + JCPAction.actionSuffix);
        if (astr == null) {
            astr = cmd;
        }
        mi.setActionCommand(astr);
        JCPAction action = getJCPAction().getAction(jcpPanel, astr, isPopupMenu);
        if (action != null) {
            // sync some action properties with menu
            mi.setEnabled(action.isEnabled());
            mi.addActionListener(action);
            logger.debug("Coupled action to new menu item...");
        }
        else {
            logger.error("Could not find JCPAction class for:" + astr);
            mi.setEnabled(false);
        }
        if(!isPopupMenu)
            addShortCuts(cmd, mi, jcpPanel);
        if(cmd.equals("undo"))
            jcpPanel.undoMenu=mi;
        if(cmd.equals("redo"))
            jcpPanel.redoMenu=mi;
        jcpPanel.menus.add((JMenuItem)mi);
        return mi;
    }


    /**
     *  Adds ShortCuts to the JChemPaintMenuBar object.<br>
     *  This simplifies and replaces the previous approach using Keycodes (VK_xxx)
     *  Keycodes do not work across different keyboards, notably the + key
     *  for zooming is problematic.<br>
     *  More here: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4262044
     *
     * @param  cmd  String The Strin to identify the MenuItem.
     * @param  mi   the regarding MenuItem.
     * @param  jcp  The JChemPaintPanel this menu is used for.
     */
    private void addShortCuts(String cmd, JMenuItem mi, AbstractJChemPaintPanel jcp) {
        Properties shortCutProps = JCPPropertyHandler.getInstance(true).getJCPShort_Cuts();

        String keyString = shortCutProps.getProperty(cmd);
        if (keyString != null) {
            KeyStroke keyStroke = KeyStroke.getKeyStroke(keyString);
            mi.setAccelerator(keyStroke);
            jcp.getInputMap().put(keyStroke, mi);
            jcp.getActionMap().put(mi, mi.getAction());
        }
    }


}
TOP

Related Classes of org.openscience.jchempaint.JChemPaintMenuHelper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.