OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libjava/] [classpath/] [javax/] [swing/] [MenuSelectionManager.java] - Blame information for rev 14

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 jlechner
/* MenuSelectionManager.java --
2
   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
 
39
package javax.swing;
40
 
41
import java.awt.Component;
42
import java.awt.Dimension;
43
import java.awt.Point;
44
import java.awt.event.KeyEvent;
45
import java.awt.event.MouseEvent;
46
import java.util.ArrayList;
47
import java.util.Vector;
48
 
49
import javax.swing.event.ChangeEvent;
50
import javax.swing.event.ChangeListener;
51
import javax.swing.event.EventListenerList;
52
 
53
/**
54
 * This class manages current menu selectection. It provides
55
 * methods to clear and set current selected menu path.
56
 * It also fires StateChange event to its registered
57
 * listeners whenever selected path of the current menu hierarchy
58
 * changes.
59
 *
60
 */
61
public class MenuSelectionManager
62
{
63
  /** ChangeEvent fired when selected path changes*/
64
  protected ChangeEvent changeEvent = new ChangeEvent(this);
65
 
66
  /** List of listeners for this MenuSelectionManager */
67
  protected EventListenerList listenerList = new EventListenerList();
68
 
69
  /** Default manager for the current menu hierarchy*/
70
  private static final MenuSelectionManager manager = new MenuSelectionManager();
71
 
72
  /** Path to the currently selected menu */
73
  private Vector selectedPath = new Vector();
74
 
75
  /**
76
   * Fires StateChange event to registered listeners
77
   */
78
  protected void fireStateChanged()
79
  {
80
    ChangeListener[] listeners = getChangeListeners();
81
 
82
    for (int i = 0; i < listeners.length; i++)
83
      listeners[i].stateChanged(changeEvent);
84
  }
85
 
86
  /**
87
   * Adds ChangeListener to this MenuSelectionManager
88
   *
89
   * @param listener ChangeListener to add
90
   */
91
  public void addChangeListener(ChangeListener listener)
92
  {
93
    listenerList.add(ChangeListener.class, listener);
94
  }
95
 
96
  /**
97
   * Removes ChangeListener from the list of registered listeners
98
   * for this MenuSelectionManager.
99
   *
100
   * @param listener ChangeListner to remove
101
   */
102
  public void removeChangeListener(ChangeListener listener)
103
  {
104
    listenerList.remove(ChangeListener.class, listener);
105
  }
106
 
107
  /**
108
   * Returns list of registered listeners with MenuSelectionManager
109
   *
110
   * @since 1.4
111
   */
112
  public ChangeListener[] getChangeListeners()
113
  {
114
    return (ChangeListener[]) listenerList.getListeners(ChangeListener.class);
115
  }
116
 
117
  /**
118
   * Unselects all the menu elements on the selection path
119
   */
120
  public void clearSelectedPath()
121
  {
122
    // Send events from the bottom most item in the menu - hierarchy to the
123
    // top most
124
    for (int i = selectedPath.size() - 1; i >= 0; i--)
125
      ((MenuElement) selectedPath.get(i)).menuSelectionChanged(false);
126
 
127
    // clear selected path
128
    selectedPath.clear();
129
 
130
    // notify all listeners that the selected path was changed    
131
    fireStateChanged();
132
  }
133
 
134
  /**
135
   * This method returns menu element on the selected path that contains
136
   * given source point. If no menu element on the selected path contains this
137
   * point, then null is returned.
138
   *
139
   * @param source Component relative to which sourcePoint is given
140
   * @param sourcePoint point for which we want to find menu element that contains it
141
   *
142
   * @return Returns menu element that contains given source point and belongs
143
   * to the currently selected path. Null is return if no such menu element found.
144
   */
145
  public Component componentForPoint(Component source, Point sourcePoint)
146
  {
147
    // Convert sourcePoint to screen coordinates.
148
    Point sourcePointOnScreen = sourcePoint;
149
 
150
    if (source.isShowing())
151
      SwingUtilities.convertPointToScreen(sourcePointOnScreen, source);
152
 
153
    Point compPointOnScreen;
154
    Component resultComp = null;
155
 
156
    // For each menu element on the selected path, express its location 
157
    // in terms of screen coordinates and check if there is any 
158
    // menu element on the selected path that contains given source point.
159
    for (int i = 0; i < selectedPath.size(); i++)
160
      {
161
        Component comp = ((Component) selectedPath.get(i));
162
        Dimension size = comp.getSize();
163
 
164
        // convert location of this menu item to screen coordinates
165
        compPointOnScreen = comp.getLocationOnScreen();
166
 
167
        if (compPointOnScreen.x <= sourcePointOnScreen.x
168
            && sourcePointOnScreen.x < compPointOnScreen.x + size.width
169
            && compPointOnScreen.y <= sourcePointOnScreen.y
170
            && sourcePointOnScreen.y < compPointOnScreen.y + size.height)
171
          {
172
            Point p = sourcePointOnScreen;
173
 
174
        if (comp.isShowing())
175
          SwingUtilities.convertPointFromScreen(p, comp);
176
 
177
            resultComp = SwingUtilities.getDeepestComponentAt(comp, p.x, p.y);
178
            break;
179
          }
180
      }
181
    return resultComp;
182
  }
183
 
184
  /**
185
   * Returns shared instance of MenuSelection Manager
186
   *
187
   * @return default Manager
188
   */
189
  public static MenuSelectionManager defaultManager()
190
  {
191
    return manager;
192
  }
193
 
194
  /**
195
   * Returns path representing current menu selection
196
   *
197
   * @return Current selection path
198
   */
199
  public MenuElement[] getSelectedPath()
200
  {
201
    MenuElement[] path = new MenuElement[selectedPath.size()];
202
 
203
    for (int i = 0; i < path.length; i++)
204
      path[i] = (MenuElement) selectedPath.get(i);
205
 
206
    return path;
207
  }
208
 
209
  /**
210
   * Returns true if specified component is part of current menu
211
   * heirarchy and false otherwise
212
   *
213
   * @param c Component for which to check
214
   * @return True if specified component is part of current menu
215
   */
216
  public boolean isComponentPartOfCurrentMenu(Component c)
217
  {
218
    MenuElement[] subElements;
219
      for (int i = 0; i < selectedPath.size(); i++)
220
      {
221
         subElements = ((MenuElement) selectedPath.get(i)).getSubElements();
222
         for (int j = 0; j < subElements.length; j++)
223
         {
224
            MenuElement me = subElements[j];
225
            if (me != null && (me.getComponent()).equals(c))
226
               return true;
227
         }
228
      }
229
 
230
      return false;
231
  }
232
 
233
  /**
234
   * DOCUMENT ME!
235
   *
236
   * @param e DOCUMENT ME!
237
   */
238
  public void processKeyEvent(KeyEvent e)
239
  {
240
    throw new UnsupportedOperationException("not implemented");
241
  }
242
 
243
  /**
244
   * Forwards given mouse event to all of the source subcomponents.
245
   *
246
   * @param event Mouse event
247
   */
248
  public void processMouseEvent(MouseEvent event)
249
  {
250
    Component source = ((Component) event.getSource());
251
 
252
    // In the case of drag event, event.getSource() returns component
253
    // where drag event originated. However menu element processing this 
254
    // event should be the one over which mouse is currently located, 
255
    // which is not necessary the source of the drag event.     
256
    Component mouseOverMenuComp;
257
 
258
    // find over which menu element the mouse is currently located
259
    if (event.getID() == MouseEvent.MOUSE_DRAGGED
260
        || event.getID() == MouseEvent.MOUSE_RELEASED)
261
      mouseOverMenuComp = componentForPoint(source, event.getPoint());
262
    else
263
      mouseOverMenuComp = source;
264
 
265
    // Process this event only if mouse is located over some menu element
266
    if (mouseOverMenuComp != null && (mouseOverMenuComp instanceof MenuElement))
267
      {
268
        MenuElement[] path = getPath(mouseOverMenuComp);
269
        ((MenuElement) mouseOverMenuComp).processMouseEvent(event, path,
270
                                                            manager);
271
 
272
        // FIXME: Java specification says that mouse events should be
273
        // forwarded to subcomponents. The code below does it, but
274
        // menu's work fine without it. This code is commented for now.   
275
 
276
        /*
277
        MenuElement[] subComponents = ((MenuElement) mouseOverMenuComp)
278
                                      .getSubElements();
279
 
280
        for (int i = 0; i < subComponents.length; i++)
281
         {
282
              subComponents[i].processMouseEvent(event, path, manager);
283
         }
284
        */
285
      }
286
    else
287
      {
288
        if (event.getID() == MouseEvent.MOUSE_RELEASED)
289
          clearSelectedPath();
290
      }
291
  }
292
 
293
  /**
294
   * Sets menu selection to the specified path
295
   *
296
   * @param path new selection path
297
   */
298
  public void setSelectedPath(MenuElement[] path)
299
  {
300
    if (path == null)
301
      {
302
        clearSelectedPath();
303
        return;
304
      }
305
 
306
    int i;
307
    int minSize = path.length; // size of the smaller path. 
308
 
309
    if (path.length > selectedPath.size())
310
      {
311
        minSize = selectedPath.size();
312
 
313
        // if new selected path contains more elements then current
314
        // selection then first add all elements at 
315
        // the indexes > selectedPath.size 
316
        for (i = selectedPath.size(); i < path.length; i++)
317
          {
318
            selectedPath.add(path[i]);
319
            path[i].menuSelectionChanged(true);
320
          }
321
      }
322
 
323
    else if (path.length < selectedPath.size())
324
      {
325
        // if new selected path contains less elements then current 
326
        // selection then first remove all elements from the selection
327
        // at the indexes > path.length
328
        for (i = selectedPath.size() - 1; i >= path.length; i--)
329
          {
330
            ((MenuElement) selectedPath.get(i)).menuSelectionChanged(false);
331
            selectedPath.remove(i);
332
          }
333
 
334
        minSize = path.length;
335
      }
336
 
337
    // Now compare elements in new and current selection path at the 
338
    // same location and adjust selection until 
339
    // same menu elements will be encountered at the
340
    // same index in both current and new selection path.
341
    MenuElement oldSelectedItem;
342
 
343
    for (i = minSize - 1; i >= 0; i--)
344
      {
345
        oldSelectedItem = (MenuElement) selectedPath.get(i);
346
 
347
        if (path[i].equals(oldSelectedItem))
348
          break;
349
 
350
        oldSelectedItem.menuSelectionChanged(false);
351
        path[i].menuSelectionChanged(true);
352
        selectedPath.setElementAt(path[i], i);
353
      }
354
 
355
    fireStateChanged();
356
  }
357
 
358
  /**
359
   * Returns path to the specified component
360
   *
361
   * @param c component for which to find path for
362
   *
363
   * @return path to the specified component
364
   */
365
  private MenuElement[] getPath(Component c)
366
  {
367
    // FIXME: There is the same method in BasicMenuItemUI. However I
368
    // cannot use it here instead of this method, since I cannot assume that 
369
    // all the menu elements on the selected path are JMenuItem or JMenu.
370
    // For now I've just duplicated it here. Please 
371
    // fix me or delete me if another better approach will be found, and 
372
    // this method will not be necessary.
373
    ArrayList path = new ArrayList();
374
 
375
    // if given component is JMenu, we also need to include 
376
    // it's popup menu in the path 
377
    if (c instanceof JMenu)
378
      path.add(((JMenu) c).getPopupMenu());
379
    while (c instanceof MenuElement)
380
      {
381
        path.add(0, (MenuElement) c);
382
 
383
        if (c instanceof JPopupMenu)
384
          c = ((JPopupMenu) c).getInvoker();
385
        else
386
          c = c.getParent();
387
      }
388
 
389
    MenuElement[] pathArray = new MenuElement[path.size()];
390
    path.toArray(pathArray);
391
    return pathArray;
392
  }
393
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.