Package javax.swing

Source Code of javax.swing.JPopupMenu$PopupMouseEventPreprocessor

/*
*  Licensed to the Apache Software Foundation (ASF) under one or more
*  contributor license agreements.  See the NOTICE file distributed with
*  this work for additional information regarding copyright ownership.
*  The ASF licenses this file to You 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.
*/
/**
* @author Alexander T. Simbirtsev
* @version $Revision$
*/
package javax.swing;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Window;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.HashSet;
import java.util.Iterator;

import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import javax.swing.plaf.PopupMenuUI;

import org.apache.harmony.awt.ComponentInternals;
import org.apache.harmony.awt.MouseEventPreprocessor;
import org.apache.harmony.x.swing.StringConstants;
import org.apache.harmony.x.swing.Utilities;

import org.apache.harmony.x.swing.internal.nls.Messages;


public class JPopupMenu extends JComponent implements Accessible, MenuElement {

    public static class Separator extends JSeparator {
        private final static String UI_CLASS_ID = "PopupMenuSeparatorUI";

        public String getUIClassID() {
            return UI_CLASS_ID;
        }
    }

    // TODO implement accessibility
    protected class AccessibleJPopupMenu extends AccessibleJComponent implements PropertyChangeListener {
        public AccessibleRole getAccessibleRole() {
            return AccessibleRole.POPUP_MENU;
        }

        public void propertyChange(final PropertyChangeEvent event) {
            throw new UnsupportedOperationException(Messages.getString("swing.27")); //$NON-NLS-1$
        }
    }

    private static class PopupMouseEventPreprocessor implements MouseEventPreprocessor {
        private final HashSet openedPopups = new HashSet();

        public boolean preprocess(final MouseEvent event) {
            if (event.getID() != MouseEvent.MOUSE_PRESSED || openedPopups.isEmpty()) {
                return true;
            }

            boolean inside = false;
            final Iterator i = openedPopups.iterator();
            while (i.hasNext() && !inside) {
                final JPopupMenu popup = (JPopupMenu)i.next();
                Point localPoint = SwingUtilities.convertPoint(event.getComponent(), event.getPoint(), popup);
                inside = popup.contains(localPoint);

                final Component invoker = popup.getInvoker();
                if (invoker != null && Boolean.TRUE.equals(popup.getClientProperty(StringConstants.HIDE_ON_INVOKER_PRESSED_PROPERTY))) {
                    localPoint = SwingUtilities.convertPoint(event.getComponent(), event.getPoint(), invoker);
                    inside |= invoker.contains(localPoint);
                }
            }
            if (inside) {
                return true;
            }

            final MenuElement[] selectedPath = MenuSelectionManager.defaultManager().getSelectedPath();
            for (int j = 1; j < selectedPath.length; j++) {
                Component c = selectedPath[j].getComponent();
                if (c != null) {
                    Point localPoint = SwingUtilities.convertPoint(event.getComponent(), event.getPoint(), c);
                    inside = c.contains(localPoint);
                    if (inside) {
                        return true;
                    }
                }
            }
            MenuSelectionManager.defaultManager().clearSelectedPath();
            return true;
        }

        public void registerPopup(final JPopupMenu popup) {
            openedPopups.add(popup);
        }

        public void unregisterPopup(final JPopupMenu popup) {
            openedPopups.remove(popup);
        }
    }

    private static int numHWPopups;
    private static Runnable cancelGrabRunnable;

    private final static String UI_CLASS_ID = "PopupMenuUI";

    private static boolean defaultLightWeightPopupEnabled = true;
    private static final PopupMouseEventPreprocessor MOUSE_EVENTS_HANDLER = new PopupMouseEventPreprocessor();

    private SingleSelectionModel selectionModel = new DefaultSingleSelectionModel();
    private String label;
    private Component invoker;
    private boolean borderPainted = true;
    private boolean lightWeightPopupEnabled = getDefaultLightWeightPopupEnabled();
    private Popup popup;
    private final Point location = new Point();

    static {
        ComponentInternals.getComponentInternals().setMouseEventPreprocessor(MOUSE_EVENTS_HANDLER);
    }

    public JPopupMenu() {
        super.setVisible(false);
        updateUI();
    }

    public JPopupMenu(final String text) {
        label = text;
        super.setVisible(false);
        updateUI();
    }

    public AccessibleContext getAccessibleContext() {
        return (accessibleContext == null) ? (accessibleContext = new AccessibleJPopupMenu())
                : accessibleContext;
    }

    protected PropertyChangeListener createActionChangeListener(final JMenuItem item) {
        return (item != null) ? item.createActionPropertyChangeListener(item.getAction()) : null;
    }

    public void addPopupMenuListener(final PopupMenuListener listener) {
        listenerList.add(PopupMenuListener.class, listener);
    }

