001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: /**
018: * @author Anton Avtamonov
019: * @version $Revision$
020: */package javax.swing;
021:
022: import java.awt.BorderLayout;
023: import java.awt.Component;
024: import java.awt.Container;
025: import java.awt.Dimension;
026: import java.awt.Point;
027: import java.awt.Rectangle;
028: import java.awt.Window;
029: import java.util.HashMap;
030: import java.util.HashSet;
031: import java.util.Iterator;
032: import java.util.Map;
033: import java.util.Set;
034:
035: import org.apache.harmony.x.swing.internal.nls.Messages;
036:
037: public class PopupFactory {
038: private static class ReleasedPopupStorage {
039: private static final int STORAGE_CAPACITY = 5;
040:
041: private Map popups = new HashMap();
042:
043: public HWPopup retrieve(final Window owner) {
044: Set popupSet = (Set) popups.get(owner);
045: if (popupSet == null) {
046: return null;
047: }
048: Iterator it = popupSet.iterator();
049: HWPopup result = (HWPopup) it.next();
050: it.remove();
051: if (popupSet.isEmpty()) {
052: popups.remove(owner);
053: }
054:
055: return result;
056: }
057:
058: public boolean store(final HWPopup popup) {
059: Container owner = popup.getPopupOwner();
060: if (owner == null) {
061: return false;
062: }
063: Set popupSet = (Set) popups.get(owner);
064: if (popupSet == null) {
065: popupSet = new HashSet();
066: popups.put(owner, popupSet);
067: }
068: if (popupSet.size() < STORAGE_CAPACITY) {
069: popupSet.add(popup);
070: return true;
071: }
072:
073: return false;
074: }
075:
076: public void remove(final HWPopup popup) {
077: Container owner = popup.getPopupOwner();
078: Set popupSet = (Set) popups.get(owner);
079: if (popupSet != null) {
080: popupSet.remove(popup);
081: if (popupSet.isEmpty()) {
082: popups.remove(owner);
083: }
084: }
085: }
086: }
087:
088: private class HWPopup extends Popup {
089: private class FactoryPopupWindow extends PopupWindow {
090: public FactoryPopupWindow(final Window owner) {
091: super (owner);
092: }
093:
094: public void hide() {
095: PopupFactory.this .releasePopup(HWPopup.this );
096: super .hide();
097: }
098:
099: public void dispose() {
100: PopupFactory.this .dropPopup(HWPopup.this );
101: super .dispose();
102: }
103: }
104:
105: public HWPopup(final Window owner, final Component content,
106: final int x, final int y) {
107: popupWindow = new FactoryPopupWindow(owner);
108: reinit(content, x, y);
109: }
110:
111: public void hide() {
112: popupWindow.hide();
113: }
114:
115: public void reinit(final Component content, final int x,
116: final int y) {
117: popupWindow.init(content, x, y);
118: }
119:
120: public void dispose() {
121: popupWindow.dispose();
122: }
123:
124: public Container getPopupOwner() {
125: return popupWindow.getOwner();
126: }
127: }
128:
129: private class LWPopup extends Popup {
130: private final JPanel contentPane;
131: private final JLayeredPane lp;
132:
133: public LWPopup(final Window owner, final Component content,
134: final int x, final int y) {
135: contentPane = new JPanel(new BorderLayout());
136: lp = getLayeredPane(owner);
137:
138: contentPane.add(content);
139: contentPane.setSize(content.getPreferredSize());
140: Point location = new Point(x, y);
141: SwingUtilities.convertPointFromScreen(location, lp);
142: contentPane.setLocation(location);
143: }
144:
145: public void show() {
146: lp.add(contentPane, JLayeredPane.POPUP_LAYER);
147: }
148:
149: public void hide() {
150: lp.remove(contentPane);
151: }
152: }
153:
154: private static PopupFactory instance = new PopupFactory();
155: private ReleasedPopupStorage popupStorage = new ReleasedPopupStorage();
156: private boolean lwPopupsEnabled;
157:
158: public static void setSharedInstance(final PopupFactory factory) {
159: if (factory == null) {
160: throw new IllegalArgumentException(Messages
161: .getString("swing.53")); //$NON-NLS-1$
162: }
163:
164: instance = factory;
165: }
166:
167: public static PopupFactory getSharedInstance() {
168: return instance;
169: }
170:
171: public Popup getPopup(final Component owner,
172: final Component content, final int x, final int y)
173: throws IllegalArgumentException {
174: if (content == null) {
175: throw new IllegalArgumentException(Messages
176: .getString("swing.52")); //$NON-NLS-1$
177: }
178:
179: Window ownerWindow = owner instanceof Window ? (Window) owner
180: : SwingUtilities.getWindowAncestor(owner);
181: if (ownerWindow == null) {
182: ownerWindow = JFrame.getSharedOwner();
183: }
184:
185: if (lwPopupsEnabled) {
186: JLayeredPane lp = getLayeredPane(ownerWindow);
187: if (lp != null) {
188: Point lpLocation = lp.getLocation();
189: SwingUtilities.convertPointToScreen(lpLocation, lp);
190: Rectangle surfaceBounds = new Rectangle(lpLocation, lp
191: .getSize());
192: Dimension prefSize = content.getPreferredSize();
193: Rectangle contentBounds = new Rectangle(x, y,
194: prefSize.width, prefSize.height);
195: if (surfaceBounds.contains(contentBounds)) {
196: return new LWPopup(ownerWindow, content, x, y);
197: }
198: }
199: }
200:
201: HWPopup result = popupStorage.retrieve(ownerWindow);
202: if (result != null) {
203: result.reinit(content, x, y);
204: return result;
205: }
206:
207: return new HWPopup(ownerWindow, content, x, y);
208: }
209:
210: void setLWPopupsEnabled(final boolean enabled) {
211: lwPopupsEnabled = enabled;
212: }
213:
214: private void releasePopup(final HWPopup popup) {
215: if (popupStorage.store(popup)) {
216: return;
217: }
218:
219: popup.dispose();
220: }
221:
222: private void dropPopup(final HWPopup popup) {
223: popupStorage.remove(popup);
224: }
225:
226: private static JLayeredPane getLayeredPane(final Window w) {
227: if (w instanceof JFrame) {
228: return ((JFrame) w).getLayeredPane();
229: } else if (w instanceof JDialog) {
230: return ((JDialog) w).getLayeredPane();
231: }
232:
233: return null;
234: }
235: }
|