KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > core > windows > view > ui > DefaultSeparateContainer


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20
21 package org.netbeans.core.windows.view.ui;
22
23
24 import java.awt.KeyboardFocusManager JavaDoc;
25 import java.beans.PropertyChangeEvent JavaDoc;
26 import java.beans.PropertyVetoException JavaDoc;
27 import java.beans.VetoableChangeListener JavaDoc;
28 import java.io.CharConversionException JavaDoc;
29 import java.text.MessageFormat JavaDoc;
30 import javax.swing.border.Border JavaDoc;
31 import javax.swing.plaf.basic.BasicHTML JavaDoc;
32 import org.netbeans.core.windows.Constants;
33 import org.netbeans.core.windows.ModeImpl;
34 import org.netbeans.core.windows.WindowManagerImpl;
35 import org.netbeans.core.windows.view.ModeView;
36 import org.netbeans.core.windows.view.ViewElement;
37 import org.netbeans.core.windows.view.dnd.TopComponentDroppable;
38 import org.netbeans.core.windows.view.dnd.WindowDnDManager;
39 import org.netbeans.core.windows.view.dnd.ZOrderManager;
40 import org.netbeans.core.windows.view.ui.tabcontrol.TabbedAdapter;
41 import org.openide.util.NbBundle;
42 import org.openide.util.Utilities;
43 import org.openide.windows.TopComponent;
44
45 import javax.swing.*;
46 import java.awt.*;
47 import java.awt.event.*;
48 import org.openide.windows.WindowManager;
49 import org.openide.xml.XMLUtil;
50
51
52 /**
53  * Implementation of <code>ModeContainer</code> for separate mode kind.
54  *
55  * @author Peter Zavadsky
56  */

