All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.jidesoft.swing.PopupWindow Maven / Gradle / Ivy

There is a newer version: 3.6.18
Show newest version
/*
 * @(#)PopupWindow.java
 *
 * Copyright 2002 - 2003 JIDE Software. All rights reserved.
 */
package com.jidesoft.swing;

import com.jidesoft.utils.PortingUtils;

import javax.swing.*;
import javax.swing.event.EventListenerList;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import java.awt.*;
import java.awt.event.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.List;
import java.util.Vector;

/**
 * PopupWindow class
 * 

* You can add another JPopupMenu or JComboxBox in this popup. *

* This class is copied from http://forum.java.sun.com/thread.jsp?forum=57&thread=230866 with some minor modifications. */ public class PopupWindow { /** * A list of event listeners for this component. */ protected EventListenerList listenerList = new EventListenerList(); private JWindow _delegate; private Container _container; private List _grabbed = new Vector(); private List _excluded = new Vector(); private WindowListener _windowListener; private ComponentListener _componentListener; private ContainerListener _containerListener; private MouseListener _mouseListener; private Component _component; // JDK 1.3 Porting Hint. // Use AWTEventListener instead // private AWTEventListener _keyEventDispatcher; private KeyEventDispatcher _keyEventDispatcher; private Component _parent; public PopupWindow(Container container) { _container = container; createDelegate(); createListeners(); } private void createDelegate() { Window window = getWindow(); if (window != null) { _delegate = new JWindow(window); } } public void add(Component component) { _component = component; _component.addPropertyChangeListener("preferredSize", new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { if (_delegate != null) { _delegate.pack(); } } }); if (_delegate != null) { _delegate.getContentPane().add(component); _delegate.pack(); // workaround for a problem. JWindow somehow offset the height by 1 // See http://developer.java.sun.com/developer/bugParade/bugs/4511106.html // looks like call pack again solve the problem. _delegate.pack(); // mDelegate.setSize(mDelegate.getSize().width, mDelegate.getSize().height + 1); } } public void show(Component relative, int x, int y) { _parent = relative; if (_delegate == null) { createDelegate(); if (_delegate == null) return; add(_component); } Point p = new Point(x, y); SwingUtilities.convertPointToScreen(p, relative); Rectangle screenSize = PortingUtils.getScreenBounds(relative); Dimension size = _component.getPreferredSize(); int left = p.x + size.width; int bottom = p.y + size.height; if (p.x < screenSize.x) { p.x = screenSize.x; } if (left > screenSize.width) { p.x = screenSize.width - size.width; } if (p.y < screenSize.y) { p.y = screenSize.y; } if (bottom > screenSize.height) { p.y = screenSize.height - size.height; } // Point location = relative.getLocationOnScreen(); _delegate.setLocation(p.x, p.y); _delegate.setSize(_component.getPreferredSize()); firePopupMenuWillBecomeVisible(); _delegate.setVisible(true); grabContainers(); // set popup window focus and register esc key // _delegate.toFront(); // _delegate.requestFocus(); // JDK 1.3 Porting Hint // Replace by AWTEventListener // Following Block is for JDK 1.3 // _keyEventDispatcher = new AWTEventListener() { // public void eventDispatched(AWTEvent e) { // if (e instanceof KeyEvent) { // if (((KeyEvent) e).getKeyCode() == KeyEvent.VK_ESCAPE) { // hide(); // } // } // } // }; // Toolkit.getDefaultToolkit().addAWTEventListener(_keyEventDispatcher, AWTEvent.KEY_EVENT_MASK); // Following Block is for JDK 1.4 _keyEventDispatcher = new KeyEventDispatcher() { public boolean dispatchKeyEvent(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { hide(); return true; } return false; } }; DefaultFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(_keyEventDispatcher); } public void hide() { if (_parent != null) { _parent.requestFocus(); } firePopupMenuWillBecomeInvisible(); if (_delegate != null) { _delegate.setVisible(false); } if (_keyEventDispatcher != null) { // JDK 1.3 Porting Hint // Replace by AWTEventListener // Toolkit.getDefaultToolkit().removeAWTEventListener(_keyEventDispatcher); DefaultFocusManager.getCurrentKeyboardFocusManager().removeKeyEventDispatcher(_keyEventDispatcher); _keyEventDispatcher = null; } releaseContainers(); disposeDelegate(); } private void createListeners() { _windowListener = new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { hide(); } @Override public void windowClosed(WindowEvent e) { hide(); } @Override public void windowIconified(WindowEvent e) { hide(); } }; _componentListener = new ComponentListener() { public void componentResized(ComponentEvent e) { hide(); } public void componentMoved(ComponentEvent e) { hide(); } public void componentShown(ComponentEvent e) { hide(); } public void componentHidden(ComponentEvent e) { hide(); } }; _containerListener = new ContainerListener() { public void componentAdded(ContainerEvent e) { hide(); } public void componentRemoved(ContainerEvent e) { hide(); } }; _mouseListener = new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { hide(); } }; } private void disposeDelegate() { if (_delegate != null) { _delegate.dispose(); _delegate = null; } } private Window getWindow() { Container c = _container; if (c == null) { return null; } while (!(c instanceof Window) && c.getParent() != null) c = c.getParent(); if (c instanceof Window) return (Window) c; return null; } private void grabContainers() { Container c = _container; while (!(c instanceof Window) && c.getParent() != null) c = c.getParent(); grabContainer(c); } private void grabContainer(Container c) { if (c instanceof Window) { ((Window) c).addWindowListener(_windowListener); c.addComponentListener(_componentListener); _grabbed.add(c); } synchronized (c.getTreeLock()) { int ncomponents = c.getComponentCount(); Component[] component = c.getComponents(); for (int i = 0; i < ncomponents; i++) { Component comp = component[i]; if (!comp.isVisible()) continue; if (isExcludedComponent(comp)) { continue; } // // TODO: this is not the right way to do things. Leave it for future enhancement to popup panel // // don't hide popup when button of abstract combobox is pressed so that that button can toggle visibility of popup panel // if(comp instanceof AbstractButton && comp.getParent() instanceof AbstractComboBox) { // if(_delegate.isAncestorOf(((AbstractComboBox) comp.getParent()).getPopupPanel())) { // continue; // } // } comp.addMouseListener(_mouseListener); _grabbed.add(comp); if (comp instanceof Container) { Container cont = (Container) comp; if (cont instanceof JLayeredPane) { cont.addContainerListener(_containerListener); } grabContainer(cont); } } } } void releaseContainers() { for (Object o : _grabbed) { Component c = (Component) o; if (c instanceof Window) { ((Window) c).removeWindowListener(_windowListener); c.removeComponentListener(_componentListener); } else { c.removeMouseListener(_mouseListener); } if (c instanceof Container) { if (c instanceof JLayeredPane) { ((Container) c).removeContainerListener(_containerListener); } } } _grabbed.clear(); } /** * Gets the visibility of this popup. * * @return true if popup is visible */ public boolean isVisible() { return _delegate != null ? _delegate.isVisible() : false; } /** * Adds a PopupMenu listener which will listen to notification messages from the popup portion of the * combo box. *

* For all standard look and feels shipped with Java 2, the popup list portion of combo box is implemented as a * JPopupMenu. A custom look and feel may not implement it this way and will therefore not receive the * notification. * * @param l the PopupMenuListener to add * @since 1.4 */ public void addPopupMenuListener(PopupMenuListener l) { listenerList.add(PopupMenuListener.class, l); } /** * Removes a PopupMenuListener. * * @param l the PopupMenuListener to remove * @see #addPopupMenuListener * @since 1.4 */ public void removePopupMenuListener(PopupMenuListener l) { listenerList.remove(PopupMenuListener.class, l); } /** * Returns an array of all the PopupMenuListeners added to this JComboBox with addPopupMenuListener(). * * @return all of the PopupMenuListeners added or an empty array if no listeners have been added * * @since 1.4 */ public PopupMenuListener[] getPopupMenuListeners() { return listenerList.getListeners(PopupMenuListener.class); } /** * Notifies PopupMenuListeners that the popup portion of the combo box will become visible. *

* This method is public but should not be called by anything other than the UI delegate. * * @see #addPopupMenuListener * @since 1.4 */ public void firePopupMenuWillBecomeVisible() { Object[] listeners = listenerList.getListenerList(); PopupMenuEvent e = null; for (int i = listeners.length - 2; i >= 0; i -= 2) { if (listeners[i] == PopupMenuListener.class) { if (e == null) e = new PopupMenuEvent(this); ((PopupMenuListener) listeners[i + 1]).popupMenuWillBecomeVisible(e); } } } /** * Notifies PopupMenuListeners that the popup portion of the combo box has become invisible. *

* This method is public but should not be called by anything other than the UI delegate. * * @see #addPopupMenuListener * @since 1.4 */ public void firePopupMenuWillBecomeInvisible() { Object[] listeners = listenerList.getListenerList(); PopupMenuEvent e = null; for (int i = listeners.length - 2; i >= 0; i -= 2) { if (listeners[i] == PopupMenuListener.class) { if (e == null) e = new PopupMenuEvent(this); ((PopupMenuListener) listeners[i + 1]).popupMenuWillBecomeInvisible(e); } } } /** * Notifies PopupMenuListeners that the popup portion of the combo box has been canceled. *

* This method is public but should not be called by anything other than the UI delegate. * * @see #addPopupMenuListener * @since 1.4 */ public void firePopupMenuCanceled() { Object[] listeners = listenerList.getListenerList(); PopupMenuEvent e = null; for (int i = listeners.length - 2; i >= 0; i -= 2) { if (listeners[i] == PopupMenuListener.class) { if (e == null) e = new PopupMenuEvent(this); ((PopupMenuListener) listeners[i + 1]).popupMenuCanceled(e); } } } /** * PopupWindow will add necessary listeners to some components so that mouse click etc can hide the popup window. * However in certain case, you might not want this. * * @param comp component which will not hide popup when it is clicked. */ public void addAsExcludedComponents(Component comp) { if (_excluded.contains(comp)) { return; } _excluded.add(comp); } public void removeFromExcludedComponents(Component comp) { if (!_excluded.contains(comp)) { return; } _excluded.remove(comp); } public boolean isExcludedComponent(Component comp) { return _excluded.contains(comp); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy