Package com.eteks.sweethome3d.swing

Source Code of com.eteks.sweethome3d.swing.SwingTools$MenuItemsVisibilityListener

/*
* SwingTools.java 21 oct. 2008
*
* Sweet Home 3D, Copyright (c) 2008 Emmanuel PUYBARET / eTeks <info@eteks.com>
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
package com.eteks.sweethome3d.swing;

import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.awt.image.FilteredImageSource;
import java.awt.image.RGBImageFilter;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.concurrent.Executors;

import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JToggleButton;
import javax.swing.JViewport;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.AbstractBorder;
import javax.swing.border.Border;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import javax.swing.text.JTextComponent;

import com.eteks.sweethome3d.model.TextureImage;
import com.eteks.sweethome3d.model.UserPreferences;
import com.eteks.sweethome3d.tools.OperatingSystem;

/**
* Gathers some useful tools for Swing.
* @author Emmanuel Puybaret
*/
public class SwingTools {
  // Borders for focused views
  private static Border unfocusedViewBorder;
  private static Border focusedViewBorder;

  private SwingTools() {
    // This class contains only tools
  }

  /**
   * Updates the border of <code>component</code> with an empty border
   * changed to a colored border when it will gain focus.
   * If the <code>component</code> component is the child of a <code>JViewPort</code>
   * instance this border will be installed on its scroll pane parent.
   */
  public static void installFocusBorder(JComponent component) {
    if (unfocusedViewBorder == null) {
      Border unfocusedViewInteriorBorder = new AbstractBorder() {
          private Color  topLeftColor;
          private Color  botomRightColor;
          private Insets insets = new Insets(1, 1, 1, 1);
         
          {
            if (OperatingSystem.isMacOSX()) {
              this.topLeftColor = Color.GRAY;
              this.botomRightColor = Color.LIGHT_GRAY;
            } else {
              this.topLeftColor = UIManager.getColor("TextField.darkShadow");
              this.botomRightColor  = UIManager.getColor("TextField.shadow");
            }
          }
         
          public Insets getBorderInsets(Component c) {
            return this.insets;
          }
   
          public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
            Color previousColor = g.getColor();
            Rectangle rect = getInteriorRectangle(c, x, y, width, height);
            g.setColor(topLeftColor);
            g.drawLine(rect.x - 1, rect.y - 1, rect.x + rect.width, rect.y - 1);
            g.drawLine(rect.x - 1, rect.y - 1, rect.x - 1, rect.y  + rect.height);
            g.setColor(botomRightColor);
            g.drawLine(rect.x, rect.y  + rect.height, rect.x + rect.width, rect.y  + rect.height);
            g.drawLine(rect.x + rect.width, rect.y, rect.x + rect.width, rect.y  + rect.height);
            g.setColor(previousColor);
          }
        };
     
      if (OperatingSystem.isMacOSXLeopardOrSuperior()) {
        unfocusedViewBorder = BorderFactory.createCompoundBorder(
            BorderFactory.createLineBorder(UIManager.getColor("Panel.background"), 2),
            unfocusedViewInteriorBorder);
        focusedViewBorder = new AbstractBorder() {
            private Insets insets = new Insets(3, 3, 3, 3);
           
            public Insets getBorderInsets(Component c) {
              return this.insets;
            }
     
            public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
              Color previousColor = g.getColor();
              // Paint a gradient paint around component
              Rectangle rect = getInteriorRectangle(c, x, y, width, height);
              g.setColor(Color.GRAY);
              g.drawLine(rect.x - 1, rect.y - 1, rect.x + rect.width, rect.y - 1);
              g.drawLine(rect.x - 1, rect.y - 1, rect.x - 1, rect.y  + rect.height);
              g.setColor(Color.LIGHT_GRAY);
              g.drawLine(rect.x, rect.y  + rect.height, rect.x + rect.width, rect.y  + rect.height);
              g.drawLine(rect.x + rect.width, rect.y, rect.x + rect.width, rect.y  + rect.height);
              Color focusColor = UIManager.getColor("Focus.color");
              int   transparencyOutline = 128;
              int   transparencyInline  = 180;
              if (focusColor == null) {
                focusColor = UIManager.getColor("textHighlight");
                transparencyOutline = 128;
                transparencyInline = 255;
              }
              g.setColor(new Color(focusColor.getRed(), focusColor.getGreen(), focusColor.getBlue(), transparencyOutline));
              g.drawRoundRect(rect.x - 3, rect.y - 3, rect.width + 5, rect.height + 5, 6, 6);
              g.drawRect(rect.x - 1, rect.y - 1, rect.width + 1, rect.height + 1);
              g.setColor(new Color(focusColor.getRed(), focusColor.getGreen(), focusColor.getBlue(), transparencyInline));
              g.drawRoundRect(rect.x - 2, rect.y - 2, rect.width + 3, rect.height + 3, 4, 4);

              // Draw corners
              g.setColor(UIManager.getColor("Panel.background"));
              g.drawLine(rect.x - 3, rect.y - 3, rect.x - 2, rect.y - 3);
              g.drawLine(rect.x - 3, rect.y - 2, rect.x - 3, rect.y - 2);
              g.drawLine(rect.x + rect.width + 1, rect.y - 3, rect.x + rect.width + 2, rect.y - 3);
              g.drawLine(rect.x + rect.width + 2, rect.y - 2, rect.x + rect.width + 2, rect.y - 2);
              g.drawLine(rect.x - 3, rect.y + rect.height + 2, rect.x - 2, rect.y + rect.height + 2);
              g.drawLine(rect.x - 3, rect.y + rect.height + 1, rect.x - 3, rect.y + rect.height + 1);
              g.drawLine(rect.x + rect.width + 1, rect.y + rect.height + 2, rect.x + rect.width + 2, rect.y + rect.height + 2);
              g.drawLine(rect.x + rect.width + 2, rect.y + rect.height + 1, rect.x + rect.width + 2, rect.y + rect.height + 1);

              g.setColor(previousColor);
            }
          };
      } else {
        if (OperatingSystem.isMacOSX()) {
          unfocusedViewBorder = BorderFactory.createCompoundBorder(
              BorderFactory.createLineBorder(UIManager.getColor("Panel.background"), 1),
              unfocusedViewInteriorBorder);
        } else {
          unfocusedViewBorder = BorderFactory.createCompoundBorder(
              BorderFactory.createEmptyBorder(1, 1, 1, 1),
              unfocusedViewInteriorBorder);
        }
        focusedViewBorder = BorderFactory.createLineBorder(UIManager.getColor("textHighlight"), 2);
      }
    }
   
    final JComponent feedbackComponent;
    if (component.getParent() instanceof JViewport
        && component.getParent().getParent() instanceof JScrollPane) {
      feedbackComponent = (JComponent)component.getParent().getParent();
    } else {
      feedbackComponent = component;
    }
    feedbackComponent.setBorder(unfocusedViewBorder);
    component.addFocusListener(new FocusListener() {
        public void focusLost(FocusEvent ev) {
          if (feedbackComponent.getBorder() == focusedViewBorder) {
            feedbackComponent.setBorder(unfocusedViewBorder);
          }
        }
       
        public void focusGained(FocusEvent ev) {
          if (feedbackComponent.getBorder() == unfocusedViewBorder) {
            feedbackComponent.setBorder(focusedViewBorder);
          }
        }
      });
  }

  /**
   * Updates the Swing resource bundles in use from the current Locale.
   */
  public static void updateSwingResourceLanguage() {
    // Read Swing localized properties because Swing doesn't update its internal strings automatically
    // when default Locale is updated (see bug http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4884480)
    updateSwingResourceBundle("com.sun.swing.internal.plaf.metal.resources.metal");
    updateSwingResourceBundle("com.sun.swing.internal.plaf.basic.resources.basic");
    if (UIManager.getLookAndFeel().getClass().getName().equals("com.sun.java.swing.plaf.gtk.GTKLookAndFeel")) {
      updateSwingResourceBundle("com.sun.java.swing.plaf.gtk.resources.gtk");
    } else if (UIManager.getLookAndFeel().getClass().getName().equals("com.sun.java.swing.plaf.motif.MotifLookAndFeel")) {
      updateSwingResourceBundle("com.sun.java.swing.plaf.motif.resources.motif");
    }
  }

  /**
   * Updates a Swing resource bundle in use from the current Locale.
   */
  private static void updateSwingResourceBundle(String swingResource) {
    ResourceBundle resource;
    try {
      resource = ResourceBundle.getBundle(swingResource);
    } catch (MissingResourceException ex) {
      resource = ResourceBundle.getBundle(swingResource, Locale.ENGLISH);
    }
    // Update UIManager properties
    for (Enumeration<?> it = resource.getKeys(); it.hasMoreElements(); ) {
      String property = (String)it.nextElement();
      UIManager.put(property, resource.getString(property));
    }
  }
 
  /**
   * Returns a localized text for menus items and labels depending on the system.
   */
  public static String getLocalizedLabelText(UserPreferences preferences,
                                             Class<?> resourceClass,
                                             String   resourceKey,
                                             Object ... resourceParameters) {
    String localizedString = preferences.getLocalizedString(resourceClass, resourceKey, resourceParameters);
    // Under Mac OS X, remove bracketed upper case roman letter used in oriental languages to indicate mnemonic
    String language = Locale.getDefault().getLanguage();
    if (OperatingSystem.isMacOSX()
        && (language.equals(Locale.CHINESE.getLanguage())
            || language.equals(Locale.JAPANESE.getLanguage())
            || language.equals(Locale.KOREAN.getLanguage()))) {
      int openingBracketIndex = localizedString.indexOf('(');
      if (openingBracketIndex != -1) {
        int closingBracketIndex = localizedString.indexOf(')');
        if (openingBracketIndex == closingBracketIndex - 2) {
          char c = localizedString.charAt(openingBracketIndex + 1);
          if (c >= 'A' && c <= 'Z') {
            localizedString = localizedString.substring(0, openingBracketIndex)
                + localizedString.substring(closingBracketIndex + 1);
          }
        }
      }
    }
    return localizedString;
  }
 
  /**
   * Adds focus and mouse listeners to the given <code>textComponent</code> that will
   * select all its text when it gains focus by transfer.
   */
  public static void addAutoSelectionOnFocusGain(final JTextComponent textComponent) {
    // A focus and mouse listener able to select text field characters
    // when it gains focus after a focus transfer
    class SelectionOnFocusManager extends MouseAdapter implements FocusListener {
      private boolean mousePressedInTextField = false;
      private int selectionStartBeforeFocusLost = -1;
      private int selectionEndBeforeFocusLost = -1;

      @Override
      public void mousePressed(MouseEvent ev) {
        this.mousePressedInTextField = true;
        this.selectionStartBeforeFocusLost = -1;
      }
     
      public void focusLost(FocusEvent ev) {
        if (ev.getOppositeComponent() == null
            || SwingUtilities.getWindowAncestor(ev.getOppositeComponent())
                != SwingUtilities.getWindowAncestor(textComponent)) {
          // Keep selection indices when focus on text field is transfered
          // to an other window
          this.selectionStartBeforeFocusLost = textComponent.getSelectionStart();
          this.selectionEndBeforeFocusLost = textComponent.getSelectionEnd();
        } else {
          this.selectionStartBeforeFocusLost = -1;
        }
      }

      public void focusGained(FocusEvent ev) {
        if (this.selectionStartBeforeFocusLost != -1) {
          EventQueue.invokeLater(new Runnable() {
              public void run() {
                // Reselect the same characters in text field
                textComponent.setSelectionStart(selectionStartBeforeFocusLost);
                textComponent.setSelectionEnd(selectionEndBeforeFocusLost);
              }
            });
        } else if (!this.mousePressedInTextField
                   && ev.getOppositeComponent() != null
                   && SwingUtilities.getWindowAncestor(ev.getOppositeComponent())
                       == SwingUtilities.getWindowAncestor(textComponent)) {
          EventQueue.invokeLater(new Runnable() {
              public void run() {
                // Select all characters when text field got the focus because of a transfer
                textComponent.selectAll();
              }
            });
        }
        this.mousePressedInTextField = false;
      }
    };
   
    SelectionOnFocusManager selectionOnFocusManager = new SelectionOnFocusManager();
    textComponent.addFocusListener(selectionOnFocusManager);
    textComponent.addMouseListener(selectionOnFocusManager);
  }
 
  /**
   * Forces radio buttons to be deselected even if they belong to a button group.
   */
  public static void deselectAllRadioButtons(JRadioButton ... radioButtons) {
    for (JRadioButton radioButton : radioButtons) {
      ButtonGroup group = ((JToggleButton.ToggleButtonModel)radioButton.getModel()).getGroup();
      group.remove(radioButton);
      radioButton.setSelected(false);
      group.add(radioButton);
    }   
  }
 
  /**
   * Displays <code>messageComponent</code> in a modal dialog box, giving focus to one of its components.
   */
  public static int showConfirmDialog(JComponent parentComponent,
                                      JComponent messageComponent,
                                      String title,
                                      final JComponent focusedComponent) {
    JOptionPane optionPane = new JOptionPane(messageComponent,
        JOptionPane.PLAIN_MESSAGE, JOptionPane.OK_CANCEL_OPTION);
    parentComponent = SwingUtilities.getRootPane(parentComponent);
    if (parentComponent != null) {
      optionPane.setComponentOrientation(parentComponent.getComponentOrientation());
    }
    final JDialog dialog = optionPane.createDialog(parentComponent, title);
    if (focusedComponent != null) {
      // Add a listener that transfer focus to focusedComponent when dialog is shown
      dialog.addComponentListener(new ComponentAdapter() {
          @Override
          public void componentShown(ComponentEvent ev) {
            focusedComponent.requestFocusInWindow();
            dialog.removeComponentListener(this);
          }
        });
    }
    dialog.setVisible(true);
   
    dialog.dispose();
    Object value = optionPane.getValue();
    if (value instanceof Integer) {
      return (Integer)value;
    } else {
      return JOptionPane.CLOSED_OPTION;
    }
  }

  /**
   * Displays <code>messageComponent</code> in a modal dialog box, giving focus to one of its components.
   */
  public static void showMessageDialog(JComponent parentComponent,
                                       JComponent messageComponent,
                                       String title,
                                       int messageType,
                                       final JComponent focusedComponent) {
    JOptionPane optionPane = new JOptionPane(messageComponent, messageType, JOptionPane.DEFAULT_OPTION);
    parentComponent = SwingUtilities.getRootPane(parentComponent);
    if (parentComponent != null) {
      optionPane.setComponentOrientation(parentComponent.getComponentOrientation());
    }
    final JDialog dialog = optionPane.createDialog(parentComponent, title);
    if (focusedComponent != null) {
      // Add a listener that transfer focus to focusedComponent when dialog is shown
      dialog.addComponentListener(new ComponentAdapter() {
          @Override
          public void componentShown(ComponentEvent ev) {
            focusedComponent.requestFocusInWindow();
            dialog.removeComponentListener(this);
          }
        });
    }
    dialog.setVisible(true);   
    dialog.dispose();
  }

  private static Map<TextureImage, BufferedImage> patternImages;
 
  /**
   * Returns the image matching a given pattern.
   */
  public static BufferedImage getPatternImage(TextureImage pattern,
                                              Color backgroundColor,
                                              Color foregroundColor) {
    if (patternImages == null) {
      patternImages = new HashMap<TextureImage, BufferedImage>();
    }
    BufferedImage image = new BufferedImage(
        (int)pattern.getWidth(), (int)pattern.getHeight(), BufferedImage.TYPE_INT_RGB);
    Graphics2D imageGraphics = (Graphics2D)image.getGraphics();
    imageGraphics.setColor(backgroundColor);
    imageGraphics.fillRect(0, 0, image.getWidth(), image.getHeight());
    // Get pattern image from cache
    BufferedImage patternImage = patternImages.get(pattern);
    if (patternImage == null) {
      try {
        InputStream imageInput = pattern.getImage().openStream();
        patternImage = ImageIO.read(imageInput);
        imageInput.close();
        patternImages.put(pattern, patternImage);
      } catch (IOException ex) {
        throw new IllegalArgumentException("Can't read pattern image " + pattern.getName());
      }
    }
    // Draw the pattern image with foreground color
    final int foregroundColorRgb = foregroundColor.getRGB() & 0xFFFFFF;
    imageGraphics.drawImage(Toolkit.getDefaultToolkit().createImage(
        new FilteredImageSource(patternImage.getSource(),
        new RGBImageFilter() {
          {
            this.canFilterIndexColorModel = true;
          }

          @Override
          public int filterRGB(int x, int y, int rgba) {
            // Always use foreground color and alpha
            return (rgba & 0xFF000000) | foregroundColorRgb;
          }
        })), 0, 0, null);
    imageGraphics.dispose();
    return image;
  }
 
  /**
   * Returns the border of a component where a user may drop objects.
   */
  public static Border getDropableComponentBorder() {
    Border border = null;
    if (OperatingSystem.isMacOSXLeopardOrSuperior()) {
      border = UIManager.getBorder("InsetBorder.aquaVariant");
    }
    if (border == null) {
      border = BorderFactory.createLoweredBevelBorder();
    }
    return border;
  }
 
  /**
   * Displays the image referenced by <code>imageUrl</code> in an AWT window
   * disposed once an other AWT frame is created.
   * If the <code>imageUrl</code> is incorrect, nothing happens.
   */
  public static void showSplashScreenWindow(URL imageUrl) {
    try {
      final BufferedImage image = ImageIO.read(imageUrl);
      final Window splashScreenWindow = new Window(new Frame()) {
          @Override
          public void paint(Graphics g) {
            g.drawImage(image, 0, 0, this);
          }
        };
       
      splashScreenWindow.setSize(image.getWidth(), image.getHeight());
      splashScreenWindow.setLocationRelativeTo(null);
      splashScreenWindow.setVisible(true);
         
      Executors.newSingleThreadExecutor().execute(new Runnable() {
          public void run() {
            try {
              while (splashScreenWindow.isVisible()) {
                Thread.sleep(500);
                // If an other frame is created, dispose splash window
                EventQueue.invokeLater(new Runnable() {
                    public void run() {
                      if (Frame.getFrames().length > 1) {
                        splashScreenWindow.dispose();
                      }
                    }
                  });
              }
            } catch (InterruptedException ex) {
              EventQueue.invokeLater(new Runnable() {
                public void run() {
                  splashScreenWindow.dispose();
                }
              });
            };
          }
        });
    } catch (IOException ex) {
      // Ignore splash screen
    }
  }
 
  /**
   * Returns a new panel with a border and the given <code>title</code>
   */
  public static JPanel createTitledPanel(String title) {
    JPanel titledPanel = new JPanel(new GridBagLayout());
    Border panelBorder = BorderFactory.createTitledBorder(title);
    // For systems different from Mac OS X 10.5, add an empty border
    if (!OperatingSystem.isMacOSXLeopardOrSuperior()) {
      panelBorder = BorderFactory.createCompoundBorder(
          panelBorder, BorderFactory.createEmptyBorder(0, 2, 2, 2));
    }   
    titledPanel.setBorder(panelBorder);   
    return titledPanel;
  }

  /**
   * Adds a listener that will update the given popup menu to hide disabled menu items.
   */
  public static void hideDisabledMenuItems(JPopupMenu popupMenu) {
    popupMenu.addPopupMenuListener(new MenuItemsVisibilityListener());
  }
 
  /**
   * A popup menu listener that displays only enabled menu items.
   */
  private static class MenuItemsVisibilityListener implements PopupMenuListener {
    public void popupMenuWillBecomeVisible(PopupMenuEvent ev) {       
      JPopupMenu popupMenu = (JPopupMenu)ev.getSource();
      // Make visible only enabled menu items  
      for (int i = 0; i < popupMenu.getComponentCount(); i++) {
        Component component = popupMenu.getComponent(i);
        if (component instanceof JMenu) {
          component.setVisible(containsEnabledItems((JMenu)component));
        } else if (component instanceof JMenuItem) {
          component.setVisible(component.isEnabled());
        }
      }
      hideUselessSeparators(popupMenu);
      // Ensure at least one item is visible
      boolean allItemsInvisible = true;
      for (int i = 0; i < popupMenu.getComponentCount(); i++) {
        if (popupMenu.getComponent(i).isVisible()) {
          allItemsInvisible = false;
          break;
        }
      } 
      if (allItemsInvisible) {
        popupMenu.getComponent(0).setVisible(true);
      }
    }

    /**
     * Makes useless separators invisible.
     */
    private void hideUselessSeparators(JPopupMenu popupMenu) {
      boolean allMenuItemsInvisible = true;
      int lastVisibleSeparatorIndex = -1;
      for (int i = 0; i < popupMenu.getComponentCount(); i++) {
        Component component = popupMenu.getComponent(i);
        if (allMenuItemsInvisible && (component instanceof JMenuItem)) {
          if (component.isVisible()) {
            allMenuItemsInvisible = false;
          }
        } else if (component instanceof JSeparator) {         
          component.setVisible(!allMenuItemsInvisible);
          if (!allMenuItemsInvisible) {
            lastVisibleSeparatorIndex = i;
          }
          allMenuItemsInvisible = true;
        }
      } 
      if (lastVisibleSeparatorIndex != -1 && allMenuItemsInvisible) {
        // Check if last separator is the first visible component
        boolean allComponentsBeforeLastVisibleSeparatorInvisible = true;
        for (int i = lastVisibleSeparatorIndex - 1; i >= 0; i--) {
          if (popupMenu.getComponent(i).isVisible()) {
            allComponentsBeforeLastVisibleSeparatorInvisible = false;
            break;
          }
        }
        boolean allComponentsAfterLastVisibleSeparatorInvisible = true;
        for (int i = lastVisibleSeparatorIndex; i < popupMenu.getComponentCount(); i++) {
          if (popupMenu.getComponent(i).isVisible()) {
            allComponentsBeforeLastVisibleSeparatorInvisible = false;
            break;
          }
        }
       
        popupMenu.getComponent(lastVisibleSeparatorIndex).setVisible(
            !allComponentsBeforeLastVisibleSeparatorInvisible && !allComponentsAfterLastVisibleSeparatorInvisible);
      }
    }

    /**
     * Returns <code>true</code> if the given <code>menu</code> contains
     * at least one enabled menu item.
     */
    private boolean containsEnabledItems(JMenu menu) {
      boolean menuContainsEnabledItems = false;
      for (int i = 0; i < menu.getMenuComponentCount() && !menuContainsEnabledItems; i++) {
        Component component = menu.getMenuComponent(i);
        if (component instanceof JMenu) {
          menuContainsEnabledItems = containsEnabledItems((JMenu)component);
        } else if (component instanceof JMenuItem) {
          menuContainsEnabledItems = component.isEnabled();
        }
      }
      return menuContainsEnabledItems;
    }

    public void popupMenuCanceled(PopupMenuEvent ev) {
    }

    public void popupMenuWillBecomeInvisible(PopupMenuEvent ev) {
    }
  }
}
TOP

Related Classes of com.eteks.sweethome3d.swing.SwingTools$MenuItemsVisibilityListener

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.