2
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
6
* The contents of this file are subject to the terms of either the GNU
7
* General Public License Version 2 only ("GPL") or the Common
8
* Development and Distribution License("CDDL") (collectively, the
9
* "License"). You may not use this file except in compliance with the
10
* License. You can obtain a copy of the License at
11
* http://www.netbeans.org/cddl-gplv2.html
12
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13
* specific language governing permissions and limitations under the
14
* License. When distributing the software, include this License Header
15
* Notice in each file and include the License file at
16
* nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
17
* particular file as subject to the "Classpath" exception as provided
18
* by Sun in the GPL Version 2 section of the License file that
19
* accompanied this code. If applicable, add the following below the
20
* License Header, with the fields enclosed by brackets [] replaced by
21
* your own identifying information:
22
* "Portions Copyrighted [year] [name of copyright owner]"
26
* The Original Software is NetBeans. The Initial Developer of the Original
27
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
28
* Microsystems, Inc. All Rights Reserved.
30
* If you wish your version of this file to be governed by only the CDDL
31
* or only the GPL Version 2, indicate your decision by adding
32
* "[Contributor] elects to include this software in this distribution
33
* under the [CDDL or GPL Version 2] license." If you do not indicate a
34
* single choice of license, a recipient has the option to distribute
35
* your version of this file under either the CDDL, the GPL Version 2 or
36
* to extend the choice of license to its licensees as provided above.
37
* However, if you add GPL Version 2 code and therefore, elected the GPL
38
* Version 2 license, then the option applies only if the new code is
39
* made subject to such option by the copyright holder.
41
package org.netbeans.modules.form.menu;
43
import java.awt.BorderLayout;
44
import java.awt.Color;
45
import java.awt.Component;
47
import java.awt.Graphics;
48
import java.awt.Graphics2D;
49
import java.awt.Insets;
50
import java.awt.Point;
51
import java.awt.RenderingHints;
52
import java.awt.dnd.DropTarget;
53
import java.awt.dnd.DropTargetDragEvent;
54
import java.awt.dnd.DropTargetDropEvent;
55
import java.awt.dnd.DropTargetEvent;
56
import java.awt.dnd.DropTargetListener;
57
import java.awt.event.ComponentEvent;
58
import java.awt.event.ComponentListener;
59
import java.awt.event.KeyEvent;
60
import java.awt.event.KeyListener;
61
import java.awt.event.MouseEvent;
62
import java.beans.PropertyChangeEvent;
63
import java.beans.PropertyChangeListener;
64
import java.util.ArrayList;
65
import java.util.Collections;
66
import java.util.HashMap;
67
import java.util.List;
69
import java.util.TooManyListenersException;
70
import javax.swing.Action;
71
import javax.swing.BorderFactory;
72
import javax.swing.Icon;
73
import javax.swing.JCheckBoxMenuItem;
74
import javax.swing.JComponent;
75
import javax.swing.JLayeredPane;
76
import javax.swing.JMenu;
77
import javax.swing.JMenuBar;
78
import javax.swing.JMenuItem;
79
import javax.swing.JPanel;
80
import javax.swing.JPopupMenu;
81
import javax.swing.JRadioButtonMenuItem;
82
import javax.swing.JSeparator;
83
import javax.swing.SwingUtilities;
84
import javax.swing.UIManager;
85
import javax.swing.border.Border;
86
import javax.swing.border.CompoundBorder;
87
import javax.swing.event.MouseInputAdapter;
88
import javax.swing.plaf.PopupMenuUI;
89
import org.netbeans.modules.form.*;
90
import org.netbeans.modules.form.actions.PropertyAction;
91
import org.netbeans.modules.form.assistant.AssistantMessages;
92
import org.netbeans.modules.form.editors.IconEditor.NbImageIcon;
93
import org.netbeans.modules.form.palette.PaletteItem;
94
import org.netbeans.modules.form.palette.PaletteUtils;
95
import org.openide.filesystems.FileObject;
96
import org.openide.nodes.Node;
97
import org.openide.nodes.NodeOp;
98
import org.openide.util.NbBundle;
102
* @author joshua.marinacci@sun.com
104
public class MenuEditLayer extends JPanel {
105
/* === constants for the look of the designer === */
106
public static final Border DRAG_MENU_BORDER = BorderFactory.createLineBorder(Color.BLACK,1);
107
public static final Border DRAG_SEPARATOR_BORDER = BorderFactory.createLineBorder(Color.RED,1);
108
public static final Color SELECTED_MENU_BACKGROUND = new Color(0xA5A6A9);
109
public static final Color EMPTY_ICON_COLOR = new Color(0xDDDDDD);
110
public static final int EMPTY_ICON_BORDER_WIDTH = 2;
112
/* === private constants === */
113
private static final boolean DEBUG = false;
114
private static final boolean USE_NEW_ITEM_COLOR_SWITCHING = false;
116
/* === public and package level fields. these should probably become getters and setters ===*/
117
public VisualDesignerPopupFactory hackedPopupFactory = null;
118
public FormDesigner formDesigner;
120
JComponent glassLayer;
121
DropTargetLayer dropTargetLayer;
122
boolean showMenubarWarning = false;
124
/* === private fields === */
125
private Map<JMenu, PopupMenuUI> menuPopupUIMap;
127
public enum SelectedPortion { Icon, Text, Accelerator, All, None };
128
private SelectedPortion selectedPortion = SelectedPortion.None;
130
private KeyboardMenuNavigator keyboardMenuNavigator;
131
private Map<RADVisualContainer,FormModelListener> formModelListeners;
132
private DragOperation dragop;
133
private FormModelListener menuBarFormListener;
134
private PropertyChangeListener selectionListener;
135
private boolean isAlive = true;
136
private static final boolean USE_JSEPARATOR_FIX = true;
138
/** Creates a new instance of MenuEditLayer */
139
public MenuEditLayer(final FormDesigner formDesigner) {
140
this.formDesigner = formDesigner;
141
menuPopupUIMap = new HashMap<JMenu, PopupMenuUI>();
142
formModelListeners = new HashMap<RADVisualContainer,FormModelListener>();
146
layers = new JLayeredPane();
147
this.setLayout(new BorderLayout());
148
this.add(layers,"Center");
150
dragop = new DragOperation(this);
152
glassLayer = new JComponent() {
153
public void paintComponent(Graphics g) {
155
g.setColor(Color.GREEN);
156
g.drawString("Glass Layer", 30,30);
157
g.drawRect(0,0,getWidth()-1,getHeight()-1);
162
layers.add(glassLayer, new Integer(500)); // put the glass layer over the drag layer
163
glassLayer.setSize(400,400); //josh: do i need this line? probably can delete it.
165
dropTargetLayer = new DropTargetLayer(this);
166
layers.add(dropTargetLayer, new Integer(JLayeredPane.DRAG_LAYER-5)); // put the drop target layer just above the drag layer
168
// make the extra layers resize to the main component
169
this.addComponentListener(new ComponentListener() {
170
public void componentResized(ComponentEvent e) {
171
glassLayer.setSize(MenuEditLayer.this.getSize());
172
dropTargetLayer.setSize(MenuEditLayer.this.getSize());
175
public void componentMoved(ComponentEvent arg0) {
178
public void componentShown(ComponentEvent arg0) {
181
public void componentHidden(ComponentEvent arg0) {
185
MouseInputAdapter mia = new GlassLayerMouseListener();
186
glassLayer.addMouseListener(mia);
187
glassLayer.addMouseMotionListener(mia);
188
configureSelectionListener();
190
if (!assistantInitialized) {
195
DragOperation getDragOperation() {
199
private boolean assistantInitialized = false;
200
private void initAssistant() {
201
String missingMenubarMsg = "You cannot add a menu component to a form without a menubar";
202
AssistantMessages messages = AssistantMessages.getDefault();
203
messages.setMessages("missingMenubar", missingMenubarMsg); // NOI18N
204
assistantInitialized = true;
207
public static boolean isMenuRelatedRADComponent(RADComponent comp) {
208
if(comp == null) return false;
209
return isMenuRelatedComponentClass(comp.getBeanClass());
212
public static boolean isNonMenuJSeparator(RADComponent comp) {
213
if(comp == null) return false;
214
if(JSeparator.class.isAssignableFrom(comp.getBeanClass())) {
215
RADComponent parent = comp.getParentComponent();
216
if(parent != null && JMenu.class.isAssignableFrom(parent.getBeanClass())) {
225
public static boolean isMenuBarContainer(RADComponent comp) {
226
if(comp == null) return false;
227
Class clas = comp.getBeanClass();
228
if(clas == null) return false;
229
if(JMenuBar.class.isAssignableFrom(clas)) return true;
233
public static boolean isMenuRelatedContainer(RADComponent comp) {
234
if(comp == null) return false;
235
Class clas = comp.getBeanClass();
236
if(clas == null) return false;
237
if(JMenu.class.isAssignableFrom(clas)) return true;
238
if(JPopupMenu.class.isAssignableFrom(clas)) return true;
242
public static boolean isMenuRelatedComponentClass(Class clas) {
243
if(clas == null) return false;
244
if(JMenuItem.class.isAssignableFrom(clas)) return true;
245
if(JMenu.class.isAssignableFrom(clas)) return true;
246
if(JSeparator.class.isAssignableFrom(clas)) return true;
247
if(JMenuBar.class.isAssignableFrom(clas)) return true;
251
public boolean isPossibleNewMenuComponent(PaletteItem item) {
252
if(item == null) return false;
253
if(item.getComponentClass() == null) return false;
254
if(JMenuItem.class.isAssignableFrom(item.getComponentClass())) {
261
public void startNewMenuComponentPickAndPlop(PaletteItem item, Point pt) {
262
this.setVisible(true);
264
dragop = new DragOperation(this);
265
dragop.start(item, pt);
268
public void startNewMenuComponentDragAndDrop(PaletteItem item) {
269
this.setVisible(true);
271
configureGlassLayer();
272
configureFormListeners();
276
protected void paintComponent(Graphics g) {
277
super.paintComponent(g);
279
g.setColor(Color.RED);
280
g.drawString("the MenuEditLayer is visible",5,getHeight()-5);
282
Graphics2D g2 = (Graphics2D) g.create();
283
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
284
g2.setColor(Color.BLACK);
285
/* Using the assistant now instead of text ontop of the glasspane.
286
* josh: I need to delete all of the previous code related to the showMenubarWarning boolean
287
if(showMenubarWarning) {
288
g2.drawString("You cannot add a menu component to a form without a menubar.", 5, getHeight()-30);
294
// the public method for non-menu parts of the form editor to
295
// start menu editing
296
public void openAndShowMenu(RADComponent metacomp, Component comp) {
297
//p("making sure the menu is open: " + metacomp + " " + metacomp.getName());
298
if(hackedPopupFactory == null) {
299
this.hackedPopupFactory = new VisualDesignerPopupFactory(this);
301
openMenu(metacomp, comp);
302
glassLayer.requestFocusInWindow();
305
void openMenu(RADComponent metacomp, Component comp) {
307
configureGlassLayer();
308
registerKeyListeners();
309
configureFormListeners();
310
configureSelectionListener();
312
JMenu menu = (JMenu) comp;
313
configureMenu(null,menu);
315
if(metacomp instanceof RADVisualContainer) {
316
keyboardMenuNavigator.setCurrentMenuRAD((RADVisualContainer)metacomp);
321
public void hideMenuLayer() {
322
// tear down each menu and menu item
323
unconfigureFormListeners();
324
unconfigureSelectionListener();
325
for(JMenu m : menuPopupUIMap.keySet()) {
328
menuPopupUIMap.clear();
329
if(hackedPopupFactory != null) {
330
hackedPopupFactory.containerMap.clear();
331
hackedPopupFactory = null;
333
if(dragop.isStarted()) {
336
// close all popup frames
337
this.setVisible(false);
338
if(keyboardMenuNavigator != null) {
339
glassLayer.removeKeyListener(keyboardMenuNavigator);
340
keyboardMenuNavigator.unconfigure();
341
keyboardMenuNavigator = null;
343
backgroundMap.clear();
344
//hackedPopupFactory.containerMap.clear();
345
if(formDesigner.getHandleLayer() != null) {
346
formDesigner.getHandleLayer().requestFocusInWindow();
350
//josh: all this key listener stuff should go into a separate class
351
private synchronized void registerKeyListeners() {
352
if(keyboardMenuNavigator == null) {
353
keyboardMenuNavigator = new KeyboardMenuNavigator(this);
354
glassLayer.addKeyListener(keyboardMenuNavigator);
355
glassLayer.addKeyListener(new KeyListener() {
357
public void keyTyped(KeyEvent e) {
360
public void keyPressed(KeyEvent e) {
361
if(e.getKeyCode() == KeyEvent.VK_ESCAPE) {
366
public void keyReleased(KeyEvent e) {
373
private VisualDesignerPopupFactory getPopupFactory() {
374
if(hackedPopupFactory == null) {
375
hackedPopupFactory = new VisualDesignerPopupFactory(this);
377
return hackedPopupFactory;
380
private void configureGlassLayer() {
382
glassLayer.setDropTarget(new DropTarget());
383
glassLayer.getDropTarget().addDropTargetListener(new GlassLayerDropTargetListener());
384
} catch (TooManyListenersException ex) {
385
ex.printStackTrace();
389
PropertyChangeListener paletteListener = null;
390
private void configureFormListeners() {
392
if(menuBarFormListener == null) {
393
menuBarFormListener = new FormModelListener() {
394
public void formChanged(FormModelEvent[] events) {
396
for(FormModelEvent evt : events) {
397
// if this is a menubar delete event
398
if(evt.getChangeType() == evt.COMPONENT_REMOVED) {
399
if(evt.getComponent() != null &&
400
JMenuBar.class.isAssignableFrom(evt.getComponent().getBeanClass())) {
404
if(evt.getChangeType() == evt.FORM_TO_BE_CLOSED) {
408
if(evt.getChangeType() == evt.COMPONENT_ADDED) {
409
if(evt.getCreatedDeleted()) {
410
if(USE_NEW_ITEM_COLOR_SWITCHING) {
411
configureNewComponent(evt.getComponent());
420
formDesigner.getFormModel().addFormModelListener(menuBarFormListener);
422
if(paletteListener == null) {
423
paletteListener = new PropertyChangeListener() {
424
public void propertyChange(PropertyChangeEvent evt) {
425
if(PaletteUtils.getSelectedItem() == null ||
426
!isMenuRelatedComponentClass(PaletteUtils.getSelectedItem().getComponentClass())) {
427
if(dragop != null && dragop.isStarted()) {
433
paletteContext = formDesigner.getFormEditor().getFormDataObject().getFormFile();
434
PaletteUtils.addPaletteListener(paletteListener, paletteContext);
438
FileObject paletteContext = null;
439
private void unconfigureFormListeners() {
440
if(menuBarFormListener != null) {
441
if(formDesigner != null && formDesigner.getFormModel() != null) {
442
formDesigner.getFormModel().removeFormModelListener(menuBarFormListener);
445
if(paletteListener != null) {
446
PaletteUtils.removePaletteListener(paletteListener, paletteContext);
447
paletteContext = null;
448
paletteListener = null;
450
menuBarFormListener = null;
453
private void configureSelectionListener() {
454
if(selectionListener == null) {
455
selectionListener = new PropertyChangeListener() {
456
public void propertyChange(PropertyChangeEvent evt) {
458
Node[] newNodes = (Node[])evt.getNewValue();
459
List<RADComponent> selectedNodes = new ArrayList<RADComponent>();
461
for(Node n : newNodes) {
462
if(n instanceof RADComponentNode) {
463
RADComponentNode radn = (RADComponentNode) n;
464
selectedNodes.add(radn.getRADComponent());
468
setSelectedRADComponents(selectedNodes);
473
formDesigner.addPropertyChangeListener("activatedNodes",selectionListener);
477
private void unconfigureSelectionListener() {
478
if(selectionListener != null) {
479
formDesigner.removePropertyChangeListener(selectionListener);
480
selectionListener = null;
484
void showMenuPopup(final JMenu menu) {
486
// if already created then just make it visible
487
if(hackedPopupFactory.containerMap.containsKey(menu)) {
488
JPanel view = hackedPopupFactory.containerMap.get(menu);
489
view.setVisible(true);
491
if(!isConfigured(menu)) {
492
configureMenu(null, menu);
494
final JPopupMenu popup = menu.getPopupMenu();
496
if(!(popup.getUI() instanceof VisualDesignerPopupMenuUI)) {
497
popup.setUI(new VisualDesignerPopupMenuUI(this, popup.getUI()));
499
if(menu.isVisible()) {
500
//force popup view creation
501
hackedPopupFactory.getPopup(menu, null, 0, 0);
503
// do later so that the component will definitely be on screen by then
504
SwingUtilities.invokeLater(new Runnable() {
507
popup.show(menu,0,menu.getHeight());
508
} catch (Exception ex) {
509
ex.printStackTrace();
510
//ignore anyexceptions caused by showing the popups
520
public boolean isMenuLayerComponent(RADComponent metacomp) {
521
if(metacomp == null) {
524
if(metacomp.getBeanClass().equals(JMenuItem.class)) {
527
if(metacomp.getBeanClass().equals(JMenu.class)) {
535
void configureMenu(final JComponent parent, final JMenu menu) {
536
//p("configuring the menu: " + menu.getText());
537
// make sure it will draw it's border so we can have rollovers and selection
538
menu.setBorderPainted(true);
539
//install the wrapper icon if not a toplevel JMenu
540
if(!isTopLevelMenu(menu)) {
541
if(!(menu.getIcon() instanceof WrapperIcon)) {
542
menu.setIcon(new WrapperIcon(menu.getIcon()));
546
// configure the maps and popups
547
JPopupMenu popup = menu.getPopupMenu();
548
//p("got a popup: " + popup);
549
menuPopupUIMap.put(menu, popup.getUI());
550
popup.setUI(new VisualDesignerPopupMenuUI(this, popup.getUI()));
552
// get all of the components in this menu
553
Component[] subComps = menu.getMenuComponents();
554
//p("the current subcomps of the menu are:");
555
for(Component c : subComps) {
558
// if this isn't the first time this menu has been opened then the sub components
559
// will have been moved to the popupPanel already, so we will find them there instead.
560
JPanel popupPanel = getPopupFactory().containerMap.get(menu);
561
if(popupPanel != null) {
562
subComps = popupPanel.getComponents();
566
RADVisualContainer menuRAD = (RADVisualContainer) formDesigner.getMetaComponent(menu);
567
registerForm(menuRAD,menu);
569
// recurse for sub-menus
570
for(Component c : subComps) {
571
if(c instanceof JMenu) {
572
configureMenu(menu, (JMenu)c);
573
RADComponent rad = formDesigner.getMetaComponent(c);
574
registerForm((RADVisualContainer)rad,(JMenu)c);
576
configureMenuItem(menu, (JComponent) c);
581
private void unconfigureMenu(final JMenu menu) {
583
menu.getPopupMenu().setUI(menuPopupUIMap.get(menu));
585
// restore all children
586
JPanel popup = hackedPopupFactory.containerMap.get(menu);
588
for(Component c : popup.getComponents()) {
589
if(c instanceof JMenu) {
590
unconfigureMenu((JMenu)c);
592
unconfigureMenuItem((JComponent) c);
596
//hide the popup(s) if it's still visible
597
if(menu.getPopupMenu() != null) {
598
menu.getPopupMenu().setVisible(false);
600
popup.setVisible(false);
601
//layers.remove(popup);
603
VisualDesignerJPanelPopup pop = hackedPopupFactory.getPopup(menu);
608
popup.setVisible(false);
610
menu.setPopupMenuVisible(false);
611
hackedPopupFactory.containerMap.remove(menu);
614
private boolean isConfigured(JComponent c) {
615
return menuPopupUIMap.containsKey(c);
619
void configureMenuItem(final JMenu parent, final JComponent c) {
620
if(c instanceof JMenuItem) {
621
JMenuItem item = (JMenuItem) c;
622
if(!(item.getIcon() instanceof WrapperIcon)) {
623
item.setIcon(new WrapperIcon(item.getIcon()));
625
installAcceleratorPreview(item);
626
item.setBorderPainted(true);
630
static final int ACCEL_PREVIEW_WIDTH = 80;
631
private static final Border accel_border = new Border() {
633
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
634
g.setColor(Color.WHITE);
636
if(DropTargetLayer.isAqua()) {
640
if(DropTargetLayer.isVista()) {
643
g.fillRect(width-ACCEL_PREVIEW_WIDTH+offset, 1,ACCEL_PREVIEW_WIDTH-0+ioffset, height+ioffset);
644
g.setColor(EMPTY_ICON_COLOR);
645
g.drawRect(width-ACCEL_PREVIEW_WIDTH+offset, 1,ACCEL_PREVIEW_WIDTH-1+ioffset, height+ioffset);
646
g.drawRect(width-ACCEL_PREVIEW_WIDTH+offset+1, 2,ACCEL_PREVIEW_WIDTH-3+ioffset, height-2+ioffset);
647
g.setColor(Color.LIGHT_GRAY);
648
g.setFont(new Font("SansSerif",Font.PLAIN,10));
649
String shortcut = NbBundle.getMessage(MenuEditLayer.class, "MENU_Shortcut"); // NOI18N
650
g.drawString(shortcut, width-ACCEL_PREVIEW_WIDTH+15,height-3+ioffset);
653
public Insets getBorderInsets(Component c) {
654
return new Insets(0,0,0,ACCEL_PREVIEW_WIDTH);
657
public boolean isBorderOpaque() {
664
//installs a special border to represent the accelerator preview
665
//if the menu item already has an accelerator, then it will
666
//remove the preview if necessary.
667
private static void installAcceleratorPreview(JMenuItem item) {
668
if(item instanceof JMenu) return;
669
//detect accelerator key
670
boolean already_has_accel = false;
671
if(item.getAccelerator() != null) already_has_accel = true;
672
if(item.getAction() != null && item.getAction().getValue(Action.ACCELERATOR_KEY) != null) already_has_accel = true;
676
boolean already_has_accel_border = false;
677
if(item.getBorder() == accel_border) {
678
already_has_accel_border = true;
679
//uninstall if needed
680
if(already_has_accel) {
681
item.setBorder(null);
686
if(item.getBorder() instanceof CompoundBorder) {
687
CompoundBorder comp = (CompoundBorder)item.getBorder();
688
if(comp.getInsideBorder() == accel_border) {
689
already_has_accel_border = true;
690
//uninstall if needed
691
if(already_has_accel) {
692
item.setBorder(comp.getOutsideBorder());
698
if(already_has_accel_border) return;
699
if(already_has_accel) return;
702
if(item.getBorder() == null) {
703
item.setBorder(accel_border);
707
item.setBorder(BorderFactory.createCompoundBorder(
708
item.getBorder(),accel_border));
712
void unconfigureMenuItem(JComponent c) {
717
//override JComponent.isOpaque to always return false
718
public boolean isOpaque() {
723
// returns true if parent really is an ancestor of target
724
boolean isAncestor(JComponent target, JComponent parent) {
725
if(!(parent instanceof JMenu)) {
728
RADComponent targetRad = formDesigner.getMetaComponent(target);
729
RADComponent parentRad = targetRad.getParentComponent();
730
if(parentRad == null) return false;
731
Object possibleParent = formDesigner.getComponent(parentRad);
732
RADComponent realParentRad = formDesigner.getMetaComponent(parent);
733
if(parentRad == realParentRad) {
736
if(parent == possibleParent) {
739
// recursively check up the chain to see if this is a further ancestor
740
if(possibleParent instanceof JMenu) {
741
return isAncestor((JMenu)possibleParent, parent);
747
boolean hasSelectedDescendants(JMenu menu) {
748
RADComponent comp =formDesigner.getMetaComponent(menu);
749
if(comp instanceof RADVisualContainer) {
750
return hasSelectedDescendants((RADVisualContainer)comp);
754
boolean hasSelectedDescendants(RADVisualContainer comp) {
755
if(this.selectedComponents.contains(comp)) {
758
for(RADComponent c : comp.getSubBeans()) {
759
if(this.selectedComponents.contains(c)) return true;
760
if(c instanceof RADVisualContainer) {
761
boolean sel = hasSelectedDescendants((RADVisualContainer)c);
768
JComponent getMenuParent(JComponent menu) {
769
RADComponent targetRad = formDesigner.getMetaComponent(menu);
770
RADComponent parentRad = targetRad.getParentComponent();
771
Object possibleParent = formDesigner.getComponent(parentRad);
772
if(possibleParent instanceof JComponent) {
773
return (JComponent) possibleParent;
780
List<RADComponent> getSelectedRADComponents() {
781
return Collections.unmodifiableList(selectedComponents);
784
RADComponent getSingleSelectedComponent() {
785
if(selectedComponents.isEmpty()) {
788
if(selectedComponents.size() > 1) {
789
setSelectedRADComponent(selectedComponents.get(0));
791
return selectedComponents.get(0);
795
private List<RADComponent> selectedComponents = new ArrayList<RADComponent>();
798
boolean isComponentSelected() {
799
return !selectedComponents.isEmpty();
802
void setSelectedRADComponent(RADComponent comp) {
803
List<RADComponent> comps = new ArrayList<RADComponent>();
805
setSelectedRADComponents(comps);
806
formDesigner.setSelectedComponent(comp);
809
void addSelectedRADComponent(RADComponent comp) {
810
List<RADComponent> comps = new ArrayList<RADComponent>();
811
comps.addAll(selectedComponents);
813
setSelectedRADComponents(comps);
814
formDesigner.addComponentToSelection(comp);
817
void setSelectedRADComponents(List<RADComponent> comps) {
819
//clear old bgs first
820
for(RADComponent rad : selectedComponents) {
821
if(isMenuRelatedRADComponent(rad) && !isMenuBarContainer(rad) && !isNonMenuJSeparator(rad)) { // don't mess w/ the menubar's background
822
JComponent c = (JComponent) formDesigner.getComponent(rad);
823
if(c != null) { // could be null if comp was just deleted
824
c.setBackground(getNormalBackground(rad, c));
829
selectedComponents.clear();
830
selectedComponents.addAll(comps);
832
//check for non-menu comps
833
for(RADComponent c : selectedComponents) {
834
if (!isMenuRelatedRADComponent(c) || isNonMenuJSeparator(c)) {
840
registerKeyListeners();
842
for(RADComponent rad : selectedComponents) {
843
JComponent c = (JComponent) formDesigner.getComponent(rad);
845
if(!isMenuBarContainer(rad)) { // don't mess w/ the menubar's background
846
c.setBackground(getSelectedBackground(c));
848
makeSureShowingOnScreen(rad, c);
849
if (c instanceof JMenu) {
850
showMenuPopup((JMenu) c);
857
} catch (Exception ex) {
858
ex.printStackTrace();
862
private String getComponentDefaultsPrefix(JComponent c) {
863
if(c instanceof JMenuBar) {
866
if(c instanceof JMenu) {
869
if(c instanceof JCheckBoxMenuItem) {
870
return "CheckBoxMenuItem";
872
if(c instanceof JRadioButtonMenuItem) {
873
return "RadioButtonMenuItem";
878
private Color getNormalBackground(RADComponent metacomp, JComponent c) {
879
RADProperty prop = metacomp.getBeanProperty("background"); // NOI18N
883
Object value = prop.getTargetValue();
884
if (value instanceof Color) {
885
color = (Color)value;
887
} catch (Exception ex) {}
890
// fallback - for example subclass of menu component
891
// that hides background property
892
color = backgroundMap.get(c);
897
private Map<JComponent, Color> backgroundMap = new HashMap<JComponent,Color>();
898
private Color getSelectedBackground(JComponent c) {
899
//don't put into the map twice
900
if(!backgroundMap.containsKey(c)) {
901
backgroundMap.put(c,c.getBackground());
903
return SELECTED_MENU_BACKGROUND;
906
private Color getNormalForeground(JComponent c) {
907
String prefix = getComponentDefaultsPrefix(c);
908
Color color = UIManager.getDefaults().getColor(prefix+".foreground");
917
private void makeSureShowingOnScreen(RADComponent rad, JComponent comp) {
918
if(!this.isVisible()) {
919
this.setVisible(true);
920
registerKeyListeners();
921
if(rad instanceof RADVisualContainer) {
922
keyboardMenuNavigator.setCurrentMenuRAD((RADVisualContainer)rad);
924
keyboardMenuNavigator.setCurrentMenuRAD((RADVisualContainer)rad.getParentComponent());
928
List<RADComponent> path = new ArrayList<RADComponent>();
929
RADComponent temp = rad.getParentComponent();
931
if(temp == null) break;
933
temp = temp.getParentComponent();
934
if(!isMenuRelatedRADComponent(temp)) {
939
// go backwards, top to bottom
940
for(int i = path.size()-1; i>=0; i--) {
941
RADComponent r = path.get(i);
942
JComponent c = (JComponent) formDesigner.getComponent(r);
943
if(c instanceof JMenu) {
944
showMenuPopup((JMenu)c);
953
private void showContextMenu(Point popupPos) {
954
ComponentInspector inspector = ComponentInspector.getInstance();
955
Node[] selectedNodes = inspector.getSelectedNodes();
956
JPopupMenu popup = NodeOp.findContextMenu(selectedNodes);
957
if(!this.isVisible()) {
958
this.setVisible(true);
961
popup.show(this, popupPos.x, popupPos.y);
966
// returns true if this is a menu container that should be highlighted if the component
967
// tcomp is dragged over it.
968
public boolean canHighlightContainer(RADVisualContainer targetContainer, RADVisualComponent tcomp) {
969
Class beanclass = tcomp.getBeanClass();
970
if(targetContainer != null && targetContainer.isMenuComponent() && targetContainer.canAddComponent(beanclass)) {
976
// is this rollover code still being used?
977
// this turns on and off the rollover highlight as well as auto-opening the menu
979
private JComponent prevRollover = null;
980
public void rolloverContainer(RADVisualContainer targetContainer) {
981
if(targetContainer == null && prevRollover != null) {
984
if(targetContainer != null) {
985
JComponent rollover = (JComponent) formDesigner.getComponent(targetContainer);
986
if(rollover != prevRollover){
989
prevRollover = rollover;
990
prevRollover.setBorder(new Border() {
992
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
993
Graphics2D g2 = (Graphics2D) g;
994
g2.setStroke(DropTargetLayer.DROP_TARGET_LINE_STROKE);
995
g2.setColor(DropTargetLayer.DROP_TARGET_COLOR);
996
g2.drawRect(x,y,width,height);
999
public Insets getBorderInsets(Component c) {
1000
return new Insets(2,2,2,2);
1003
public boolean isBorderOpaque() {
1006
//BorderFactory.createLineBorder(Color.ORANGE,2)
1008
prevRollover.repaint();
1009
if(rollover instanceof JMenu) {
1010
formDesigner.openMenu(targetContainer);
1011
//openMenu(targetContainer,rollover);
1016
public void clearRollover() {
1017
if(prevRollover==null) return;
1018
prevRollover.setBorder(BorderFactory.createEmptyBorder());
1019
prevRollover.repaint();
1020
prevRollover = null;
1024
void addRadComponentToBefore(RADVisualComponent payloadRad, JComponent target) {
1025
addRadComponentTo(payloadRad, target, +0);
1028
void addRadComponentToAfter(RADVisualComponent payloadRad, JComponent target) {
1029
addRadComponentTo(payloadRad, target, +1);
1031
private void addRadComponentTo(RADVisualComponent payloadRad, JComponent target, int offset) {
1033
JComponent targetParent = getMenuParent(target);
1034
if(target.getParent() instanceof JMenuBar) {
1035
targetParent = (JComponent) target.getParent();
1037
//p("target parent = " + targetParent);
1038
RADVisualComponent targetRad = (RADVisualComponent) formDesigner.getMetaComponent(target);
1039
//p("target rad = " + targetRad);
1040
RADVisualContainer targetParentRad = (RADVisualContainer) formDesigner.getMetaComponent(targetParent);
1041
//p("target parent rad = " + targetParentRad);
1043
assert targetParentRad != null;
1045
//p("=== inserting before drop target component ===");
1046
int index2 = targetParentRad.getIndexOf(targetRad) + offset;
1047
//p("inserting at index: " + index2);
1048
FormModelEvent fme2 = formDesigner.getFormModel().fireComponentAdded(payloadRad, false);
1049
formDesigner.getFormModel().addVisualComponent(payloadRad, targetParentRad, new Integer(index2), true);
1050
} catch (Exception ex) {
1051
ex.printStackTrace();
1056
boolean addRadComponentToEnd(JComponent targetComponent, MetaComponentCreator creator) {
1057
RADVisualContainer targetContainer = (RADVisualContainer) formDesigner.getMetaComponent(targetComponent);
1058
//p("target container = " + targetContainer);
1059
Object constraints = null;
1060
boolean added = creator.addPrecreatedComponent(targetContainer, constraints);
1061
//p("added comp: " + creator.getPrecreatedMetaComponent());
1065
void moveRadComponentInto(JComponent payload, JComponent targetMenu) {
1068
//check if dragging onto self
1069
if(payload == targetMenu) {
1073
//check if dragging to a descendant node
1074
if(isAncestor(targetMenu, payload)) {
1078
JComponent payloadParent = getMenuParent(payload);
1079
if(payloadParent == null) {
1080
payloadParent = (JComponent) payload.getParent();
1082
//p("payload parent = " + payloadParent);
1083
RADVisualComponent payloadRad = (RADVisualComponent) formDesigner.getMetaComponent(payload);
1084
//p("payload rad = " + payloadRad);
1085
RADVisualContainer payloadParentRad = (RADVisualContainer) formDesigner.getMetaComponent(payloadParent);
1086
//p("payload parent rad = " + payloadParentRad);
1088
if(payloadRad != null && payloadParentRad == null) {
1089
p("MenuDesigner: WARNING! their is a payload rad without a parent! how did we get here!");
1092
// remove the component from it's old location
1093
// if no payload rad then that probably means this is a new component from the palette
1094
if(payloadRad != null && payloadParentRad != null) {
1095
int index = payloadParentRad.getIndexOf(payloadRad);
1096
payloadParentRad.remove(payloadRad);
1097
FormModelEvent fme = formDesigner.getFormModel().fireComponentRemoved(payloadRad, payloadParentRad, index, false);
1100
RADVisualContainer targetMenuRad = (RADVisualContainer) formDesigner.getMetaComponent(targetMenu);
1101
//p("target menu rad = " + targetMenuRad);
1102
//add inside the target menu
1103
//p("=== inserting at end of a menu ===");
1104
//add to end of the toplevel menu
1105
targetMenuRad.add(payloadRad, -1);
1106
targetMenuRad.getLayoutSupport().addComponents(new RADVisualComponent[] { payloadRad }, null, -1);
1107
FormModelEvent fme2 = formDesigner.getFormModel().fireComponentAdded(payloadRad, false);
1109
} catch (Exception ex) {
1110
ex.printStackTrace();
1114
void moveRadComponentToBefore(JComponent payload, JComponent target) {
1115
moveRadComponentTo(payload, target, 0);
1117
void moveRadComponentToAfter(JComponent payload, JComponent target) {
1118
moveRadComponentTo(payload, target, 1);
1120
private void moveRadComponentTo(JComponent payload, JComponent target, int offset) {
1122
if(payload == target) {
1125
//check if dragging to a descendant node
1126
if(isAncestor(target, payload)) {
1129
JComponent payloadParent = getMenuParent(payload);
1131
if(payloadParent == null) {
1132
payloadParent = (JComponent) payload.getParent();
1134
//p("payload parent = " + payloadParent);
1136
JComponent targetParent = getMenuParent(target);
1138
if(targetParent == null) {
1139
targetParent = (JComponent) target.getParent();
1141
//p("target parent = " + targetParent);
1143
RADVisualComponent payloadRad = (RADVisualComponent) formDesigner.getMetaComponent(payload);
1144
//p("payload rad = " + payloadRad);
1145
RADVisualComponent targetRad = (RADVisualComponent) formDesigner.getMetaComponent(target);
1146
//p("target rad = " + targetRad);
1147
RADVisualContainer payloadParentRad = (RADVisualContainer) formDesigner.getMetaComponent(payloadParent);
1148
//p("payload parent rad = " + payloadParentRad);
1149
RADVisualContainer targetParentRad = (RADVisualContainer) formDesigner.getMetaComponent(targetParent);
1150
//p("target parent rad = " + targetParentRad);
1153
//if a toplevel menu dragged next to another toplevel menu
1154
if(payload instanceof JMenu && payload.getParent() instanceof JMenuBar
1155
&& target instanceof JMenu && target.getParent() instanceof JMenuBar) {
1156
//remove from old spot
1157
targetParent = (JComponent) target.getParent();
1158
payloadParent = (JComponent) payload.getParent();
1159
payloadParentRad = (RADVisualContainer) formDesigner.getMetaComponent(payloadParent);
1160
targetParentRad = (RADVisualContainer) formDesigner.getMetaComponent(targetParent);
1161
//p("new payload parent rad = " + payloadParentRad);
1164
//p("=== removing ===");
1165
//skip if no payload rad, which probably means this is a new component from the palette
1166
if(payloadRad != null && payloadParentRad != null) {
1167
//p("=== did a remove ===");
1168
int index = payloadParentRad.getIndexOf(payloadRad);
1169
payloadParentRad.remove(payloadRad);
1170
FormModelEvent fme = formDesigner.getFormModel().fireComponentRemoved(payloadRad, payloadParentRad, index, false);
1174
//if dragged component into a toplevel menu
1175
if(targetParent == null && target instanceof JMenu && target.getParent() instanceof JMenuBar) {
1176
//p("=== inserting at end of a toplevel menu ===");
1177
targetParentRad = (RADVisualContainer) targetRad;
1178
//add to end of the toplevel menu
1179
targetParentRad.add(payloadRad, -1);
1180
targetParentRad.getLayoutSupport().addComponents(new RADVisualComponent[] { payloadRad }, null, -1);
1181
FormModelEvent fme2 = formDesigner.getFormModel().fireComponentAdded(payloadRad, false);
1185
// insert if target exists, else the item was removed by dragging out of the menu
1186
if(targetParentRad != null) {
1187
//p("=== inserting before drop target component ===");
1188
int index2 = targetParentRad.getIndexOf(targetRad) + offset;
1189
//p("index of target = " + index2);
1190
targetParentRad.add(payloadRad, index2);
1191
targetParentRad.getLayoutSupport().addComponents(new RADVisualComponent[] { payloadRad },
1193
FormModelEvent fme2 = formDesigner.getFormModel().fireComponentAdded(payloadRad, false);
1195
} catch (Exception ex) {
1196
ex.printStackTrace();
1200
public static boolean addComponentToEndOfMenu(RADComponent targetContainer, PaletteItem paletteItem) {
1201
FormModel model = targetContainer.getFormModel();
1202
MetaComponentCreator creator = model.getComponentCreator();
1203
RADVisualComponent precreated = creator.precreateVisualComponent(
1204
paletteItem.getComponentClassSource());
1205
JComponent newComponent = (JComponent) precreated.getBeanInstance();
1206
boolean added = creator.addPrecreatedComponent(targetContainer, null);
1211
// change the look of the component to reflect the newly added state.
1212
// this mainly means making the foreground color light gray.
1213
void configureNewComponent(RADComponent item) {
1215
JComponent c = (JComponent) formDesigner.getComponent(item);
1217
c.setForeground(Color.LIGHT_GRAY);
1223
// change the look of the component to reflect the fully edited state
1224
private void configureEditedComponent(JComponent c) {
1225
//p("configuring an edited component");
1226
if(c == null) return;
1227
if(USE_NEW_ITEM_COLOR_SWITCHING) {
1228
if(c.getForeground() == Color.LIGHT_GRAY) {
1229
c.setForeground(getNormalForeground(c));
1234
void configureEditedComponent(RADComponent c) {
1236
configureEditedComponent((JComponent)formDesigner.getComponent(c));
1240
//listens to see if this particular menu has been changed
1241
private void registerForm(final RADVisualContainer metacomp, final JMenu menu) {
1242
// don't double register
1243
if(!formModelListeners.containsKey(metacomp)) {
1244
FormModelListener fml = new FormModelListener() {
1245
public void formChanged(FormModelEvent[] events) {
1246
p("form changed starting");
1247
if (events != null) {
1248
for(FormModelEvent evt : events) {
1250
p("form model update: " + evt.getChangeType() + " = ");
1251
switch(evt.getChangeType()) {
1252
case FormModelEvent.COMPONENT_PROPERTY_CHANGED: p("COMPONENT_PROPERTY_CHANGED");break;
1253
case FormModelEvent.COMPONENT_ADDED: p("COMPONENT_ADDED");break;
1254
case FormModelEvent.COMPONENT_REMOVED: p("COMPONENT_REMOVED");break;
1255
case FormModelEvent.COMPONENTS_REORDERED: p("COMPONENTS_REORDERED");break;
1256
case FormModelEvent.BINDING_PROPERTY_CHANGED: p("BINDING_PROPERTY_CHANGED");break;
1257
case FormModelEvent.FORM_LOADED: p("FORM_LOADED"); break;
1258
case FormModelEvent.FORM_TO_BE_CLOSED: p("FORM_TO_BE_CLOSED"); break;
1259
default: p("unknown type");
1261
if(evt.getComponent() != null) {
1262
p(" " + evt.getComponent().getName());
1265
if(evt.getChangeType() == evt.FORM_TO_BE_CLOSED) {
1266
formModelListeners.remove(metacomp);
1267
metacomp.getFormModel().addFormModelListener(this);
1271
if(evt.getChangeType() == evt.COMPONENT_PROPERTY_CHANGED) {
1272
if("action".equals(evt.getPropertyName())) {
1273
configureEditedComponent(evt.getComponent());
1276
if(evt.getChangeType() == evt.COMPONENT_PROPERTY_CHANGED || evt.getChangeType() == evt.BINDING_PROPERTY_CHANGED) {
1277
if(evt.getContainer() == metacomp || evt.getComponent() == metacomp) {
1278
rebuildOnScreenMenu(metacomp);
1280
updateIcon(evt.getComponent());
1283
if(evt.getChangeType() == evt.COMPONENT_ADDED) {
1284
updateIcon(evt.getComponent());
1285
//reinstall the accelerator preview when moving items around
1286
if(evt.getComponent() != null) {
1287
Component co = (Component) formDesigner.getComponent(evt.getComponent());
1288
if(co instanceof JMenuItem) {
1289
installAcceleratorPreview((JMenuItem)co);
1294
// if this menu was deleted then make sure it's popup is hidden and removed
1295
if(evt.getChangeType() == evt.COMPONENT_REMOVED) {
1296
if(evt.getComponent() == metacomp) {
1297
p("this component was removed");
1298
unconfigureMenu(menu);
1302
// if something added to the menu we monitor
1303
if(evt.getChangeType() == evt.COMPONENT_ADDED ||
1304
evt.getChangeType() == evt.COMPONENTS_REORDERED ||
1305
evt.getChangeType() == evt.COMPONENT_REMOVED) {
1306
if(evt.getContainer() == metacomp) {
1307
// then rebuild the menu
1308
rebuildOnScreenMenu(metacomp);
1311
if(evt.getContainer() == getFormMenuBar()) {
1312
p("it was a rad though: " + getFormMenuBar());
1313
JComponent comp = (JComponent) formDesigner.getComponent(getFormMenuBar());
1314
p("comp = " + comp);
1315
//comp.revalidate();
1316
RADVisualContainer rad = (RADVisualContainer) getFormMenuBar();
1318
for(RADVisualComponent c : rad.getSubComponents()) {
1321
comp.add((JComponent)formDesigner.getComponent(c));
1328
p("form changed ending");
1331
formModelListeners.put(metacomp,fml);
1332
metacomp.getFormModel().addFormModelListener(fml);
1336
private void rebuildOnScreenMenu(RADVisualContainer menuRAD) {
1337
if(menuRAD == null) return;
1338
if(hackedPopupFactory == null) return;
1339
p("** rebuildOnScreenMenu() called on: " + menuRAD.getName());
1340
JMenu menu = (JMenu) formDesigner.getComponent(menuRAD);
1341
if(hackedPopupFactory.containerMap.containsKey(menu)) {
1342
JPanel popupContainer = hackedPopupFactory.containerMap.get(menu);
1343
if(popupContainer == null) return;
1344
//p("looking over components left");
1345
for(Component c : popupContainer.getComponents()) {
1346
//p("found comp: " + c);
1347
if(c instanceof JMenu) {
1348
unconfigureMenu((JMenu)c);
1350
unconfigureMenuItem((JComponent)c);
1353
//p("removing all from container");;
1354
popupContainer.removeAll();
1356
for(RADVisualComponent child : menuRAD.getSubComponents()) {
1358
JComponent jchild = (JComponent) formDesigner.getComponent(child);
1359
//p("checking: " + jchild);
1360
if(!isConfigured(jchild)) {
1361
//p("not configured!");
1362
if(jchild instanceof JMenu) {
1363
configureMenu(menu, (JMenu)jchild);
1365
configureMenuItem(menu,jchild);
1368
popupContainer.add(jchild);
1373
popupContainer.setSize(popupContainer.getLayout().preferredLayoutSize(popupContainer));
1375
popupContainer.repaint();
1377
//p("menu popup not built yet: " + menu.getName());
1381
private void updateIcon(RADComponent rad) {
1382
p("updating icon for rad: " + rad);
1384
Component comp = (Component) formDesigner.getComponent(rad);
1385
if(comp instanceof JMenuItem) {
1386
JMenuItem item = (JMenuItem) comp;
1387
//p("item rad = " + rad);
1388
RADProperty icon_prop = rad.getBeanProperty("icon");
1389
//p("icon prop = " + icon_prop);
1390
Object value = icon_prop.getValue();
1391
//p("value = " + value);
1392
// extract the new value
1394
if(value instanceof Icon) {
1395
icon = (Icon) value;
1397
if(value instanceof NbImageIcon) {
1398
icon = ((NbImageIcon)value).getIcon();
1400
if(value instanceof ResourceValue) {
1401
ResourceValue rv = (ResourceValue) value;
1402
//p("design value = " + rv.getDesignValue());
1403
Object designValue = rv.getDesignValue();
1404
if(designValue instanceof Icon) {
1405
//p("updating icon w/ design value");
1406
icon = (Icon) designValue;
1408
if(designValue instanceof NbImageIcon) {
1409
icon = ((NbImageIcon)designValue).getIcon();
1412
// do the actual update
1413
if(!(item.getIcon() instanceof WrapperIcon) && !isTopLevelMenu(item)) {
1414
item.setIcon(new WrapperIcon(item.getIcon()));
1417
if(item.getIcon() instanceof WrapperIcon) {
1418
((WrapperIcon)item.getIcon()).setIcon(icon);
1419
} else { // we should never get here
1423
} catch (Throwable thr) {
1424
thr.printStackTrace();
1429
private static void p(String string) {
1432
System.out.println(string);
1438
//returns true if this array contains a menu component
1439
public static boolean containsMenuTypeComponent(RADVisualComponent[] comps) {
1440
if(comps == null) return false;
1441
if(comps.length < 1) return false;
1442
for(RADVisualComponent c : comps) {
1443
if(JMenuItem.class.isAssignableFrom(c.getBeanClass())) return true;
1444
if(JMenuBar.class.isAssignableFrom(c.getBeanClass())) return true;
1445
if(JMenu.class.isAssignableFrom(c.getBeanClass())) return true;
1450
public static boolean containsMenuBar(RADVisualComponent[] comps) {
1451
if(comps == null) return false;
1452
if(comps.length < 1) return false;
1453
for(RADVisualComponent c : comps) {
1454
if(JMenuBar.class.isAssignableFrom(c.getBeanClass())) return true;
1459
// returns true if this container is a menubar or menu, else false
1460
public static boolean isValidMenuContainer(RADVisualContainer cont) {
1461
if(cont == null) return false;
1462
if(JMenuBar.class.isAssignableFrom(cont.getBeanClass())) return true;
1463
if(JMenu.class.isAssignableFrom(cont.getBeanClass())) return true;
1467
public static boolean isTopLevelMenu(JComponent comp) {
1468
if(comp == null) return false;
1469
if(comp instanceof JMenu) {
1470
if(comp.getParent() instanceof JMenuBar) return true;
1475
public boolean doesFormContainMenuBar() {
1476
for(RADComponent comp : formDesigner.getFormModel().getAllComponents()) {
1477
if(JMenuBar.class.isAssignableFrom(comp.getBeanClass())) {
1484
public RADComponent getFormMenuBar() {
1485
for(RADComponent comp : formDesigner.getFormModel().getAllComponents()) {
1486
if(JMenuBar.class.isAssignableFrom(comp.getBeanClass())) {
1494
private class GlassLayerMouseListener extends MouseInputAdapter {
1495
Point pressPoint = null;
1496
JComponent pressComp = null;
1497
private boolean isEditing = false;
1499
public void mouseClicked(MouseEvent e) {
1502
public void mousePressed(MouseEvent e) {
1503
p("mouse pressed: " + e);
1504
p("started = " + dragop.isStarted() + " pnp = " + dragop.isPickAndPlop() + " target = " + dragop.getTargetComponent());
1506
//if this is a valid menu drop
1507
if(dragop.isStarted() && dragop.getTargetComponent() != null &&
1508
isMenuRelatedComponentClass(dragop.getTargetComponent().getClass())) {
1509
p("skipping the lower part");
1510
if(e.isShiftDown()) {
1511
dragop.end(e.getPoint(), false);
1512
PaletteItem item = PaletteUtils.getSelectedItem();
1513
dragop.start(item, e.getPoint());
1515
dragop.end(e.getPoint(), true);
1519
if(shouldRedispatchToHandle()) {
1521
formDesigner.getHandleLayer().dispatchEvent(e);
1525
if(dragop.isStarted()) {
1526
dragop.end(e.getPoint());
1530
// open top level menus when clicking them
1531
RADComponent rad = formDesigner.getHandleLayer().getMetaComponentAt(e.getPoint(), HandleLayer.COMP_DEEPEST);
1533
JComponent c = (JComponent) formDesigner.getComponent(rad);
1534
if(c != null && isTopLevelMenu(c)) {
1535
if(e.getClickCount() > 1) {
1537
configureEditedComponent(c);
1538
formDesigner.startInPlaceEditing(rad);
1541
glassLayer.requestFocusInWindow();
1542
if(DropTargetLayer.isMultiselectPressed(e)) {
1543
addSelectedRADComponent(rad);
1545
setSelectedRADComponent(rad);
1547
if(e.isPopupTrigger()) {
1548
showContextMenu(e.getPoint());
1551
if(!dragop.isStarted()) {
1552
pressPoint = e.getPoint();
1559
if(c instanceof JMenuBar) {
1560
setSelectedRADComponent(rad);
1561
if(e.isPopupTrigger()) {
1562
showContextMenu(e.getPoint());
1569
JComponent c = dragop.getDeepestComponentInPopups(e.getPoint());
1572
if(c == null && !isMenuRelatedRADComponent(rad)) {
1573
p("not a menu component. going back to handle layer");
1574
PaletteUtils.clearPaletteSelection();
1576
formDesigner.getHandleLayer().mousePressed(e);
1581
if(e.getClickCount() > 1) {
1582
if(c instanceof JMenuItem) {
1583
p("starting the inline editing");
1584
JMenuItem item = (JMenuItem) c;
1585
Point pt = SwingUtilities.convertPoint(glassLayer, e.getPoint(), item);
1586
SelectedPortion portion = DropTargetLayer.calculateSelectedPortion(item, pt);
1587
p("selected portion = " + portion);
1588
RADComponent radcomp = formDesigner.getMetaComponent(item);
1589
configureEditedComponent(c);
1590
if(portion == SelectedPortion.Icon) {
1592
showIconEditor(radcomp);
1593
} else if (portion == SelectedPortion.Accelerator) {
1595
showAcceleratorEditor(radcomp);
1598
formDesigner.startInPlaceEditing(radcomp);
1603
// show context menu
1604
if(e.isPopupTrigger()) {
1605
p("showing a context menu");
1606
showContextMenu(e.getPoint());
1610
//prep for drag motion for menuitem to menuitem drags
1611
if(!dragop.isStarted() && c instanceof JMenuItem) {
1612
p("possibly starting a drag op");
1613
pressPoint = e.getPoint();
1619
public void mouseReleased(MouseEvent e) {
1620
if(e.isPopupTrigger()) {
1621
//p("showing a context menu");
1622
showContextMenu(e.getPoint());
1626
//p("mouse released: " + e);
1627
if(dragop.isStarted() && !e.isShiftDown()) {
1628
dragop.end(e.getPoint());
1631
JComponent c = (JComponent) dragop.getDeepestComponentInPopups(e.getPoint());
1633
if(c instanceof JMenuItem) {
1634
Point localPt = SwingUtilities.convertPoint(glassLayer, e.getPoint(), c);
1635
selectedPortion = DropTargetLayer.calculateSelectedPortion((JMenuItem)c, localPt);
1636
dropTargetLayer.repaint();
1638
selectedPortion = SelectedPortion.None;
1640
glassLayer.requestFocusInWindow();
1641
RADComponent rad = formDesigner.getMetaComponent(c);
1642
//add to selection if shift is down, instead of replacing
1643
if(DropTargetLayer.isMultiselectPressed(e)) {
1644
addSelectedRADComponent(rad);
1646
setSelectedRADComponent(rad);
1654
private void showIconEditor(RADComponent comp) {
1656
RADProperty prop = comp.getBeanProperty("icon");
1657
new PropertyAction(prop).actionPerformed(null);
1658
} catch (Throwable th) {
1659
th.printStackTrace();
1662
private void showAcceleratorEditor(RADComponent comp) {
1664
RADProperty prop = comp.getBeanProperty("accelerator");
1665
new PropertyAction(prop).actionPerformed(null);
1666
} catch (Throwable th) {
1667
th.printStackTrace();
1671
public void mouseEntered(MouseEvent e) {
1672
if(showMenubarWarning) {
1673
showMenubarWarning = false;
1676
if(dragop.isStarted()) {
1677
if(PaletteUtils.getSelectedItem() == null && dragop.isPickAndPlop()) {
1680
dragop.setTargetVisible(true);
1683
if(!dragop.isStarted() || PaletteUtils.getSelectedItem() != dragop.getCurrentItem()) {
1684
PaletteItem item = PaletteUtils.getSelectedItem();
1686
// if not menu related at all, then jump back to handle layer
1687
if(item != null && !isMenuRelatedComponentClass(item.getComponentClass())) {
1688
p("not a menu component. going back to the handle layer");
1693
if(formDesigner.getDesignerMode() == FormDesigner.MODE_ADD && item != null) {
1694
if(JMenuBar.class.isAssignableFrom(item.getComponentClass())) {
1695
p("dragging in a menu bar. go back to handle layer");
1699
dragop.start(item,e.getPoint());
1703
if(formDesigner.getDesignerMode() == FormDesigner.MODE_SELECT && showMenubarWarning) {
1704
p("still in bad mode");
1705
//glassLayer.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
1706
showMenubarWarning = false;
1712
public void mouseExited(MouseEvent e) {
1713
//p("mouse exited: " + e);
1714
if(dragop.isStarted()) {
1715
dragop.setTargetVisible(false);
1719
public void mouseDragged(MouseEvent e) {
1720
if(!dragop.isStarted() && pressPoint != null && pressComp instanceof JMenuItem
1721
&& e.getPoint().distance(pressPoint) > 10) {
1722
p("starting the dragop");
1723
dragop.start((JMenuItem)pressComp, e.getPoint());
1727
if(dragop.isStarted()) {
1728
dragop.move(e.getPoint());
1733
public void mouseMoved(MouseEvent e) {
1734
if(shouldRedispatchToHandle()) {
1735
formDesigner.getHandleLayer().dispatchEvent(e);
1739
if(dragop.isStarted()) {
1740
if(!doesFormContainMenuBar()) {
1741
FormEditor.getAssistantModel(formDesigner.getFormModel()).setContext("missingMenubar"); // NOI18N
1743
dragop.move(e.getPoint());
1748
private boolean shouldRedispatchToHandle() {
1749
if(!USE_JSEPARATOR_FIX) return false;
1750
if(dragop.isStarted() && dragop.isPickAndPlop()) {
1751
if(dragop.getDragComponent() instanceof JSeparator /*&&
1752
dropTargetLayer.getDropTargetComponent() == null*/) {
1761
private boolean shouldRedispatchDnDToHandle(DropTargetDragEvent dtde) {
1764
RADComponent rad = formDesigner.getHandleLayer().getMetaComponentAt(dtde.getLocation(), HandleLayer.COMP_DEEPEST);
1765
p("comp under = " + rad);
1766
if(rad != null && isMenuRelatedComponentClass(rad.getBeanClass())) {
1767
p("over menu stuff. cancel the proxying");
1770
//if(true) return false;
1771
if(!USE_JSEPARATOR_FIX) return false;
1772
PaletteItem item = PaletteUtils.getSelectedItem();
1773
if(item != null && JSeparator.class.isAssignableFrom(item.getComponentClass())) {
1779
private class GlassLayerDropTargetListener implements DropTargetListener {
1780
public void dragEnter(DropTargetDragEvent dtde) {
1781
if(shouldRedispatchDnDToHandle(dtde)) {
1782
dragProxying = true;
1783
formDesigner.getHandleLayer().getNewComponentDropListener().dragEnter(dtde);
1786
p("drag enter: " + dtde);
1787
if(!dragop.isStarted()) {
1792
private void start(DropTargetDragEvent dtde) {
1793
p("really starting the Drag stuff");
1794
PaletteItem item = PaletteUtils.getSelectedItem();
1796
if(item != null && !isMenuRelatedComponentClass(item.getComponentClass())) {
1797
p("not a menu component. going back to the handle layer");
1802
if(formDesigner.getDesignerMode() == FormDesigner.MODE_ADD && item != null) {
1803
if(JMenuBar.class.isAssignableFrom(item.getComponentClass())) {
1804
p("dragging in a menu bar. go back to handle layer");
1808
dragop.start(item,dtde.getLocation());
1812
public void dragOver(DropTargetDragEvent dtde) {
1813
p("full dragover: " + dtde.getLocation());
1814
p("should redispatch = " + shouldRedispatchDnDToHandle(dtde));
1815
// look at the rad component under the cursor first
1817
if(dragProxying && shouldRedispatchDnDToHandle(dtde)) {
1818
formDesigner.getHandleLayer().getNewComponentDropListener().dragOver(dtde);
1821
p("switching to normal menulayer dnd");
1822
dragProxying = false;
1823
p("drag over: " + dtde);
1824
if(dragop.isStarted()) {
1826
dragop.move(dtde.getLocation());
1832
public void dropActionChanged(DropTargetDragEvent dtde) {
1835
public void dragExit(DropTargetEvent dte) {
1836
//if(shouldRedispatchDnDToHandle()) {
1838
formDesigner.getHandleLayer().getNewComponentDropListener().dragExit(dte);
1840
dragProxying = false;
1843
public void drop(DropTargetDropEvent dtde) {
1844
//if(shouldRedispatchDnDToHandle()) {
1846
formDesigner.getHandleLayer().getNewComponentDropListener().drop(dtde);
1847
dragProxying = false;
1850
if(dragop.isStarted()) {
1851
dragop.end(dtde.getLocation());
1852
dragProxying = false;
1860
public SelectedPortion getCurrentSelectedPortion() {
1861
return selectedPortion;
1865
private boolean dragProxying = false;
1866
public boolean isDragProxying() {
1867
return dragProxying;
1871
static class WrapperIcon implements Icon {
1872
private Icon wrapee;
1873
public WrapperIcon() {
1876
public WrapperIcon(Icon icon) {
1880
public void setIcon(Icon icon) {
1884
public void paintIcon(Component arg0, Graphics g, int x, int y) {
1885
if(wrapee != null) {
1886
wrapee.paintIcon(arg0, g, x, y);
1888
Graphics g2 = g.create();
1889
g2.setColor(Color.WHITE);
1890
g2.fillRect(x,y,getIconWidth()-1, getIconHeight()-1);
1891
g2.setColor(MenuEditLayer.EMPTY_ICON_COLOR);
1892
g2.drawRect(x,y,getIconWidth()-1, getIconHeight()-1);
1893
g2.drawRect(x+1,y+1,getIconWidth()-3, getIconHeight()-3);
1898
public int getIconWidth() {
1899
if(wrapee != null) {
1900
return wrapee.getIconWidth();
1905
public int getIconHeight() {
1906
if(wrapee != null) {
1907
return wrapee.getIconHeight();