    public void removePopupMenuListener(final PopupMenuListener listener) {
        listenerList.remove(PopupMenuListener.class, listener);
    }

    public PopupMenuListener[] getPopupMenuListeners() {
        return (PopupMenuListener[])getListeners(PopupMenuListener.class);
    }

    protected void firePopupMenuCanceled() {
        final PopupMenuListener[] listeners = getPopupMenuListeners();
        if (listeners.length == 0){
            return;
        }

        final PopupMenuEvent event = new PopupMenuEvent(this);
        for (int i = 0; i < listeners.length; i++) {
            listeners[i].popupMenuCanceled(event);
        }
    }

    protected void firePopupMenuWillBecomeInvisible() {
        final PopupMenuListener[] listeners = getPopupMenuListeners();
        if (listeners.length == 0){
            return;
        }

        final PopupMenuEvent event = new PopupMenuEvent(this);
        for (int i = 0; i < listeners.length; i++) {
            listeners[i].popupMenuWillBecomeInvisible(event);
        }
    }

    protected void firePopupMenuWillBecomeVisible() {
        final PopupMenuListener[] listeners = getPopupMenuListeners();
        if (listeners.length == 0){
            return;
        }

        final PopupMenuEvent event = new PopupMenuEvent(this);
        for (int i = 0; i < listeners.length; i++) {
            listeners[i].popupMenuWillBecomeVisible(event);
        }
    }

    public JMenuItem add(final Action action) {
        final JMenuItem result = add(createActionComponent(action));
        result.setAction(action);
        return result;
    }

    public JMenuItem add(final String text) {
        return add(new JMenuItem(text));
    }

    public JMenuItem add(final JMenuItem item) {
        return (JMenuItem)super.add(item);
    }

    public void addSeparator() {
        super.add(new JPopupMenu.Separator());
    }

    public void insert(final Component c, final int i) {
        if (i < 0) {
            throw new IllegalArgumentException(Messages.getString("swing.21")); //$NON-NLS-1$
        }
        if (i <= getComponentCount()) {
            super.add(c, i);
        }
    }

    public void insert(final Action action, final int i) {
        if (i < 0) {
            throw new IllegalArgumentException(Messages.getString("swing.21")); //$NON-NLS-1$
        }
        insert(createActionComponent(action), i < getComponentCount() ? i : getComponentCount());
    }

    public void remove(final int i) {
        if (i < 0) {
            throw new IllegalArgumentException(Messages.getString("swing.21")); //$NON-NLS-1$
        }
        if (i >= getComponentCount()) {
            throw new IllegalArgumentException(Messages.getString("swing.22")); //$NON-NLS-1$
        }

        super.remove(i);
    }

    /**
     * @deprecated
     */
    public Component getComponentAtIndex(final int i) {
        return super.getComponent(i);
    }

    public int getComponentIndex(final Component c) {
        for (int i = 0; i < getComponentCount(); i++) {
            if (getComponent(i) == c) {
                return i;
            }
        }
        return -1;
    }

    public MenuElement[] getSubElements() {
        return Utilities.getSubElements(this);
    }

    protected JMenuItem createActionComponent(final Action action) {
        return JMenuItem.createJMenuItem(action);
    }

    public static boolean getDefaultLightWeightPopupEnabled() {
        return defaultLightWeightPopupEnabled;
    }

    public static void setDefaultLightWeightPopupEnabled(final boolean lightWeightPopupEnabled) {
        JPopupMenu.defaultLightWeightPopupEnabled = lightWeightPopupEnabled;
    }

    public boolean isLightWeightPopupEnabled() {
        return lightWeightPopupEnabled;
    }

    public void setLightWeightPopupEnabled(final boolean lightWeightPopupEnabled) {
        this.lightWeightPopupEnabled = lightWeightPopupEnabled;
    }

    public void setInvoker(final Component invoker) {
        this.invoker = invoker;
    }

    public Component getInvoker() {
        return invoker;
    }

    public Component getComponent() {
        return this;
    }

    public void setLabel(final String label) {
        String oldValue = this.label;
        this.label = label;
        firePropertyChange(StringConstants.LABEL_PROPERTY_CHANGED, oldValue, label);
    }

    public String getLabel() {
        return label;
    }

    public Insets getMargin() {
        return new Insets(0, 0, 0, 0);
    }

    public void setBorderPainted(final boolean painted) {
        borderPainted = painted;
    }

    public boolean isBorderPainted() {
        return borderPainted;
    }

    protected void paintBorder(final Graphics g) {
        if (isBorderPainted()) {
            super.paintBorder(g);
        }
    }

    public boolean isPopupTrigger(final MouseEvent event) {
        return getUI().isPopupTrigger(event);
    }