57 public final class DefaultSeparateContainer extends AbstractModeContainer {
58
59     /** Separate mode represented by JFrame or null if dialog is used */
60     private final ModeFrame modeFrame;
61     /** Separate mode represented by JDialog or null if frame is used */
62     private final ModeDialog modeDialog;
63
64     /** Creates a DefaultSeparateContainer. */
65     public DefaultSeparateContainer(final ModeView modeView, WindowDnDManager windowDnDManager, Rectangle bounds, int kind) {
66         super(modeView, windowDnDManager, kind);
67         // JFrame or JDialog according to the mode kind
68
if (kind == Constants.MODE_KIND_EDITOR) {
69             modeFrame = new ModeFrame(this, modeView);
70             modeFrame.setIconImage(MainWindow.createIDEImage());
71             modeDialog = null;
72         } else {
73             modeDialog = new ModeDialog(WindowManager.getDefault().getMainWindow(), this, modeView);
74             modeFrame = null;
75         }
76         Window w = getModeUIWindow();
77         ((RootPaneContainer) w).getContentPane().add(tabbedHandler.getComponent());
78         w.setBounds(bounds);
79     }
80     
81     public void requestAttention (TopComponent tc) {
82         //not implemented
83
}
84     
85     public void cancelRequestAttention (TopComponent tc) {
86         //not implemented
87
}
88
89     /** */
90     protected Component getModeComponent() {
91         return getModeUIWindow();
92     }
93     
94     protected Tabbed createTabbed() {
95         Tabbed tabbed;
96         if(getKind() == Constants.MODE_KIND_EDITOR) {
97             tabbed = new TabbedAdapter(Constants.MODE_KIND_EDITOR);
98         } else {
99             tabbed = new TabbedAdapter(Constants.MODE_KIND_VIEW);
100         }
101         return tabbed;
102     }
103     
104     protected void updateTitle (String JavaDoc title) {
105         getModeUIBase().updateTitle(title);
106     }
107     
108     protected void updateActive (boolean active) {
109         Window w = getModeUIWindow();
110         if(active) {
111             if (w.isVisible() && !w.isActive()) {
112                 w.toFront();
113             }
114         }
115     }
116     
117     public boolean isActive () {
118         return getModeUIWindow().isActive();
119     }
120     
121     protected boolean isAttachingPossible() {
122         return false;
123     }
124     
125     protected TopComponentDroppable getModeDroppable() {
126         return getModeUIBase();
127     }
128
129     private Window getModeUIWindow () {
130         return modeFrame != null ? modeFrame : modeDialog;
131     }
132
133     private ModeUIBase getModeUIBase () {
134         return (ModeUIBase)getModeUIWindow();
135     }
136
137     /** Separate mode UI backed by JFrame.
138      *
139      * [dafe] Whole DnD of window system expects that ModeComponent and
140      * TopComponentDroppable implementation must exist in AWT hierarchy,
141      * so I have to extend Swing class here, not just use it. That's why all this
142      * delegating stuff.
143      */

144     private static class ModeFrame extends JFrame implements ModeUIBase {
145
146         /** Base helper to delegate to for common things */
147         private SharedModeUIBase modeBase;
148    
149         public ModeFrame (AbstractModeContainer abstractModeContainer, ModeView view) {
150             super();
151             // To be able to activate on mouse click.
152
enableEvents(java.awt.AWTEvent.MOUSE_EVENT_MASK);
153             modeBase = new SharedModeUIBaseImpl(abstractModeContainer, view, this);
154         }
155
156         public ModeView getModeView() {
157             return modeBase.getModeView();
158         }
159
160         public int getKind() {
161             return modeBase.getKind();
162         }
163
164         public Shape getIndicationForLocation(Point location) {
165             return modeBase.getIndicationForLocation(location);
166         }
167
168         public Object JavaDoc getConstraintForLocation(Point location) {
169             return modeBase.getConstraintForLocation(location);
170         }
171
172         public Component getDropComponent() {
173             return modeBase.getDropComponent();
174         }
175
176         public ViewElement getDropViewElement() {
177             return modeBase.getDropViewElement();
178         }
179
180         public boolean canDrop(TopComponent transfer, Point location) {
181             return modeBase.canDrop(transfer, location);
182         }
183
184         public boolean supportsKind(int kind, TopComponent transfer) {
185             return modeBase.supportsKind(kind, transfer);
186         }
187
188         /** Actually sets title for the frame
189          */

190         public void updateTitle(String JavaDoc title) {
191             // extract HTML from text - Output window (and soon others) uses it
192
if (BasicHTML.isHTMLString(title)) {
193                 char[] c = title.toCharArray();
194                 StringBuffer JavaDoc sb = new StringBuffer JavaDoc(title.length());
195                 boolean inTag = false;
196                 boolean inEntity = false;
197                 for (int i=0; i < c.length; i++) {
198                     if (inTag && c[i] == '>') { //NOI18N
199
inTag = false;
200                         continue;
201                     }
202                     if (!inTag && c[i] == '<') { //NOI18N
203
inTag = true;
204                         continue;
205                     }
206                     if (!inTag) {
207                         sb.append(c[i]);
208                     }
209                 }
210                 //XXX, would be nicer to support the full complement of entities...
211
title = Utilities.replaceString(sb.toString(), "&nbsp;", " "); //NOI18N
212
}
213             String JavaDoc completeTitle = MessageFormat.format(
214                     NbBundle.getMessage(DefaultSeparateContainer.class, "CTL_SeparateEditorTitle"),
215                     title);
216             setTitle(completeTitle);
217         }
218
219     } // end of ModeFrame
220

221     /** Separate mode UI backed by JFrame.
222      *
223      * [dafe] Whole DnD of window system expects that ModeComponent and
224      * TopComponentDroppable implementation must exist in AWT hierarchy,
225      * so I have to extend Swing class here, not just use it. That's why all this
226      * delegating stuff.
227      */

228     private static class ModeDialog extends JDialog implements ModeUIBase {
229
230         /** Base helper to delegate to for common things */
231         private SharedModeUIBase modeBase;
232     
233         public ModeDialog (Frame owner, AbstractModeContainer abstractModeContainer, ModeView view) {
234             super(owner);
235             // To be able to activate on mouse click.
236
enableEvents(java.awt.AWTEvent.MOUSE_EVENT_MASK);
237             modeBase = new SharedModeUIBaseImpl(abstractModeContainer, view, this);
238         }
239
240         public ModeView getModeView() {
241             return modeBase.getModeView();
242         }
243
244         public int getKind() {
245             return modeBase.getKind();
246         }
247
248         public Shape getIndicationForLocation(Point location) {
249             return modeBase.getIndicationForLocation(location);
250         }
251
252         public Object JavaDoc getConstraintForLocation(Point location) {
253             return modeBase.getConstraintForLocation(location);
254         }
255
256         public Component getDropComponent() {
257             return modeBase.getDropComponent();
258         }
259
260         public ViewElement getDropViewElement() {
261             return modeBase.getDropViewElement();
262         }
263
264         public boolean canDrop(TopComponent transfer, Point location) {
265             return modeBase.canDrop(transfer, location);
266         }
267
268         public boolean supportsKind(int kind, TopComponent transfer) {
269             return modeBase.supportsKind(kind, transfer);
270         }
271
272         public void updateTitle(String JavaDoc title) {
273             // noop - no title for dialogs
274
}
275
276     } // end of ModeDialog
277

278     /** Defines shared common attributes of UI element for separate mode. */
279     public interface SharedModeUIBase extends ModeComponent, TopComponentDroppable {
280     }
281
282     /** Defines base of UI element for separate mode, containing extras
283      * in which JDialog and JFrame separate mode differs
284      */

285     public interface ModeUIBase extends ModeComponent, TopComponentDroppable {
286         public void updateTitle (String JavaDoc title);
287     }
288
289     /** Base impl of separate UI element, used as delegatee for shared things.
290      */

291     private static class SharedModeUIBaseImpl implements SharedModeUIBase {
292         
293         private final AbstractModeContainer abstractModeContainer;
294         private final ModeView modeView;
295         private long frametimestamp = 0;
296
297         /** UI representation of separate window */
298         private Window window;
299         
300         public SharedModeUIBaseImpl (AbstractModeContainer abstractModeContainer, ModeView view, Window window) {
301             this.abstractModeContainer = abstractModeContainer;
302             this.modeView = view;
303             this.window = window;
304             initWindow(window);
305             attachListeners(window);
306         }
307
308         /** Creates and returns window appropriate for type of dragged TC;
309          * either frame or dialog.
310          */

311         private void initWindow (Window w) {
312             // mark this as separate window, so that ShortcutAndMenuKeyEventProcessor
313
// allows normal shorcut processing like inside main window
314
((RootPaneContainer)w).getRootPane().putClientProperty(
315                     Constants.SEPARATE_WINDOW_PROPERTY, Boolean.TRUE);
316
317             // register in z-order mng
318
ZOrderManager.getInstance().attachWindow((RootPaneContainer)w);
319         }
320
321         private void attachListeners (Window w) {
322             w.addWindowListener(new WindowAdapter() {
323                 public void windowClosing(WindowEvent evt) {
324                     modeView.getController().userClosingMode(modeView);
325                     ZOrderManager.getInstance().detachWindow((RootPaneContainer)window);
326                 }
327
328                 public void windowClosed (WindowEvent evt) {
329                     ZOrderManager.getInstance().detachWindow((RootPaneContainer)window);
330                 }
331
332                 public void windowActivated(WindowEvent event) {
333                     if (frametimestamp != 0 && System.currentTimeMillis() > frametimestamp + 500) {
334                         modeView.getController().userActivatedModeWindow(modeView);
335                     }
336                     frametimestamp = System.currentTimeMillis();
337                 }
338                 public void windowOpened(WindowEvent event) {
339                     frametimestamp = System.currentTimeMillis();
340                 }
341             }); // end of WindowListener
342

343             w.addComponentListener(new ComponentAdapter() {
344                 public void componentResized(ComponentEvent evt) {
345                     /*if(DefaultSeparateContainer.this.frame.getExtendedState() == Frame.MAXIMIZED_BOTH) {
346                         // Ignore changes when the frame is in maximized state.
347                         return;
348                     }*/

349
350                     modeView.getController().userResizedModeBounds(modeView, window.getBounds());
351                 }
352
353                 public void componentMoved(ComponentEvent evt) {
354                     /*if(DefaultSeparateContainer.this.frame.getExtendedState() == Frame.MAXIMIZED_BOTH) {
355                         // Ignore changes when the frame is in maximized state.
356                         return;
357                     }*/

358
359                     modeView.getController().userResizedModeBounds(modeView, window.getBounds());
360                 }
361
362             }); // end of ComponentListener
363

364         
365             window.addWindowStateListener(new WindowStateListener() {
366                 public void windowStateChanged(WindowEvent evt) {
367          // All the timestamping is a a workaround beause of buggy GNOME and of its kind who iconify the windows on leaving the desktop.
368
Component comp = modeView.getComponent();
369                     if (comp instanceof Frame /*&& comp.isVisible() */) {
370                         long currentStamp = System.currentTimeMillis();
371                         if (currentStamp > (modeView.getUserStamp() + 500) && currentStamp > (modeView.getMainWindowStamp() + 1000)) {
372                             modeView.getController().userChangedFrameStateMode(modeView, evt.getNewState());
373                         } else {
374                             modeView.setUserStamp(0);
375                             modeView.setMainWindowStamp(0);
376                             modeView.updateFrameState();
377                         }
378                         long stamp = System.currentTimeMillis();
379                         modeView.setUserStamp(stamp);
380                     }
381                 }
382             }); // end of WindowStateListener
383

384         }
385
386         public void setVisible(boolean visible) {
387             frametimestamp = System.currentTimeMillis();
388             window.setVisible(visible);
389         }
390         
391         public void toFront() {
392             frametimestamp = System.currentTimeMillis();
393             window.toFront();
394         }
395         
396         public ModeView getModeView() {
397             return abstractModeContainer.getModeView();
398         }
399         
400         public int getKind() {
401             return abstractModeContainer.getKind();
402         }
403
404         // TopComponentDroppable>>
405
public Shape getIndicationForLocation(Point location) {
406             return abstractModeContainer.getIndicationForLocation(location);
407         }
408         
409         public Object JavaDoc getConstraintForLocation(Point location) {
410             return abstractModeContainer.getConstraintForLocation(location);
411         }
412         
413         public Component getDropComponent() {
414             return abstractModeContainer.getDropComponent();
415         }
416         
417         public ViewElement getDropViewElement() {
418             return abstractModeContainer.getDropModeView();
419         }
420         
421         public boolean canDrop(TopComponent transfer, Point location) {
422             return abstractModeContainer.canDrop(transfer);
423         }
424         
425         public boolean supportsKind(int kind, TopComponent transfer) {
426             // this is not a typo, yes it should be the same as canDrop
427
return abstractModeContainer.canDrop(transfer);
428             //return true;
429
/*
430              if(Constants.SWITCH_MODE_ADD_NO_RESTRICT
431             || WindowManagerImpl.getInstance().isTopComponentAllowedToMoveAnywhere(transfer)) {
432                 return true;
433             }
434
435             return kind == Constants.MODE_KIND_VIEW || kind == Constants.MODE_KIND_SLIDING;
436              */

437         }
438         // TopComponentDroppable<<
439

440
441     } // End of ModeWindow.
442

443 }
444
445
Popular Tags