Lines 52-58
Link Here
|
52 |
import org.netbeans.core.windows.Constants; |
52 |
import org.netbeans.core.windows.Constants; |
53 |
import org.netbeans.core.windows.Debug; |
53 |
import org.netbeans.core.windows.Debug; |
54 |
import org.netbeans.core.windows.WindowManagerImpl; |
54 |
import org.netbeans.core.windows.WindowManagerImpl; |
55 |
import org.netbeans.core.windows.view.ui.Tabbed; |
55 |
import org.netbeans.swing.tabcontrol.customtabs.Tabbed; |
56 |
import org.netbeans.swing.tabcontrol.ComponentConverter; |
56 |
import org.netbeans.swing.tabcontrol.ComponentConverter; |
57 |
import org.netbeans.swing.tabcontrol.TabData; |
57 |
import org.netbeans.swing.tabcontrol.TabData; |
58 |
import org.netbeans.swing.tabcontrol.TabbedContainer; |
58 |
import org.netbeans.swing.tabcontrol.TabbedContainer; |
Lines 64-75
Link Here
|
64 |
import javax.swing.event.ChangeEvent; |
64 |
import javax.swing.event.ChangeEvent; |
65 |
import javax.swing.event.ChangeListener; |
65 |
import javax.swing.event.ChangeListener; |
66 |
import java.awt.*; |
66 |
import java.awt.*; |
67 |
import java.util.ArrayList; |
67 |
import java.awt.event.ActionListener; |
68 |
import java.util.Arrays; |
68 |
import java.util.Arrays; |
69 |
import org.netbeans.core.windows.ModeImpl; |
69 |
import org.netbeans.core.windows.ModeImpl; |
70 |
import org.netbeans.core.windows.Switches; |
70 |
import org.netbeans.core.windows.Switches; |
71 |
import org.netbeans.core.windows.actions.ActionUtils; |
71 |
import org.netbeans.core.windows.actions.ActionUtils; |
72 |
import org.netbeans.core.windows.view.dnd.TopComponentDraggable; |
|
|
73 |
import org.netbeans.swing.tabcontrol.TabDisplayer; |
72 |
import org.netbeans.swing.tabcontrol.TabDisplayer; |
74 |
import org.netbeans.swing.tabcontrol.WinsysInfoForTabbedContainer; |
73 |
import org.netbeans.swing.tabcontrol.WinsysInfoForTabbedContainer; |
75 |
import org.netbeans.swing.tabcontrol.event.TabActionEvent; |
74 |
import org.netbeans.swing.tabcontrol.event.TabActionEvent; |
Lines 81-87
Link Here
|
81 |
* |
80 |
* |
82 |
* @author Tim Boudreau |
81 |
* @author Tim Boudreau |
83 |
*/ |
82 |
*/ |
84 |
public class TabbedAdapter extends TabbedContainer implements Tabbed, Tabbed.Accessor, SlideController { |
83 |
public class TabbedAdapter extends TabbedContainer implements Tabbed.Accessor, SlideController { |
85 |
|
84 |
|
86 |
public static final int DOCUMENT = 1; |
85 |
public static final int DOCUMENT = 1; |
87 |
|
86 |
|
Lines 93-100
Link Here
|
93 |
private PropertyChangeListener tooltipListener, weakTooltipListener; |
92 |
private PropertyChangeListener tooltipListener, weakTooltipListener; |
94 |
|
93 |
|
95 |
/** Creates a new instance of TabbedAdapter */ |
94 |
/** Creates a new instance of TabbedAdapter */ |
96 |
public TabbedAdapter (int type) { |
95 |
public TabbedAdapter (int type, WinsysInfoForTabbedContainer winsysInfo) { |
97 |
super (null, type, new WinsysInfo(type)); |
96 |
super (null, type, winsysInfo); |
98 |
getSelectionModel().addChangeListener(new ChangeListener() { |
97 |
getSelectionModel().addChangeListener(new ChangeListener() { |
99 |
@Override |
98 |
@Override |
100 |
public void stateChanged (ChangeEvent ce) { |
99 |
public void stateChanged (ChangeEvent ce) { |
Lines 104-114
Link Here
|
104 |
} |
103 |
} |
105 |
} |
104 |
} |
106 |
}); |
105 |
}); |
107 |
// Color fillC = (Color)UIManager.get("nb_workplace_fill"); //NOI18N |
|
|
108 |
// if (fillC != null) setBackground (fillC); |
109 |
} |
106 |
} |
110 |
|
107 |
|
|
|
108 |
|
109 |
public void addComponents(Component[] comps, String[] names, javax.swing.Icon[] icons, String[] tips) { |
110 |
TabData[] data = new TabData[comps.length]; |
111 |
for (int i=0; i < comps.length; i++) { |
112 |
TabData td = new TabData (comps[i], icons[i], names[i], tips[i]); |
113 |
data[i] = td; |
114 |
comps[i].addPropertyChangeListener(JComponent.TOOL_TIP_TEXT_KEY, getTooltipListener(comps[i])); |
115 |
} |
116 |
getModel().addTabs (0, data); |
117 |
} |
118 |
|
119 |
|
120 |
/** Removes tooltip listeners from given tabs */ |
121 |
private void detachTooltipListeners(List tabs) { |
122 |
JComponent curComp; |
123 |
for (Iterator iter = tabs.iterator(); iter.hasNext(); ) { |
124 |
curComp = (JComponent)((TabData)iter.next()).getComponent(); |
125 |
curComp.removePropertyChangeListener(JComponent.TOOL_TIP_TEXT_KEY, |
126 |
getTooltipListener(curComp)); |
127 |
} |
128 |
} |
129 |
|
130 |
|
131 |
private String getSideForLocation(Point location) { |
132 |
Rectangle bounds = getBounds(); |
133 |
bounds.setLocation(0, 0); |
134 |
|
135 |
final int TOP_HEIGHT = 10; |
136 |
final int BOTTOM_HEIGHT = (int)(0.25 * bounds.height); |
137 |
|
138 |
final int LEFT_WIDTH = Math.max (getWidth() / 8, 40); |
139 |
final int RIGHT_WIDTH = LEFT_WIDTH; |
140 |
|
141 |
if(DEBUG) { |
142 |
debugLog(""); // NOI18N |
143 |
debugLog("TOP_HEIGHT =" + TOP_HEIGHT); // NOI18N |
144 |
debugLog("BOTTOM_HEIGHT =" + BOTTOM_HEIGHT); // NOI18N |
145 |
debugLog("LEFT_WIDTH =" + LEFT_WIDTH); // NOI18N |
146 |
debugLog("RIGHT_WIDTH =" + RIGHT_WIDTH); // NOI18N |
147 |
} |
148 |
|
149 |
// Size of area which indicates creation of new split. |
150 |
// int delta = Constants.DROP_AREA_SIZE; |
151 |
Rectangle top = new Rectangle(0, 0, bounds.width, BOTTOM_HEIGHT); |
152 |
if(top.contains(location)) { |
153 |
return Constants.TOP; |
154 |
} |
155 |
|
156 |
Polygon left = new EqualPolygon( |
157 |
new int[] {0, LEFT_WIDTH, LEFT_WIDTH, 0}, |
158 |
new int[] {TOP_HEIGHT, TOP_HEIGHT, bounds.height - BOTTOM_HEIGHT, bounds.height}, |
159 |
4 |
160 |
); |
161 |
if(left.contains(location)) { |
162 |
return Constants.LEFT; |
163 |
} |
164 |
|
165 |
Polygon right = new EqualPolygon( |
166 |
new int[] {bounds.width - RIGHT_WIDTH, bounds.width, bounds.width, bounds.width - RIGHT_WIDTH}, |
167 |
new int[] {TOP_HEIGHT, TOP_HEIGHT, bounds.height, bounds.height - BOTTOM_HEIGHT}, |
168 |
4 |
169 |
); |
170 |
if(right.contains(location)) { |
171 |
return Constants.RIGHT; |
172 |
} |
173 |
|
174 |
Polygon bottom = new EqualPolygon( |
175 |
new int[] {LEFT_WIDTH, bounds.width - RIGHT_WIDTH, bounds.width, 0}, |
176 |
new int[] {bounds.height - BOTTOM_HEIGHT, bounds.height - BOTTOM_HEIGHT, bounds.height, bounds.height}, |
177 |
4 |
178 |
); |
179 |
if(bottom.contains(location)) { |
180 |
return Constants.BOTTOM; |
181 |
} |
182 |
|
183 |
return null; |
184 |
} |
185 |
|
186 |
private Shape getStartingIndication(Point startingPoint, Point location) { |
187 |
Rectangle rect = getBounds(); |
188 |
rect.setLocation(location.x - startingPoint.x, location.y - startingPoint.y); |
189 |
return rect; |
190 |
} |
191 |
// DnD<< |
192 |
|
193 |
|
194 |
/** Notifies all registered listeners about the event. */ |
195 |
private void fireStateChanged() { |
196 |
if (!SwingUtilities.isEventDispatchThread()) { |
197 |
Logger.getAnonymousLogger().warning( |
198 |
"All state changes to the tab component must happen on the event thread!"); //NOI18N |
199 |
Exception e = new Exception(); |
200 |
e.fillInStackTrace(); |
201 |
Logger.getAnonymousLogger().warning(e.getStackTrace()[1].toString()); |
202 |
} |
203 |
|
204 |
//Note: Firing the events while holding the tree lock avoids many |
205 |
//gratuitous repaints that slow down switching tabs. To demonstrate this, |
206 |
//comment this code out and run the IDE with -J-Dawt.nativeDoubleBuffering=true |
207 |
//so you'll really see every repaint. When switching between a form |
208 |
//tab and an editor tab, you will see the property sheet get repainted |
209 |
//8 times due to changes in the component hierarchy, before the |
210 |
//selected node is even changed to the appropriate one for the new tab. |
211 |
//Synchronizing here ensures that never happens. |
212 |
|
213 |
// [dafe]: Firing under tree lock is bad practice and causes deadlocking, |
214 |
// see http://www.netbeans.org/issues/show_bug.cgi?id=120874 |
215 |
// Comments above seems not to be valid anymore in JDK 1.5 and |
216 |
// newer. Even if running with -J-Dawt.nativeDoubleBuffering=true, there |
217 |
// is no difference in number of repaints no matter if holding the tree |
218 |
// lock or not. Repeated redrawing seems to be coalesced well, so removing |
219 |
// AWT tree lock |
220 |
|
221 |
cs.fireChange(); |
222 |
} |
223 |
|
224 |
private static void debugLog(String message) { |
225 |
Debug.log(TabbedAdapter.class, message); |
226 |
} |
227 |
|
228 |
private ModeImpl getModeImpl() { |
229 |
TopComponent[] topComponents = tabbedImpl.getTopComponents(); |
230 |
if( topComponents.length < 1 ) |
231 |
return null; |
232 |
return ( ModeImpl ) WindowManagerImpl.getInstance().findMode( topComponents[0] ); |
233 |
} |
234 |
|
235 |
/** Finds out in what state is window system mode containing given component. |
236 |
* |
237 |
* @return true if given component is inside mode which is in maximized state, |
238 |
* false otherwise |
239 |
*/ |
240 |
public static boolean isInMaximizedMode (Component comp) { |
241 |
ModeImpl maxMode = WindowManagerImpl.getInstance().getCurrentMaximizedMode(); |
242 |
if (maxMode == null) { |
243 |
return false; |
244 |
} |
245 |
return maxMode.containsTopComponent((TopComponent)comp); |
246 |
} |
247 |
|
248 |
/********** implementation of SlideController *****************/ |
249 |
|
111 |
@Override |
250 |
@Override |
|
|
251 |
public void userToggledAutoHide(int tabIndex, boolean enabled) { |
252 |
postActionEvent(new TabActionEvent(this, TabbedContainer.COMMAND_ENABLE_AUTO_HIDE, tabIndex)); |
253 |
} |
254 |
|
255 |
@Override |
256 |
public void userToggledTransparency(int tabIndex) { |
257 |
postActionEvent(new TabActionEvent(this, TabbedContainer.COMMAND_TOGGLE_TRANSPARENCY, tabIndex)); |
258 |
} |
259 |
|
260 |
/********* implementation of Tabbed.Accessor **************/ |
261 |
|
262 |
@Override |
263 |
public Tabbed getTabbed() { |
264 |
return tabbedImpl; |
265 |
} |
266 |
|
267 |
/********* implementation of WinsysInfoForTabbed ********/ |
268 |
|
269 |
public static class WinsysInfo extends WinsysInfoForTabbedContainer { |
270 |
private int containerType; |
271 |
public WinsysInfo( int containerType ) { |
272 |
this.containerType = containerType; |
273 |
} |
274 |
|
275 |
@Override |
276 |
public Object getOrientation (Component comp) { |
277 |
WindowManagerImpl wmi = WindowManagerImpl.getInstance(); |
278 |
// don't show pin button in separate views |
279 |
if (!wmi.isDocked((TopComponent)comp)) { |
280 |
return TabDisplayer.ORIENTATION_INVISIBLE; |
281 |
} |
282 |
|
283 |
String side = wmi.guessSlideSide((TopComponent)comp); |
284 |
Object result = null; |
285 |
if (side.equals(Constants.LEFT)) { |
286 |
result = TabDisplayer.ORIENTATION_WEST; |
287 |
} else if (side.equals(Constants.RIGHT)) { |
288 |
result = TabDisplayer.ORIENTATION_EAST; |
289 |
} else if (side.equals(Constants.BOTTOM)) { |
290 |
result = TabDisplayer.ORIENTATION_SOUTH; |
291 |
} else if (side.equals(Constants.TOP)) { |
292 |
result = TabDisplayer.ORIENTATION_NORTH; |
293 |
} else { |
294 |
result = TabDisplayer.ORIENTATION_CENTER; |
295 |
} |
296 |
return result; |
297 |
} |
298 |
|
299 |
@Override |
300 |
public boolean inMaximizedMode (Component comp) { |
301 |
return isInMaximizedMode(comp); |
302 |
} |
303 |
|
304 |
@Override |
305 |
public boolean isTopComponentSlidingEnabled() { |
306 |
return Switches.isTopComponentSlidingEnabled(); |
307 |
} |
308 |
|
309 |
@Override |
310 |
public boolean isTopComponentClosingEnabled() { |
311 |
if( containerType == Constants.MODE_KIND_EDITOR ) |
312 |
return Switches.isEditorTopComponentClosingEnabled(); |
313 |
else |
314 |
return Switches.isViewTopComponentClosingEnabled(); |
315 |
} |
316 |
|
317 |
@Override |
318 |
public boolean isTopComponentMaximizationEnabled() { |
319 |
return Switches.isTopComponentMaximizationEnabled(); |
320 |
} |
321 |
|
322 |
@Override |
323 |
public boolean isTopComponentClosingEnabled(TopComponent tc) { |
324 |
return !Boolean.TRUE.equals(tc.getClientProperty(TopComponent.PROP_CLOSING_DISABLED)) |
325 |
&& isTopComponentClosingEnabled(); |
326 |
} |
327 |
|
328 |
@Override |
329 |
public boolean isTopComponentMaximizationEnabled(TopComponent tc) { |
330 |
return !Boolean.TRUE.equals(tc.getClientProperty(TopComponent.PROP_MAXIMIZATION_DISABLED)) |
331 |
&& isTopComponentMaximizationEnabled(); |
332 |
} |
333 |
|
334 |
@Override |
335 |
public boolean isTopComponentSlidingEnabled(TopComponent tc) { |
336 |
return !Boolean.TRUE.equals(tc.getClientProperty(TopComponent.PROP_SLIDING_DISABLED)) |
337 |
&& isTopComponentSlidingEnabled(); |
338 |
} |
339 |
|
340 |
@Override |
341 |
public boolean isModeSlidingEnabled() { |
342 |
return Switches.isModeSlidingEnabled(); |
343 |
} |
344 |
} // end of LocInfo |
345 |
|
346 |
/** Returns instance of weak property change listener used to listen to |
347 |
* tooltip changes. Weak listener is needed, in some situations (close of |
348 |
* whole mode), our class is not notified from winsys. |
349 |
*/ |
350 |
private PropertyChangeListener getTooltipListener(Component comp) { |
351 |
if (tooltipListener == null) { |
352 |
tooltipListener = new ToolTipListener(); |
353 |
weakTooltipListener = WeakListeners.propertyChange(tooltipListener, comp); |
354 |
} |
355 |
return weakTooltipListener; |
356 |
} |
357 |
|
358 |
private final Tabbed tabbedImpl = new Tabbed() { |
359 |
|
360 |
@Override |
112 |
public void addTopComponent(String name, javax.swing.Icon icon, TopComponent tc, String toolTip) { |
361 |
public void addTopComponent(String name, javax.swing.Icon icon, TopComponent tc, String toolTip) { |
113 |
insertComponent (name, icon, tc, toolTip, getTabCount()); |
362 |
insertComponent (name, icon, tc, toolTip, getTabCount()); |
114 |
} |
363 |
} |
Lines 131-137
Link Here
|
131 |
public void requestAttention (TopComponent tc) { |
380 |
public void requestAttention (TopComponent tc) { |
132 |
int idx = indexOf(tc); |
381 |
int idx = indexOf(tc); |
133 |
if (idx >= 0) { |
382 |
if (idx >= 0) { |
134 |
requestAttention(idx); |
383 |
TabbedAdapter.this.requestAttention(idx); |
135 |
} else { |
384 |
} else { |
136 |
Logger.getAnonymousLogger().fine( |
385 |
Logger.getAnonymousLogger().fine( |
137 |
"RequestAttention on component unknown to container: " + tc); //NOI18N |
386 |
"RequestAttention on component unknown to container: " + tc); //NOI18N |
Lines 142-148
Link Here
|
142 |
public void cancelRequestAttention (TopComponent tc) { |
391 |
public void cancelRequestAttention (TopComponent tc) { |
143 |
int idx = indexOf(tc); |
392 |
int idx = indexOf(tc); |
144 |
if (idx >= 0) { |
393 |
if (idx >= 0) { |
145 |
cancelRequestAttention(idx); |
394 |
TabbedAdapter.this.cancelRequestAttention(idx); |
146 |
} else { |
395 |
} else { |
147 |
throw new IllegalArgumentException ("TopComponent " + tc |
396 |
throw new IllegalArgumentException ("TopComponent " + tc |
148 |
+ " is not a child of this container"); //NOI18N |
397 |
+ " is not a child of this container"); //NOI18N |
Lines 194-208
Link Here
|
194 |
} |
443 |
} |
195 |
} |
444 |
} |
196 |
|
445 |
|
197 |
public void addComponents(Component[] comps, String[] names, javax.swing.Icon[] icons, String[] tips) { |
446 |
@Override |
198 |
ArrayList al = new ArrayList (comps.length); |
447 |
public Rectangle getTabBounds(int tabIndex) { |
199 |
TabData[] data = new TabData[comps.length]; |
448 |
return getTabRect(tabIndex, new Rectangle()); |
200 |
for (int i=0; i < comps.length; i++) { |
|
|
201 |
TabData td = new TabData (comps[i], icons[i], names[i], tips[i]); |
202 |
data[i] = td; |
203 |
comps[i].addPropertyChangeListener(JComponent.TOOL_TIP_TEXT_KEY, getTooltipListener(comps[i])); |
204 |
} |
449 |
} |
205 |
getModel().addTabs (0, data); |
450 |
|
|
|
451 |
@Override |
452 |
public Rectangle getTabsArea() { |
453 |
return getUI().getTabsArea(); |
206 |
} |
454 |
} |
207 |
|
455 |
|
208 |
@Override |
456 |
@Override |
Lines 264-280
Link Here
|
264 |
repaint(); |
512 |
repaint(); |
265 |
} |
513 |
} |
266 |
} |
514 |
} |
267 |
|
|
|
268 |
/** Removes tooltip listeners from given tabs */ |
269 |
private void detachTooltipListeners(List tabs) { |
270 |
JComponent curComp; |
271 |
for (Iterator iter = tabs.iterator(); iter.hasNext(); ) { |
272 |
curComp = (JComponent)((TabData)iter.next()).getComponent(); |
273 |
curComp.removePropertyChangeListener(JComponent.TOOL_TIP_TEXT_KEY, |
274 |
getTooltipListener(curComp)); |
275 |
} |
276 |
} |
277 |
|
278 |
// DnD>> |
515 |
// DnD>> |
279 |
/** Finds tab which contains x coordinate of given location point. |
516 |
/** Finds tab which contains x coordinate of given location point. |
280 |
* @param location The point for which a constraint is required |
517 |
* @param location The point for which a constraint is required |
Lines 308-319
Link Here
|
308 |
*/ |
545 |
*/ |
309 |
@Override |
546 |
@Override |
310 |
public Shape getIndicationForLocation(Point location, |
547 |
public Shape getIndicationForLocation(Point location, |
311 |
TopComponentDraggable startingTransfer, Point startingPoint, boolean attachingPossible) { |
548 |
TopComponent startingTransfer, Point startingPoint, boolean attachingPossible) { |
312 |
|
549 |
|
313 |
Rectangle rect = getBounds(); |
550 |
Rectangle rect = getBounds(); |
314 |
rect.setLocation(0, 0); |
551 |
rect.setLocation(0, 0); |
315 |
|
552 |
|
316 |
TopComponent draggedTC = startingTransfer.getTopComponent(); |
553 |
TopComponent draggedTC = startingTransfer; |
317 |
//#47909 |
554 |
//#47909 |
318 |
int tab = tabForCoordinate(location); |
555 |
int tab = tabForCoordinate(location); |
319 |
// first process the tabs when mouse is inside the tabs area.. |
556 |
// first process the tabs when mouse is inside the tabs area.. |
Lines 349-425
Link Here
|
349 |
return s; |
586 |
return s; |
350 |
} |
587 |
} |
351 |
|
588 |
|
352 |
if( startingTransfer.isTopComponentTransfer() && startingPoint != null |
589 |
if( null != startingTransfer && startingPoint != null |
353 |
&& indexOf(startingTransfer.getTopComponent()) != -1) { |
590 |
&& indexOf(startingTransfer) != -1) { |
354 |
return getStartingIndication(startingPoint, location); |
591 |
return getStartingIndication(startingPoint, location); |
355 |
} |
592 |
} |
356 |
|
593 |
|
357 |
return rect; |
594 |
return rect; |
358 |
} |
595 |
} |
359 |
|
596 |
|
360 |
private String getSideForLocation(Point location) { |
597 |
@Override |
361 |
Rectangle bounds = getBounds(); |
598 |
public Component getComponent() { |
362 |
bounds.setLocation(0, 0); |
599 |
return TabbedAdapter.this; |
363 |
|
|
|
364 |
final int TOP_HEIGHT = 10; |
365 |
final int BOTTOM_HEIGHT = (int)(0.25 * bounds.height); |
366 |
|
367 |
final int LEFT_WIDTH = Math.max (getWidth() / 8, 40); |
368 |
final int RIGHT_WIDTH = LEFT_WIDTH; |
369 |
|
370 |
if(DEBUG) { |
371 |
debugLog(""); // NOI18N |
372 |
debugLog("TOP_HEIGHT =" + TOP_HEIGHT); // NOI18N |
373 |
debugLog("BOTTOM_HEIGHT =" + BOTTOM_HEIGHT); // NOI18N |
374 |
debugLog("LEFT_WIDTH =" + LEFT_WIDTH); // NOI18N |
375 |
debugLog("RIGHT_WIDTH =" + RIGHT_WIDTH); // NOI18N |
376 |
} |
600 |
} |
377 |
|
601 |
|
378 |
// Size of area which indicates creation of new split. |
602 |
/** Add action for enabling auto hide of views */ |
379 |
// int delta = Constants.DROP_AREA_SIZE; |
603 |
@Override |
380 |
Rectangle top = new Rectangle(0, 0, bounds.width, BOTTOM_HEIGHT); |
604 |
public Action[] getPopupActions(Action[] defaultActions, int tabIndex) { |
381 |
if(top.contains(location)) { |
605 |
if( tabIndex < 0 ) { |
382 |
return Constants.TOP; |
606 |
ModeImpl mode = getModeImpl(); |
383 |
} |
607 |
if( null != mode ) |
384 |
|
608 |
return ActionUtils.createDefaultPopupActions( mode ); |
385 |
Polygon left = new EqualPolygon( |
|
|
386 |
new int[] {0, LEFT_WIDTH, LEFT_WIDTH, 0}, |
387 |
new int[] {TOP_HEIGHT, TOP_HEIGHT, bounds.height - BOTTOM_HEIGHT, bounds.height}, |
388 |
4 |
389 |
); |
390 |
if(left.contains(location)) { |
391 |
return Constants.LEFT; |
392 |
} |
393 |
|
394 |
Polygon right = new EqualPolygon( |
395 |
new int[] {bounds.width - RIGHT_WIDTH, bounds.width, bounds.width, bounds.width - RIGHT_WIDTH}, |
396 |
new int[] {TOP_HEIGHT, TOP_HEIGHT, bounds.height, bounds.height - BOTTOM_HEIGHT}, |
397 |
4 |
398 |
); |
399 |
if(right.contains(location)) { |
400 |
return Constants.RIGHT; |
401 |
} |
402 |
|
403 |
Polygon bottom = new EqualPolygon( |
404 |
new int[] {LEFT_WIDTH, bounds.width - RIGHT_WIDTH, bounds.width, 0}, |
405 |
new int[] {bounds.height - BOTTOM_HEIGHT, bounds.height - BOTTOM_HEIGHT, bounds.height, bounds.height}, |
406 |
4 |
407 |
); |
408 |
if(bottom.contains(location)) { |
409 |
return Constants.BOTTOM; |
410 |
} |
411 |
|
412 |
return null; |
609 |
return null; |
413 |
} |
610 |
} |
414 |
|
611 |
return defaultActions; |
415 |
private Shape getStartingIndication(Point startingPoint, Point location) { |
|
|
416 |
Rectangle rect = getBounds(); |
417 |
rect.setLocation(location.x - startingPoint.x, location.y - startingPoint.y); |
418 |
return rect; |
419 |
} |
612 |
} |
420 |
// DnD<< |
|
|
421 |
|
613 |
|
422 |
|
|
|
423 |
/** Registers ChangeListener to receive events. |
614 |
/** Registers ChangeListener to receive events. |
424 |
* @param listener The listener to register. |
615 |
* @param listener The listener to register. |
425 |
* |
616 |
* |
Lines 438-634
Link Here
|
438 |
cs.removeChangeListener(listener); |
629 |
cs.removeChangeListener(listener); |
439 |
} |
630 |
} |
440 |
|
631 |
|
441 |
/** Notifies all registered listeners about the event. */ |
|
|
442 |
private void fireStateChanged() { |
443 |
if (!SwingUtilities.isEventDispatchThread()) { |
444 |
Logger.getAnonymousLogger().warning( |
445 |
"All state changes to the tab component must happen on the event thread!"); //NOI18N |
446 |
Exception e = new Exception(); |
447 |
e.fillInStackTrace(); |
448 |
Logger.getAnonymousLogger().warning(e.getStackTrace()[1].toString()); |
449 |
} |
450 |
|
451 |
//Note: Firing the events while holding the tree lock avoids many |
452 |
//gratuitous repaints that slow down switching tabs. To demonstrate this, |
453 |
//comment this code out and run the IDE with -J-Dawt.nativeDoubleBuffering=true |
454 |
//so you'll really see every repaint. When switching between a form |
455 |
//tab and an editor tab, you will see the property sheet get repainted |
456 |
//8 times due to changes in the component hierarchy, before the |
457 |
//selected node is even changed to the appropriate one for the new tab. |
458 |
//Synchronizing here ensures that never happens. |
459 |
|
460 |
// [dafe]: Firing under tree lock is bad practice and causes deadlocking, |
461 |
// see http://www.netbeans.org/issues/show_bug.cgi?id=120874 |
462 |
// Comments above seems not to be valid anymore in JDK 1.5 and |
463 |
// newer. Even if running with -J-Dawt.nativeDoubleBuffering=true, there |
464 |
// is no difference in number of repaints no matter if holding the tree |
465 |
// lock or not. Repeated redrawing seems to be coalesced well, so removing |
466 |
// AWT tree lock |
467 |
|
468 |
cs.fireChange(); |
469 |
} |
470 |
|
471 |
private static void debugLog(String message) { |
472 |
Debug.log(TabbedAdapter.class, message); |
473 |
} |
474 |
|
475 |
@Override |
632 |
@Override |
476 |
public Component getComponent() { |
633 |
public int getTabCount() { |
477 |
return this; |
634 |
return TabbedAdapter.this.getTabCount(); |
478 |
} |
635 |
} |
479 |
|
636 |
|
480 |
/** Add action for enabling auto hide of views */ |
|
|
481 |
@Override |
637 |
@Override |
482 |
public Action[] getPopupActions(Action[] defaultActions, int tabIndex) { |
638 |
public int indexOf( Component tc ) { |
483 |
if( tabIndex < 0 ) { |
639 |
return TabbedAdapter.this.indexOf( tc ); |
484 |
ModeImpl mode = getModeImpl(); |
|
|
485 |
if( null != mode ) |
486 |
return ActionUtils.createDefaultPopupActions( mode ); |
487 |
return null; |
488 |
} |
640 |
} |
489 |
return defaultActions; |
|
|
490 |
} |
491 |
|
641 |
|
492 |
private ModeImpl getModeImpl() { |
|
|
493 |
TopComponent[] topComponents = getTopComponents(); |
494 |
if( topComponents.length < 1 ) |
495 |
return null; |
496 |
return ( ModeImpl ) WindowManagerImpl.getInstance().findMode( topComponents[0] ); |
497 |
} |
498 |
|
499 |
/** Finds out in what state is window system mode containing given component. |
500 |
* |
501 |
* @return true if given component is inside mode which is in maximized state, |
502 |
* false otherwise |
503 |
*/ |
504 |
public static boolean isInMaximizedMode (Component comp) { |
505 |
ModeImpl maxMode = WindowManagerImpl.getInstance().getCurrentMaximizedMode(); |
506 |
if (maxMode == null) { |
507 |
return false; |
508 |
} |
509 |
return maxMode.containsTopComponent((TopComponent)comp); |
510 |
} |
511 |
|
512 |
/********** implementation of SlideController *****************/ |
513 |
|
514 |
@Override |
642 |
@Override |
515 |
public void userToggledAutoHide(int tabIndex, boolean enabled) { |
643 |
public void setTitleAt( int index, String title ) { |
516 |
postActionEvent(new TabActionEvent(this, TabbedContainer.COMMAND_ENABLE_AUTO_HIDE, tabIndex)); |
644 |
TabbedAdapter.this.setTitleAt( index, title ); |
517 |
} |
645 |
} |
518 |
|
646 |
|
519 |
@Override |
647 |
@Override |
520 |
public void userToggledTransparency(int tabIndex) { |
648 |
public void setIconAt( int index, Icon icon ) { |
521 |
postActionEvent(new TabActionEvent(this, TabbedContainer.COMMAND_TOGGLE_TRANSPARENCY, tabIndex)); |
649 |
TabbedAdapter.this.setIconAt( index, icon ); |
522 |
} |
650 |
} |
523 |
|
651 |
|
524 |
/********* implementation of Tabbed.Accessor **************/ |
|
|
525 |
|
526 |
@Override |
652 |
@Override |
527 |
public Tabbed getTabbed() { |
653 |
public void setToolTipTextAt( int index, String toolTip ) { |
528 |
return this; |
654 |
TabbedAdapter.this.setToolTipTextAt( index, toolTip ); |
529 |
} |
655 |
} |
530 |
|
656 |
|
531 |
@Override |
657 |
@Override |
532 |
public Rectangle getTabBounds(int tabIndex) { |
658 |
public void addActionListener( ActionListener al ) { |
533 |
return getTabRect(tabIndex, new Rectangle()); |
659 |
TabbedAdapter.this.addActionListener( al ); |
534 |
} |
660 |
} |
535 |
|
661 |
|
536 |
@Override |
662 |
@Override |
537 |
public Rectangle getTabsArea() { |
663 |
public void removeActionListener( ActionListener al ) { |
538 |
return getUI().getTabsArea(); |
664 |
TabbedAdapter.this.removeActionListener( al ); |
539 |
} |
665 |
} |
540 |
|
666 |
|
541 |
/********* implementation of WinsysInfoForTabbed ********/ |
|
|
542 |
|
543 |
static class WinsysInfo extends WinsysInfoForTabbedContainer { |
544 |
private int containerType; |
545 |
public WinsysInfo( int containerType ) { |
546 |
this.containerType = containerType; |
547 |
} |
548 |
|
549 |
@Override |
667 |
@Override |
550 |
public Object getOrientation (Component comp) { |
668 |
public void setActive( boolean active ) { |
551 |
WindowManagerImpl wmi = WindowManagerImpl.getInstance(); |
669 |
TabbedAdapter.this.setActive( active ); |
552 |
// don't show pin button in separate views |
|
|
553 |
if (!wmi.isDocked((TopComponent)comp)) { |
554 |
return TabDisplayer.ORIENTATION_INVISIBLE; |
555 |
} |
670 |
} |
556 |
|
671 |
|
557 |
String side = wmi.guessSlideSide((TopComponent)comp); |
|
|
558 |
Object result = null; |
559 |
if (side.equals(Constants.LEFT)) { |
560 |
result = TabDisplayer.ORIENTATION_WEST; |
561 |
} else if (side.equals(Constants.RIGHT)) { |
562 |
result = TabDisplayer.ORIENTATION_EAST; |
563 |
} else if (side.equals(Constants.BOTTOM)) { |
564 |
result = TabDisplayer.ORIENTATION_SOUTH; |
565 |
} else if (side.equals(Constants.TOP)) { |
566 |
result = TabDisplayer.ORIENTATION_NORTH; |
567 |
} else { |
568 |
result = TabDisplayer.ORIENTATION_CENTER; |
569 |
} |
570 |
return result; |
571 |
} |
572 |
|
573 |
@Override |
672 |
@Override |
574 |
public boolean inMaximizedMode (Component comp) { |
673 |
public int tabForCoordinate( Point p ) { |
575 |
return isInMaximizedMode(comp); |
674 |
return TabbedAdapter.this.tabForCoordinate( p ); |
576 |
} |
675 |
} |
577 |
|
676 |
|
578 |
@Override |
677 |
@Override |
579 |
public boolean isTopComponentSlidingEnabled() { |
678 |
public Image createImageOfTab( int tabIndex ) { |
580 |
return Switches.isTopComponentSlidingEnabled(); |
679 |
return TabbedAdapter.this.createImageOfTab( tabIndex ); |
581 |
} |
680 |
} |
582 |
|
681 |
|
583 |
@Override |
682 |
@Override |
584 |
public boolean isTopComponentClosingEnabled() { |
683 |
public boolean isTransparent() { |
585 |
if( containerType == Constants.MODE_KIND_EDITOR ) |
684 |
return TabbedAdapter.this.isTransparent(); |
586 |
return Switches.isEditorTopComponentClosingEnabled(); |
|
|
587 |
else |
588 |
return Switches.isViewTopComponentClosingEnabled(); |
589 |
} |
685 |
} |
590 |
|
686 |
|
591 |
@Override |
687 |
@Override |
592 |
public boolean isTopComponentMaximizationEnabled() { |
688 |
public void setTransparent( boolean transparent ) { |
593 |
return Switches.isTopComponentMaximizationEnabled(); |
689 |
TabbedAdapter.this.setTransparent( transparent ); |
594 |
} |
690 |
} |
595 |
|
691 |
|
596 |
@Override |
692 |
}; |
597 |
public boolean isTopComponentClosingEnabled(TopComponent tc) { |
|
|
598 |
return !Boolean.TRUE.equals(tc.getClientProperty(TopComponent.PROP_CLOSING_DISABLED)) |
599 |
&& isTopComponentClosingEnabled(); |
600 |
} |
601 |
|
693 |
|
602 |
@Override |
|
|
603 |
public boolean isTopComponentMaximizationEnabled(TopComponent tc) { |
604 |
return !Boolean.TRUE.equals(tc.getClientProperty(TopComponent.PROP_MAXIMIZATION_DISABLED)) |
605 |
&& isTopComponentMaximizationEnabled(); |
606 |
} |
607 |
|
608 |
@Override |
609 |
public boolean isTopComponentSlidingEnabled(TopComponent tc) { |
610 |
return !Boolean.TRUE.equals(tc.getClientProperty(TopComponent.PROP_SLIDING_DISABLED)) |
611 |
&& isTopComponentSlidingEnabled(); |
612 |
} |
613 |
|
614 |
@Override |
615 |
public boolean isModeSlidingEnabled() { |
616 |
return Switches.isModeSlidingEnabled(); |
617 |
} |
618 |
} // end of LocInfo |
619 |
|
620 |
/** Returns instance of weak property change listener used to listen to |
621 |
* tooltip changes. Weak listener is needed, in some situations (close of |
622 |
* whole mode), our class is not notified from winsys. |
623 |
*/ |
624 |
private PropertyChangeListener getTooltipListener(Component comp) { |
625 |
if (tooltipListener == null) { |
626 |
tooltipListener = new ToolTipListener(); |
627 |
weakTooltipListener = WeakListeners.propertyChange(tooltipListener, comp); |
628 |
} |
629 |
return weakTooltipListener; |
630 |
} |
631 |
|
632 |
/** Listening to changes of tooltips of currently asociated top components */ |
694 |
/** Listening to changes of tooltips of currently asociated top components */ |
633 |
private class ToolTipListener implements PropertyChangeListener { |
695 |
private class ToolTipListener implements PropertyChangeListener { |
634 |
|
696 |
|