    public void menuSelectionChanged(final boolean isIncluded) {
        if (isIncluded == isVisible()) {
            return;
        }

        if (isIncluded) {
            final Component c = getInvoker();
            if (c instanceof JMenu) {
                ((JMenu)c).setPopupMenuVisible(true);
            }
        } else {
            setVisible(false);
        }
    }

    public void pack() {
        final LayoutManager layout = getLayout();
        if (layout != null) {
            layout.layoutContainer(this);
        }
    }

    public void processKeyEvent(final KeyEvent event,
                                final MenuElement[] path,
                                final MenuSelectionManager msm) {
        // seems like it does no useful work
    }

    public void processMouseEvent(final MouseEvent event,
                                  final MenuElement[] path,
                                  final MenuSelectionManager msm) {
    }

    public void setSelected(final Component selection) {
        if (selectionModel != null) {
            selectionModel.setSelectedIndex(getComponentIndex(selection));
        }
    }

    public void setSelectionModel(final SingleSelectionModel model) {
        selectionModel = model;
    }

    public SingleSelectionModel getSelectionModel() {
        return selectionModel;
    }

    public void setVisible(final boolean visible) {
        boolean oldValue = isVisible();

        if (visible) {
            super.show();
            MOUSE_EVENTS_HANDLER.registerPopup(this);
        } else {
            super.hide();
            MOUSE_EVENTS_HANDLER.unregisterPopup(this);
        }

        if (getUI() != null) {
            if (visible) {
                popup = getUI().getPopup(this, location.x, location.y);
                firePopupMenuWillBecomeVisible();
                popup.show();
                startMouseGrab();
            } else if (popup != null){
                firePopupMenuWillBecomeInvisible();
                popup.hide();
                endMouseGrab();
            }
        }

        updateSelectionManager(visible);
        firePropertyChange(StringConstants.VISIBLE_PROPERTY_CHANGED, oldValue, visible);
    }

    public void show(final Component invoker, final int x, final int y) {
        setInvoker(invoker);
        Point p = new Point(x, y);
        if (invoker != null) {
            p = adjustPopupLocation(invoker, p);
        }
        setLocation(p.x, p.y);
        setVisible(true);
    }

    public void setLocation(final int x, final int y) {
        location.move(x, y);

        Window w = SwingUtilities.getWindowAncestor(this);
        if (w != null) {
            w.setLocation(x, y);
        }
    }

    public void setPopupSize(final int width, final int height) {
        setPreferredSize(new Dimension(width, height));
    }

    public void setPopupSize(final Dimension size) {
        setPreferredSize(size);
    }

    public void updateUI() {
        setUI(UIManager.getUI(this));
    }

    public void setUI(final PopupMenuUI ui) {
        super.setUI(ui);
    }

    public PopupMenuUI getUI() {
        return (PopupMenuUI)ui;
    }

    public String getUIClassID() {
        return UI_CLASS_ID;
    }

    private void updateSelectionManager(final boolean visible) {
        final MenuSelectionManager manager = MenuSelectionManager.defaultManager();
        final MenuElement[] oldPath = manager.getSelectedPath();
        MenuElement[] newPath = null;
        if (visible) {
            MenuElement selectableChild = Utilities.getFirstSelectableItem(getSubElements());
            if (Utilities.isEmptyArray(oldPath) && selectableChild != null) {
                newPath = new MenuElement[] {this, selectableChild};
            } else {
                newPath = Utilities.addToPath(oldPath, this);
            }
            manager.setSelectedPath(newPath);
        }
    }

    private void endMouseGrab() {
        if (numHWPopups > 0) {
            numHWPopups--;
        }
        if (numHWPopups == 0) {
            ComponentInternals.getComponentInternals().endMouseGrab();
        }
    }

    private void startMouseGrab() {
        if (numHWPopups == 0) {
            if (cancelGrabRunnable == null) {
                cancelGrabRunnable = new Runnable() {
                    public void run() {
                        if (isVisible()) {
                            MenuSelectionManager.defaultManager().clearSelectedPath();
                        }
                    }
                };
            }
            final Window window = SwingUtilities.getWindowAncestor(this);
            ComponentInternals.getComponentInternals().startMouseGrab(window, cancelGrabRunnable);
        }
        numHWPopups++;
    }

    private Point adjustPopupLocation(final Component invoker, Point p) {
        Point invokerScreenLocation = invoker.getLocationOnScreen();
        p.translate(invokerScreenLocation.x, invokerScreenLocation.y);
        Rectangle bounds = new Rectangle(invokerScreenLocation, invoker.getSize());
        boolean horizontal = (invoker instanceof JMenu) ? !((JMenu)(invoker)).isTopLevelMenu() : false;
        p = Utilities.adjustPopupLocation(p, getPreferredSize(),
                                          bounds, horizontal,
                                          invoker.getGraphicsConfiguration());
        return p;
    }

}
TOP

Related Classes of javax.swing.JPopupMenu$PopupMouseEventPreprocessor

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.