This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 253699
Collapse All | Expand All

(-)a/o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/plaf/DefaultTabbedContainerUI.java (-426 / +586 lines)
Lines 43-49 Link Here
43
 */
43
 */
44
44
45
package org.netbeans.swing.tabcontrol.plaf;
45
package org.netbeans.swing.tabcontrol.plaf;
46
47
import java.awt.AlphaComposite;
46
import java.awt.AlphaComposite;
48
import java.awt.BorderLayout;
47
import java.awt.BorderLayout;
49
import java.awt.Component;
48
import java.awt.Component;
Lines 97-204 Link Here
97
import org.netbeans.swing.tabcontrol.event.ComplexListDataListener;
96
import org.netbeans.swing.tabcontrol.event.ComplexListDataListener;
98
import org.netbeans.swing.tabcontrol.event.TabActionEvent;
97
import org.netbeans.swing.tabcontrol.event.TabActionEvent;
99
import org.netbeans.swing.tabcontrol.event.VeryComplexListDataEvent;
98
import org.netbeans.swing.tabcontrol.event.VeryComplexListDataEvent;
99
import org.netbeans.swing.tabcontrol.plaf.EqualPolygon;
100
import org.netbeans.swing.tabcontrol.plaf.FxProvider;
100
101
101
/**
102
/**
102
 * Default UI implementation for tabbed containers.  Manages installing the tab
103
 * contentDisplayer and content contentDisplayer components, and the
104
 * relationship between the data models and selection models of the UI.
105
 * <p>
106
 * Note that there is typically little reasons to subclass this - to affect the display
107
 * or behavior of the tabs, implement {@link org.netbeans.swing.tabcontrol.TabDisplayerUI},
108
 * the UI delegate for the embedded component which displays the tabs.
109
 *
103
 *
110
 * @author Tim Boudreau
104
 * @author russell
111
 */
105
 */
112
public class DefaultTabbedContainerUI extends TabbedContainerUI {
106
public class DefaultTabbedContainerUI extends TabbedContainerUI {
107
113
    /**
108
    /**
114
     * Action listener which receives actions from the tab displayer and propagates them through
109
     * Action listener which receives actions from the tab displayer and
115
     * action listeners on the tab displayer, to allow clients to consume the events.
110
     * propagates them through action listeners on the tab displayer, to allow
111
     * clients to consume the events.
116
     */
112
     */
117
    private ActionListener actionListener = null;
113
    private ActionListener actionListener = null;
118
    /**
114
    /**
119
     * Flag to ensure listeners attached, since ComponentShown notifications are not always
115
     * Flag to ensure listeners attached, since ComponentShown notifications are
120
     * reliable.
116
     * not always reliable.
121
     */
117
     */
122
    /** UIManager key for the border of the tab displayer in editor ui type. */
118
    /**
119
     * UIManager key for the border of the tab displayer in editor ui type.
120
     */
123
    public static final String KEY_EDITOR_CONTENT_BORDER = "TabbedContainer.editor.contentBorder"; //NOI18N
121
    public static final String KEY_EDITOR_CONTENT_BORDER = "TabbedContainer.editor.contentBorder"; //NOI18N
124
    /** UIManager key for the border of the tab displayer in editor ui type */
122
    /**
123
     * UIManager key for the border of the tab displayer in editor ui type
124
     */
125
    public static final String KEY_EDITOR_TABS_BORDER = "TabbedContainer.editor.tabsBorder"; //NOI18N
125
    public static final String KEY_EDITOR_TABS_BORDER = "TabbedContainer.editor.tabsBorder"; //NOI18N
126
    /** UIManager key for the border of the entire tabbed container in editor ui type*/
126
    /**
127
     * UIManager key for the border of the entire tabbed container in editor ui
128
     * type
129
     */
127
    public static final String KEY_EDITOR_OUTER_BORDER = "TabbedContainer.editor.outerBorder"; //NOI18N
130
    public static final String KEY_EDITOR_OUTER_BORDER = "TabbedContainer.editor.outerBorder"; //NOI18N
128
131
129
    /** UIManager key for the border of the tab displayer in view ui type. */
132
    /**
133
     * UIManager key for the border of the tab displayer in view ui type.
134
     */
130
    public static final String KEY_VIEW_CONTENT_BORDER = "TabbedContainer.view.contentBorder"; //NOI18N
135
    public static final String KEY_VIEW_CONTENT_BORDER = "TabbedContainer.view.contentBorder"; //NOI18N
131
    /** UIManager key for the border of the tab displayer in view ui type. */
136
    /**
137
     * UIManager key for the border of the tab displayer in view ui type.
138
     */
132
    public static final String KEY_VIEW_TABS_BORDER = "TabbedContainer.view.tabsBorder"; //NOI18N
139
    public static final String KEY_VIEW_TABS_BORDER = "TabbedContainer.view.tabsBorder"; //NOI18N
133
    /** UIManager key for the border of the entire tabbed container in view ui type.*/
140
    /**
141
     * UIManager key for the border of the entire tabbed container in view ui
142
     * type.
143
     */
134
    public static final String KEY_VIEW_OUTER_BORDER = "TabbedContainer.view.outerBorder"; //NOI18N
144
    public static final String KEY_VIEW_OUTER_BORDER = "TabbedContainer.view.outerBorder"; //NOI18N
135
145
136
    /** UIManager key for the border of the tab displayer in sliding ui type. */
146
    /**
147
     * UIManager key for the border of the tab displayer in sliding ui type.
148
     */
137
    public static final String KEY_SLIDING_CONTENT_BORDER = "TabbedContainer.sliding.contentBorder"; //NOI18N
149
    public static final String KEY_SLIDING_CONTENT_BORDER = "TabbedContainer.sliding.contentBorder"; //NOI18N
138
    /** UIManager key for the border of the tab displayer in sliding ui type */
150
    /**
151
     * UIManager key for the border of the tab displayer in sliding ui type
152
     */
139
    public static final String KEY_SLIDING_TABS_BORDER = "TabbedContainer.sliding.tabsBorder"; //NOI18N
153
    public static final String KEY_SLIDING_TABS_BORDER = "TabbedContainer.sliding.tabsBorder"; //NOI18N
140
    /** UIManager key for the border of the entire tabbed container in sliding ui type*/
154
    /**
155
     * UIManager key for the border of the entire tabbed container in sliding ui
156
     * type
157
     */
141
    public static final String KEY_SLIDING_OUTER_BORDER = "TabbedContainer.sliding.outerBorder"; //NOI18N
158
    public static final String KEY_SLIDING_OUTER_BORDER = "TabbedContainer.sliding.outerBorder"; //NOI18N
142
159
143
    /** UIManager key for the border of the tab displayer in toolbar ui type. */
160
    /**
161
     * UIManager key for the border of the tab displayer in toolbar ui type.
162
     */
144
    public static final String KEY_TOOLBAR_CONTENT_BORDER = "TabbedContainer.toolbar.contentBorder"; //NOI18N
163
    public static final String KEY_TOOLBAR_CONTENT_BORDER = "TabbedContainer.toolbar.contentBorder"; //NOI18N
145
    /** UIManager key for the border of the tab displayer in toolbar ui type */
164
    /**
165
     * UIManager key for the border of the tab displayer in toolbar ui type
166
     */
146
    public static final String KEY_TOOLBAR_TABS_BORDER = "TabbedContainer.toolbar.tabsBorder"; //NOI18N
167
    public static final String KEY_TOOLBAR_TABS_BORDER = "TabbedContainer.toolbar.tabsBorder"; //NOI18N
147
    /** UIManager key for the border of the entire tabbed container in toolbar ui type*/
168
    /**
169
     * UIManager key for the border of the entire tabbed container in toolbar ui
170
     * type
171
     */
148
    public static final String KEY_TOOLBAR_OUTER_BORDER = "TabbedContainer.toolbar.outerBorder"; //NOI18N
172
    public static final String KEY_TOOLBAR_OUTER_BORDER = "TabbedContainer.toolbar.outerBorder"; //NOI18N
149
173
150
    /** Component listener which listens on the container, and attaches/detaches listeners.
174
    /**
151
     * <strong>do not alter the value in this field.  To provide a different implementation,
175
     * Component listener which listens on the container, and attaches/detaches
152
     * override the appropriate creation method.</strong>
176
     * listeners.
153
     **/
177
     * <strong>do not alter the value in this field. To provide a different
178
     * implementation, override the appropriate creation method.</strong>
179
     *
180
     */
154
    protected ComponentListener componentListener = null;
181
    protected ComponentListener componentListener = null;
155
    /** Change listener which tracks changes in the selection model and changes the displayed
182
    /**
156
     * component to reflect the selected tab
183
     * Change listener which tracks changes in the selection model and changes
157
     * <strong>do not alter the value in this field.  To provide a different implementation,
184
     * the displayed component to reflect the selected tab
158
     * override the appropriate creation method.</strong>
185
     * <strong>do not alter the value in this field. To provide a different
186
     * implementation, override the appropriate creation method.</strong>
159
     */
187
     */
160
    protected ChangeListener selectionListener = null;
188
    protected ChangeListener selectionListener = null;
161
    /** Listener on the data model, which handles updating the contained components to keep them
189
    /**
162
     * in sync with the contents of the data model.
190
     * Listener on the data model, which handles updating the contained
163
     * <strong>do not alter the value in this field.  To provide a different implementation,
191
     * components to keep them in sync with the contents of the data model.
164
     * override the appropriate creation method.</strong>
192
     * <strong>do not alter the value in this field. To provide a different
193
     * implementation, override the appropriate creation method.</strong>
194
     *
165
     * @see TabbedContainer#setContentPolicy
195
     * @see TabbedContainer#setContentPolicy
166
     */
196
     */
167
    protected ComplexListDataListener modelListener = null;
197
    protected ComplexListDataListener modelListener = null;
168
    /**
198
    /**
169
     * Layout manager which will handle layout of the tabbed container.
199
     * Layout manager which will handle layout of the tabbed container.
170
     * <strong>do not alter the value in this field.  To provide a different implementation,
200
     * <strong>do not alter the value in this field. To provide a different
171
     * override the appropriate creation method.</strong>
201
     * implementation, override the appropriate creation method.</strong>
172
     */
202
     */
173
    protected LayoutManager contentDisplayerLayout = null;
203
    protected LayoutManager contentDisplayerLayout = null;
174
    /** Property change listener which detects changes on the tabbed container, such as its active state, which
204
    /**
175
     * should be propagated to the tab displayer.
205
     * Property change listener which detects changes on the tabbed container,
176
     * <strong>do not alter the value in this field.  To provide a different implementation,
206
     * such as its active state, which should be propagated to the tab
177
     * override the appropriate creation method.</strong>
207
     * displayer.
208
     * <strong>do not alter the value in this field. To provide a different
209
     * implementation, override the appropriate creation method.</strong>
178
     */
210
     */
179
    protected PropertyChangeListener propertyChangeListener = null;
211
    protected PropertyChangeListener propertyChangeListener = null;
180
    /**
212
    /**
181
     * FxProvider which will provide transition effects when tabs are changed.  By default, only used for
213
     * FxProvider which will provide transition effects when tabs are changed.
182
     * TabbedContainer.TYPE_SLIDE tabs.
214
     * By default, only used for TabbedContainer.TYPE_SLIDE tabs.
183
     * <strong>do not alter the value in this field.  To provide a different implementation,
215
     * <strong>do not alter the value in this field. To provide a different
184
     * override the appropriate creation method.</strong>
216
     * implementation, override the appropriate creation method.</strong>
185
     */
217
     */
186
    protected FxProvider slideEffectManager = null;
218
    protected FxProvider slideEffectManager = null;
187
219
188
    /**
220
    /**
189
     * The component which displays the selected component in the tabbed container.
221
     * The component which displays the selected component in the tabbed
190
     * <strong>do not alter the value in this field.  To provide a different implementation,
222
     * container.
191
     * override the appropriate creation method.</strong>
223
     * <strong>do not alter the value in this field. To provide a different
224
     * implementation, override the appropriate creation method.</strong>
192
     */
225
     */
193
    protected JComponent contentDisplayer = null;
226
    protected JComponent contentDisplayer = null;
194
    /**
227
    /**
195
     * The Displayer for the tabs.  Normally an instance of <code>TabDisplayer</code>.  To get the actual
228
     * The Displayer for the tabs. Normally an instance of
196
     * GUI component that is showing tabs, call its <code>getComponent()</code> method.
229
     * <code>TabDisplayer</code>. To get the actual GUI component that is
197
     * <strong>do not alter the value in this field.  To provide a different implementation,
230
     * showing tabs, call its <code>getComponent()</code> method.
198
     * override the appropriate creation method.</strong>
231
     * <strong>do not alter the value in this field. To provide a different
232
     * implementation, override the appropriate creation method.</strong>
199
     */
233
     */
200
    protected TabDisplayer tabDisplayer = null;
234
    protected TabDisplayer tabDisplayer = null;
201
    
235
202
    private HierarchyListener hierarchyListener = null;
236
    private HierarchyListener hierarchyListener = null;
203
237
204
    /**
238
    /**
Lines 212-229 Link Here
212
        return new DefaultTabbedContainerUI((TabbedContainer) c);
246
        return new DefaultTabbedContainerUI((TabbedContainer) c);
213
    }
247
    }
214
248
215
    /** This method is final.  Subclasses which need to provide additional initialization should override
249
    /**
216
     * <code>install()</code>
250
     * This method is final. Subclasses which need to provide additional
251
     * initialization should override <code>install()</code>
217
     *
252
     *
218
     * @param c A JComponent, which must == the displayer field initialized in the constructor
253
     * @param c A JComponent, which must == the displayer field initialized in
254
     * the constructor
219
     */
255
     */
220
    @Override
256
    @Override
221
    public final void installUI(JComponent c) {
257
    public final void installUI(JComponent c) {
222
        assert c == container;
258
        assert c == container;
223
        container.setLayout(createLayout());
259
        container.setLayout(createLayout());
224
        contentDisplayer = createContentDisplayer();
260
        contentDisplayer = createContentDisplayer();
225
        if( "Aqua".equals(UIManager.getLookAndFeel().getID()) //NOI18N
261
        if ("Aqua".equals(UIManager.getLookAndFeel().getID()) //NOI18N
226
            && (container.getType() == TabbedContainer.TYPE_VIEW
262
                && (container.getType() == TabbedContainer.TYPE_VIEW
227
                || container.getType() == TabbedContainer.TYPE_SLIDING)
263
                || container.getType() == TabbedContainer.TYPE_SLIDING)
228
                && !Boolean.getBoolean("nb.explorerview.aqua.defaultbackground")) { //NOI18N
264
                && !Boolean.getBoolean("nb.explorerview.aqua.defaultbackground")) { //NOI18N
229
            contentDisplayer.setBackground(UIManager.getColor("NbExplorerView.background")); //NOI18N
265
            contentDisplayer.setBackground(UIManager.getColor("NbExplorerView.background")); //NOI18N
Lines 250-269 Link Here
250
        tabDisplayer.getSelectionModel().addChangeListener(selectionListener);
286
        tabDisplayer.getSelectionModel().addChangeListener(selectionListener);
251
287
252
    }
288
    }
253
    
289
254
    
290
    /**
255
    /** Used by unit tests */
291
     * Used by unit tests
292
     */
256
    TabDisplayer getTabDisplayer() {
293
    TabDisplayer getTabDisplayer() {
257
        return tabDisplayer;
294
        return tabDisplayer;
258
    }
295
    }
259
296
260
    private MouseListener forward = null;
297
    private MouseListener forward = null;
261
298
262
    /** This method is final.  Subclasses which need to provide additional initialization should override
299
    /**
263
     * <code>uninstall()</code>
300
     * This method is final. Subclasses which need to provide additional
301
     * initialization should override <code>uninstall()</code>
264
     *
302
     *
265
     * @param c A JComponent, which must == the displayer field initialized in the constructor
303
     * @param c A JComponent, which must == the displayer field initialized in
304
     * the constructor
266
     */
305
     */
306
    @Override
267
    public final void uninstallUI(JComponent c) {
307
    public final void uninstallUI(JComponent c) {
268
        assert c == container;
308
        assert c == container;
269
        tabDisplayer.getSelectionModel().removeChangeListener(selectionListener);
309
        tabDisplayer.getSelectionModel().removeChangeListener(selectionListener);
Lines 283-307 Link Here
283
        forward = null;
323
        forward = null;
284
    }
324
    }
285
325
286
    /** Subclasses may override this method to do anything they need to do on installUI().  It will
326
    /**
287
     * be called after listeners, the displayer, etc. (all pseudo-final protected fields) have been
327
     * Subclasses may override this method to do anything they need to do on
288
     * initialized.
328
     * installUI(). It will be called after listeners, the displayer, etc. (all
329
     * pseudo-final protected fields) have been initialized.
289
     */
330
     */
290
    protected void install() {
331
    protected void install() {
291
332
292
    }
333
    }
293
334
294
    /** Subclasses may override this method to do anything they need to do on uninstallUI().  It will
335
    /**
295
     * be called before the protected fields of the instance have been nulled.
336
     * Subclasses may override this method to do anything they need to do on
337
     * uninstallUI(). It will be called before the protected fields of the
338
     * instance have been nulled.
296
     */
339
     */
297
    protected void uninstall() {
340
    protected void uninstall() {
298
341
299
    }
342
    }
300
    
343
344
    @Override
301
    protected boolean uichange() {
345
    protected boolean uichange() {
302
        installBorders();
346
        installBorders();
303
        return false;
347
        return false;
304
    }    
348
    }
305
349
306
    /**
350
    /**
307
     * Installs the content displayer component and its layout manager
351
     * Installs the content displayer component and its layout manager
Lines 312-319 Link Here
312
    }
356
    }
313
357
314
    /**
358
    /**
315
     * Installs the tab displayer component into the container.  By default, installs it using the
359
     * Installs the tab displayer component into the container. By default,
316
     * constraint <code>BorderLayout.NORTH</code>.
360
     * installs it using the constraint <code>BorderLayout.NORTH</code>.
317
     */
361
     */
318
    protected void installTabDisplayer() {
362
    protected void installTabDisplayer() {
319
        container.add(tabDisplayer, BorderLayout.NORTH);
363
        container.add(tabDisplayer, BorderLayout.NORTH);
Lines 328-396 Link Here
328
        String contentKey;
372
        String contentKey;
329
        String outerKey;
373
        String outerKey;
330
        switch (container.getType()) {
374
        switch (container.getType()) {
331
            case TabbedContainer.TYPE_EDITOR :
375
            case TabbedContainer.TYPE_EDITOR:
332
                tabsKey = KEY_EDITOR_TABS_BORDER;
376
                tabsKey = KEY_EDITOR_TABS_BORDER;
333
                contentKey = KEY_EDITOR_CONTENT_BORDER;
377
                contentKey = KEY_EDITOR_CONTENT_BORDER;
334
                outerKey = KEY_EDITOR_OUTER_BORDER;
378
                outerKey = KEY_EDITOR_OUTER_BORDER;
335
                break;
379
                break;
336
            case TabbedContainer.TYPE_VIEW :
380
            case TabbedContainer.TYPE_VIEW:
337
                tabsKey = KEY_VIEW_TABS_BORDER;
381
                tabsKey = KEY_VIEW_TABS_BORDER;
338
                contentKey = KEY_VIEW_CONTENT_BORDER;
382
                contentKey = KEY_VIEW_CONTENT_BORDER;
339
                outerKey = KEY_VIEW_OUTER_BORDER;
383
                outerKey = KEY_VIEW_OUTER_BORDER;
340
                break;
384
                break;
341
            case TabbedContainer.TYPE_SLIDING :
385
            case TabbedContainer.TYPE_SLIDING:
342
                tabsKey = KEY_SLIDING_TABS_BORDER;
386
                tabsKey = KEY_SLIDING_TABS_BORDER;
343
                contentKey = KEY_SLIDING_CONTENT_BORDER;
387
                contentKey = KEY_SLIDING_CONTENT_BORDER;
344
                outerKey = KEY_SLIDING_OUTER_BORDER;
388
                outerKey = KEY_SLIDING_OUTER_BORDER;
345
                break;
389
                break;
346
            case TabbedContainer.TYPE_TOOLBAR :
390
            case TabbedContainer.TYPE_TOOLBAR:
347
                tabsKey = KEY_TOOLBAR_TABS_BORDER;
391
                tabsKey = KEY_TOOLBAR_TABS_BORDER;
348
                contentKey = KEY_TOOLBAR_CONTENT_BORDER;
392
                contentKey = KEY_TOOLBAR_CONTENT_BORDER;
349
                outerKey = KEY_TOOLBAR_OUTER_BORDER;
393
                outerKey = KEY_TOOLBAR_OUTER_BORDER;
350
                break;
394
                break;
351
            default :
395
            default:
352
                throw new IllegalStateException ("Unknown type: "
396
                throw new IllegalStateException("Unknown type: "
353
                    + container.getType());
397
                        + container.getType());
354
        }
398
        }
355
        try {
399
        try {
356
            Border b = (Border) UIManager.get (contentKey);
400
            Border b = (Border) UIManager.get(contentKey);
357
            contentDisplayer.setBorder(b);
401
            contentDisplayer.setBorder(b);
358
            b = (Border) UIManager.get (tabsKey);
402
            b = (Border) UIManager.get(tabsKey);
359
            tabDisplayer.setBorder(b);
403
            tabDisplayer.setBorder(b);
360
            b = (Border) UIManager.get (outerKey);
404
            b = (Border) UIManager.get(outerKey);
361
            container.setBorder(b);
405
            container.setBorder(b);
362
        } catch (ClassCastException cce) {
406
        } catch (ClassCastException cce) {
363
            System.err.println ("Expected a border from UIManager for "
407
            System.err.println("Expected a border from UIManager for "
364
                + tabsKey + "," + contentKey + "," + outerKey);
408
                    + tabsKey + "," + contentKey + "," + outerKey);
365
        }
409
        }
366
    }
410
    }
367
411
368
    /**
412
    /**
369
     * Installs a component listener on the component.  Listeners on the data
413
     * Installs a component listener on the component. Listeners on the data
370
     * model and selection model are installed when the component is shown, as
414
     * model and selection model are installed when the component is shown, as
371
     * detected by the component listener.
415
     * detected by the component listener.
372
     */
416
     */
373
    protected void installListeners() {
417
    protected void installListeners() {
374
        container.addComponentListener(componentListener);
418
        container.addComponentListener(componentListener);
375
        container.addHierarchyListener (hierarchyListener);
419
        container.addHierarchyListener(hierarchyListener);
376
        //Allow mouse events to be forwarded as if they came from the 
420
        //Allow mouse events to be forwarded as if they came from the 
377
        //container
421
        //container
378
        tabDisplayer.addMouseListener (forward);
422
        tabDisplayer.addMouseListener(forward);
379
        contentDisplayer.addMouseListener (forward);
423
        contentDisplayer.addMouseListener(forward);
380
    }
424
    }
381
425
382
    /**
426
    /**
383
     * Begin listening to the model for changes in the selection, which should
427
     * Begin listening to the model for changes in the selection, which should
384
     * cause us to update the displayed component in the content
428
     * cause us to update the displayed component in the content
385
     * contentDisplayer. Listening starts when the component is first shown, and
429
     * contentDisplayer. Listening starts when the component is first shown, and
386
     * stops when it is hidden;  if you override <code>createComponentListener()</code>,
430
     * stops when it is hidden; if you override
387
     * you will need to call this method when the component is shown.
431
     * <code>createComponentListener()</code>, you will need to call this method
432
     * when the component is shown.
388
     */
433
     */
389
    protected void attachModelAndSelectionListeners() {
434
    protected void attachModelAndSelectionListeners() {
390
        container.getModel().addComplexListDataListener(modelListener);
435
        container.getModel().addComplexListDataListener(modelListener);
391
        container.addPropertyChangeListener(propertyChangeListener);
436
        container.addPropertyChangeListener(propertyChangeListener);
392
        tabDisplayer.setActive (container.isActive());
437
        tabDisplayer.setActive(container.isActive());
393
        tabDisplayer.addActionListener (actionListener);
438
        tabDisplayer.addActionListener(actionListener);
394
    }
439
    }
395
440
396
    /**
441
    /**
Lines 398-422 Link Here
398
     * cause us to update the displayed component in the content
443
     * cause us to update the displayed component in the content
399
     * contentDisplayer, and changes in the data model which can affect the
444
     * contentDisplayer, and changes in the data model which can affect the
400
     * displayed component. Listening starts when the component is first shown,
445
     * displayed component. Listening starts when the component is first shown,
401
     * and stops when it is hidden;  if you override <code>createComponentListener()</code>,
446
     * and stops when it is hidden; if you override
402
     * you will need to call this method when the component is hidden.
447
     * <code>createComponentListener()</code>, you will need to call this method
448
     * when the component is hidden.
403
     */
449
     */
404
    protected void detachModelAndSelectionListeners() {
450
    protected void detachModelAndSelectionListeners() {
405
        container.getModel().removeComplexListDataListener(modelListener);
451
        container.getModel().removeComplexListDataListener(modelListener);
406
        container.removePropertyChangeListener(propertyChangeListener);
452
        container.removePropertyChangeListener(propertyChangeListener);
407
        tabDisplayer.removeActionListener (actionListener);
453
        tabDisplayer.removeActionListener(actionListener);
408
    }
454
    }
409
455
410
    /**
456
    /**
411
     * Uninstalls the component listener installed in <code>installListeners()</code>
457
     * Uninstalls the component listener installed in
458
     * <code>installListeners()</code>
412
     */
459
     */
413
    protected void uninstallListeners() {
460
    protected void uninstallListeners() {
414
        container.removeComponentListener(componentListener);
461
        container.removeComponentListener(componentListener);
415
        container.removeHierarchyListener (hierarchyListener);
462
        container.removeHierarchyListener(hierarchyListener);
416
        componentListener = null;
463
        componentListener = null;
417
        propertyChangeListener = null;
464
        propertyChangeListener = null;
418
        tabDisplayer.removeMouseListener (forward);
465
        tabDisplayer.removeMouseListener(forward);
419
        contentDisplayer.removeMouseListener (forward);
466
        contentDisplayer.removeMouseListener(forward);
420
    }
467
    }
421
468
422
    /**
469
    /**
Lines 447-470 Link Here
447
                    container.getModel(), container.getType(), container.getLocationInformer());
494
                    container.getModel(), container.getType(), container.getLocationInformer());
448
        }
495
        }
449
        result.setName("Tab Displayer");  //NOI18N
496
        result.setName("Tab Displayer");  //NOI18N
450
        result.setComponentConverter( container.getComponentConverter() );
497
        result.setComponentConverter(container.getComponentConverter());
451
        return result;
498
        return result;
452
    }
499
    }
453
500
454
    /**
501
    /**
455
     * Create the component which will contain the content (the components which
502
     * Create the component which will contain the content (the components which
456
     * correspond to tabs).  The default implementation simply returns a
503
     * correspond to tabs). The default implementation simply returns a vanilla,
457
     * vanilla, unadorned <code>JPanel</code>.
504
     * unadorned <code>JPanel</code>.
458
     */
505
     */
459
    protected JPanel createContentDisplayer() {
506
    protected JPanel createContentDisplayer() {
460
        JPanel result = new JPanel();
507
        JPanel result = new JPanel();
461
        result.setName ("Content displayer"); //NOI18N
508
        result.setName("Content displayer"); //NOI18N
462
        return result;
509
        return result;
463
    }
510
    }
464
511
465
    /**
512
    /**
466
     * Create an FxProvider instance which will provide transition effects when tabs are selected.
513
     * Create an FxProvider instance which will provide transition effects when
467
     * By default creates a no-op instance for all displayer types except TYPE_SLIDING.
514
     * tabs are selected. By default creates a no-op instance for all displayer
515
     * types except TYPE_SLIDING.
468
     *
516
     *
469
     * @return An instance of FxProvider
517
     * @return An instance of FxProvider
470
     */
518
     */
Lines 482-489 Link Here
482
530
483
    /**
531
    /**
484
     * Creates the content contentDisplayer's layout manager, responsible for
532
     * Creates the content contentDisplayer's layout manager, responsible for
485
     * ensuring that the correct component is on top and is the only one
533
     * ensuring that the correct component is on top and is the only one showing
486
     * showing
487
     */
534
     */
488
    protected LayoutManager createContentDisplayerLayout() {
535
    protected LayoutManager createContentDisplayerLayout() {
489
        return new StackLayout();
536
        return new StackLayout();
Lines 491-503 Link Here
491
538
492
    /**
539
    /**
493
     * Create the layout manager that will manage the layout of the
540
     * Create the layout manager that will manage the layout of the
494
     * TabbedContainer.  A TabbedContainer contains two components - the tabs
541
     * TabbedContainer. A TabbedContainer contains two components - the tabs
495
     * contentDisplayer, and the component contentDisplayer.
542
     * contentDisplayer, and the component contentDisplayer.
496
     * <p/>
543
     * <p/>
497
     * The layout manager determines the position of the tabs relative to the
544
     * The layout manager determines the position of the tabs relative to the
498
     * contentDisplayer component which displays the tab contents.
545
     * contentDisplayer component which displays the tab contents.
499
     * <p/>
546
     * <p/>
500
     * The default implementation uses BorderLayout.  If you override this, you
547
     * The default implementation uses BorderLayout. If you override this, you
501
     * should probably override <code>installDisplayer()</code> as well.
548
     * should probably override <code>installDisplayer()</code> as well.
502
     */
549
     */
503
    protected LayoutManager createLayout() {
550
    protected LayoutManager createLayout() {
Lines 520-535 Link Here
520
567
521
    /**
568
    /**
522
     * Create a property change listener which will update the tab displayer in
569
     * Create a property change listener which will update the tab displayer in
523
     * accordance with property changes on the container.  Currently the only
570
     * accordance with property changes on the container. Currently the only
524
     * property change of interest is calls to <code>TabbedContainer.setActive()</code>,
571
     * property change of interest is calls to
525
     * which simply cause the active state to be set on the displayer.
572
     * <code>TabbedContainer.setActive()</code>, which simply cause the active
573
     * state to be set on the displayer.
526
     */
574
     */
527
    protected PropertyChangeListener createPropertyChangeListener() {
575
    protected PropertyChangeListener createPropertyChangeListener() {
528
        return new ContainerPropertyChangeListener();
576
        return new ContainerPropertyChangeListener();
529
    }
577
    }
530
578
531
    /** Creates an action listener to catch actions performed on the tab displayer
579
    /**
532
     * and forward them to listeners on the container for consumption.
580
     * Creates an action listener to catch actions performed on the tab
581
     * displayer and forward them to listeners on the container for consumption.
533
     *
582
     *
534
     * @return An action listener
583
     * @return An action listener
535
     */
584
     */
Lines 548-564 Link Here
548
            showComponent(toComp(td));
597
            showComponent(toComp(td));
549
        }
598
        }
550
    }
599
    }
551
    
600
552
    /** Convenience method for fetching a component from a TabData object
601
    /**
553
     * via the container's ComponentConverter */
602
     * Convenience method for fetching a component from a TabData object via the
554
    protected final Component toComp (TabData data) {
603
     * container's ComponentConverter
604
     */
605
    protected final Component toComp(TabData data) {
555
        return container.getComponentConverter().getComponent(data);
606
        return container.getComponentConverter().getComponent(data);
556
    }
607
    }
557
608
558
    /**
609
    /**
559
     * Shows the passed component. <strong>This method does not communicate with
610
     * Shows the passed component. <strong>This method does not communicate with
560
     * the data model in any way shape or form, it just moves the passed
611
     * the data model in any way shape or form, it just moves the passed
561
     * component to the front.  It should only be called in response to an event
612
     * component to the front. It should only be called in response to an event
562
     * from the data model or selection model.
613
     * from the data model or selection model.
563
     * <p/>
614
     * <p/>
564
     * If you override <code>createContentDisplayerLayoutModel()</code> to
615
     * If you override <code>createContentDisplayerLayoutModel()</code> to
Lines 575-581 Link Here
575
            Component last = stack.getVisibleComponent();
626
            Component last = stack.getVisibleComponent();
576
            stack.showComponent(c, contentDisplayer);
627
            stack.showComponent(c, contentDisplayer);
577
            if (c != null) {
628
            if (c != null) {
578
                Integer offset = (Integer)((JComponent)c).getClientProperty("MultiViewBorderHack.topOffset");
629
                Integer offset = (Integer) ((JComponent) c).getClientProperty("MultiViewBorderHack.topOffset");
579
                contentDisplayer.putClientProperty("MultiViewBorderHack.topOffset", offset);
630
                contentDisplayer.putClientProperty("MultiViewBorderHack.topOffset", offset);
580
            } else {
631
            } else {
581
                contentDisplayer.putClientProperty("MultiViewBorderHack.topOffset", null);
632
                contentDisplayer.putClientProperty("MultiViewBorderHack.topOffset", null);
Lines 589-621 Link Here
589
    }
640
    }
590
641
591
    /**
642
    /**
592
     * Shows a component in the control, using the <code>FxProvider</code> created in
643
     * Shows a component in the control, using the <code>FxProvider</code>
593
     * <code>createFxProvider()</code> to manage showing it.  Equivalent to calling <code>showComponent</code>,
644
     * created in <code>createFxProvider()</code> to manage showing it.
594
     * but there may be a delay while the effect is performed.  If no <code>FxProvider</code> is installed,
645
     * Equivalent to calling <code>showComponent</code>, but there may be a
595
     * this will simply delegate to <code>showComponent</code>; if not, the <code>FxProvider</code> is expected
646
     * delay while the effect is performed. If no <code>FxProvider</code> is
596
     * to do that when its effect is completed.
647
     * installed, this will simply delegate to <code>showComponent</code>; if
648
     * not, the <code>FxProvider</code> is expected to do that when its effect
649
     * is completed.
597
     *
650
     *
598
     * @param c The component to be shown.
651
     * @param c The component to be shown.
599
     */
652
     */
600
    protected final void showComponentWithFxProvider (Component c) {
653
    protected final void showComponentWithFxProvider(Component c) {
601
        if (slideEffectManager == null || !container.isShowing() || (!(c instanceof JComponent))) {
654
        if (slideEffectManager == null || !container.isShowing() || (!(c instanceof JComponent))) {
602
            Component last = showComponent (c);
655
            Component last = showComponent(c);
603
            maybeRemoveLastComponent (last);
656
            maybeRemoveLastComponent(last);
604
        } else {
657
        } else {
605
            slideEffectManager.start((JComponent) c, container.getRootPane(), 
658
            slideEffectManager.start((JComponent) c, container.getRootPane(),
606
                tabDisplayer.getClientProperty(TabDisplayer.PROP_ORIENTATION));
659
                    tabDisplayer.getClientProperty(TabDisplayer.PROP_ORIENTATION));
607
        }
660
        }
608
    }
661
    }
609
662
610
    /**
663
    /**
611
     * Removes the passed component from the AWT hierarchy if the container's content policy is
664
     * Removes the passed component from the AWT hierarchy if the container's
612
     * CONTENT_POLICY_ADD_ONLY_SELECTED.
665
     * content policy is CONTENT_POLICY_ADD_ONLY_SELECTED.
613
     *
666
     *
614
     * @param c The component that should be removed
667
     * @param c The component that should be removed
615
     */
668
     */
616
    private final void maybeRemoveLastComponent (Component c) {
669
    private final void maybeRemoveLastComponent(Component c) {
617
        if (c != null && container.getContentPolicy() == TabbedContainer.CONTENT_POLICY_ADD_ONLY_SELECTED) {
670
        if (c != null && container.getContentPolicy() == TabbedContainer.CONTENT_POLICY_ADD_ONLY_SELECTED) {
618
            contentDisplayer.remove (c);
671
            contentDisplayer.remove(c);
619
        }
672
        }
620
    }
673
    }
621
674
Lines 627-634 Link Here
627
            List tabs = container.getModel().getTabs();
680
            List tabs = container.getModel().getTabs();
628
            Component curC = null;
681
            Component curC = null;
629
            for (Iterator iter = tabs.iterator(); iter.hasNext();) {
682
            for (Iterator iter = tabs.iterator(); iter.hasNext();) {
630
                curC = toComp ((TabData) iter.next());
683
                curC = toComp((TabData) iter.next());
631
                // string parameter is needed for StackLayout to kick in correctly
684
                // string parameter is needed for StackLayout to kick in correctly
685
                if (curC.getParent() != null) {
686
                    curC.getParent().remove(curC);
687
                }
632
                contentDisplayer.add(curC, "");
688
                contentDisplayer.add(curC, "");
633
            }
689
            }
634
        } else {
690
        } else {
Lines 642-650 Link Here
642
    }
698
    }
643
699
644
    /**
700
    /**
645
     * Create a listener for the TabDataModel.  This listener is responsible for
701
     * Create a listener for the TabDataModel. This listener is responsible for
646
     * keeping the state of the contained components in the displayer in sync
702
     * keeping the state of the contained components in the displayer in sync
647
     * with the contents of the data model.  Note that it is not necessary for
703
     * with the contents of the data model. Note that it is not necessary for
648
     * this listener to adjust the selection - DefaultTabSelectionModel handles
704
     * this listener to adjust the selection - DefaultTabSelectionModel handles
649
     * cases such as removing the selected component appropriately, so if such a
705
     * cases such as removing the selected component appropriately, so if such a
650
     * model change happens, a selection change will be immediately forthcoming
706
     * model change happens, a selection change will be immediately forthcoming
Lines 669-675 Link Here
669
        return new SelectionListener();
725
        return new SelectionListener();
670
    }
726
    }
671
727
672
    /** Sets the active state of the displayer to match that of the container */
728
    /**
729
     * Sets the active state of the displayer to match that of the container
730
     */
673
    private void updateActiveState() {
731
    private void updateActiveState() {
674
        //#45630 - more of a hack than a fix.
732
        //#45630 - more of a hack than a fix.
675
        //apparently uninstallUI() was called before the the ContainerPropertyChangeListener instance was removed in 
733
        //apparently uninstallUI() was called before the the ContainerPropertyChangeListener instance was removed in 
Lines 680-688 Link Here
680
        if (displ != null && cont != null) {
738
        if (displ != null && cont != null) {
681
            displ.setActive(cont.isActive());
739
            displ.setActive(cont.isActive());
682
        }
740
        }
683
        
741
684
    }
742
    }
685
743
744
    @Override
686
    public Rectangle getTabRect(int tab, Rectangle r) {
745
    public Rectangle getTabRect(int tab, Rectangle r) {
687
        if (r == null) {
746
        if (r == null) {
688
            r = new Rectangle();
747
            r = new Rectangle();
Lines 693-717 Link Here
693
        r.y += p.y;
752
        r.y += p.y;
694
        return r;
753
        return r;
695
    }
754
    }
696
    
755
697
    protected void requestAttention (int tab) {
756
    @Override
698
        tabDisplayer.requestAttention (tab);
757
    protected void requestAttention(int tab) {
758
        tabDisplayer.requestAttention(tab);
699
    }
759
    }
700
    
760
701
    protected void cancelRequestAttention (int tab) {
761
    @Override
762
    protected void cancelRequestAttention(int tab) {
702
        tabDisplayer.cancelRequestAttention(tab);
763
        tabDisplayer.cancelRequestAttention(tab);
703
    }
764
    }
704
765
705
    @Override
766
    @Override
706
    protected void setAttentionHighlight (int tab, boolean highlight) {
767
    protected void setAttentionHighlight(int tab, boolean highlight) {
707
        tabDisplayer.setAttentionHighlight(tab, highlight);
768
        tabDisplayer.setAttentionHighlight(tab, highlight);
708
    }
769
    }
709
    
770
710
    public void setShowCloseButton (boolean val) {
771
    @Override
772
    public void setShowCloseButton(boolean val) {
711
        tabDisplayer.setShowCloseButton(val);
773
        tabDisplayer.setShowCloseButton(val);
712
    }
774
    }
713
    
775
714
    public boolean isShowCloseButton () {
776
    @Override
777
    public boolean isShowCloseButton() {
715
        return tabDisplayer.isShowCloseButton();
778
        return tabDisplayer.isShowCloseButton();
716
    }
779
    }
717
780
Lines 720-729 Link Here
720
     * border is provided via UIDefaults.
783
     * border is provided via UIDefaults.
721
     */
784
     */
722
    private static final class DefaultWindowBorder implements Border {
785
    private static final class DefaultWindowBorder implements Border {
786
723
        private static final Insets insets = new Insets(1, 1, 2, 2);
787
        private static final Insets insets = new Insets(1, 1, 2, 2);
724
788
789
        @Override
725
        public void paintBorder(Component c, Graphics g, int x, int y, int w,
790
        public void paintBorder(Component c, Graphics g, int x, int y, int w,
726
                                int h) {
791
                int h) {
727
            g.translate(x, y);
792
            g.translate(x, y);
728
793
729
            g.setColor(UIManager.getColor("controlShadow")); //NOI18N
794
            g.setColor(UIManager.getColor("controlShadow")); //NOI18N
Lines 735-759 Link Here
735
            g.translate(-x, -y);
800
            g.translate(-x, -y);
736
        }
801
        }
737
802
803
        @Override
738
        public Insets getBorderInsets(Component c) {
804
        public Insets getBorderInsets(Component c) {
739
            return insets;
805
            return insets;
740
        }
806
        }
741
807
808
        @Override
742
        public boolean isBorderOpaque() {
809
        public boolean isBorderOpaque() {
743
            return true;
810
            return true;
744
        }
811
        }
745
    } // end of DefaultWindowBorder
812
    } // end of DefaultWindowBorder
746
813
747
    protected class ContainerPropertyChangeListener implements PropertyChangeListener {
814
    protected class ContainerPropertyChangeListener implements PropertyChangeListener {
748
        
815
816
        @Override
749
        public void propertyChange(PropertyChangeEvent evt) {
817
        public void propertyChange(PropertyChangeEvent evt) {
750
            if (TabbedContainer.PROP_ACTIVE.equals(evt.getPropertyName())) {
818
            if (TabbedContainer.PROP_ACTIVE.equals(evt.getPropertyName())) {
751
                updateActiveState();
819
                updateActiveState();
752
            }
820
            }
753
        }
821
        }
754
    }
822
    }
755
    
823
756
    /** Checks the position of the tabbed container relative to its parent
824
    /**
825
     * Checks the position of the tabbed container relative to its parent
757
     * window, and potentially updates its orientation client property.
826
     * window, and potentially updates its orientation client property.
758
     *
827
     *
759
     * @see TabDisplayer#PROP_ORIENTATION
828
     * @see TabDisplayer#PROP_ORIENTATION
Lines 762-768 Link Here
762
        if (!container.isDisplayable()) {
831
        if (!container.isDisplayable()) {
763
            return;
832
            return;
764
        }
833
        }
765
        if (Boolean.FALSE.equals(container.getClientProperty (TabbedContainer.PROP_MANAGE_TAB_POSITION))) {
834
        if (Boolean.FALSE.equals(container.getClientProperty(TabbedContainer.PROP_MANAGE_TAB_POSITION))) {
766
            //The client has specified that it does not want automatic management
835
            //The client has specified that it does not want automatic management
767
            //of the displayer orientation
836
            //of the displayer orientation
768
            return;
837
            return;
Lines 797-842 Link Here
797
866
798
        if (currOrientation != orientation) {
867
        if (currOrientation != orientation) {
799
            tabDisplayer.putClientProperty(
868
            tabDisplayer.putClientProperty(
800
                TabDisplayer.PROP_ORIENTATION, orientation);
869
                    TabDisplayer.PROP_ORIENTATION, orientation);
801
            container.validate();
870
            container.validate();
802
        }
871
        }
803
    }
872
    }
804
873
874
    @Override
805
    public int tabForCoordinate(Point p) {
875
    public int tabForCoordinate(Point p) {
806
        p = SwingUtilities.convertPoint(container, p, tabDisplayer);
876
        p = SwingUtilities.convertPoint(container, p, tabDisplayer);
807
        return tabDisplayer.tabForCoordinate(p);
877
        return tabDisplayer.tabForCoordinate(p);
808
    }
878
    }
809
879
880
    @Override
810
    public void makeTabVisible(int tab) {
881
    public void makeTabVisible(int tab) {
811
        tabDisplayer.makeTabVisible (tab);
882
        tabDisplayer.makeTabVisible(tab);
812
    }
883
    }
813
884
885
    @Override
814
    public SingleSelectionModel getSelectionModel() {
886
    public SingleSelectionModel getSelectionModel() {
815
        return tabDisplayer.getSelectionModel();
887
        return tabDisplayer.getSelectionModel();
816
    }
888
    }
817
889
890
    @Override
818
    public Image createImageOfTab(int idx) {
891
    public Image createImageOfTab(int idx) {
819
        return tabDisplayer.getUI().createImageOfTab(idx);
892
        return tabDisplayer.getUI().createImageOfTab(idx);
820
    }
893
    }
821
894
895
    @Override
822
    public Polygon getExactTabIndication(int idx) {
896
    public Polygon getExactTabIndication(int idx) {
823
        Polygon result = tabDisplayer.getUI().getExactTabIndication(idx);
897
        Polygon result = tabDisplayer.getUI().getExactTabIndication(idx);
824
        scratchPoint.setLocation(0,0);
898
        scratchPoint.setLocation(0, 0);
825
        Point p = SwingUtilities.convertPoint(tabDisplayer, scratchPoint, container);
899
        Point p = SwingUtilities.convertPoint(tabDisplayer, scratchPoint, container);
826
        result.translate (-p.x, -p.y);
900
        result.translate(-p.x, -p.y);
827
        return appendContentBoundsTo(result);
901
        return appendContentBoundsTo(result);
828
    }
902
    }
829
903
830
    private Point scratchPoint = new Point();
904
    private Point scratchPoint = new Point();
905
906
    @Override
831
    public Polygon getInsertTabIndication(int idx) {
907
    public Polygon getInsertTabIndication(int idx) {
832
        Polygon result = tabDisplayer.getUI().getInsertTabIndication(idx);
908
        Polygon result = tabDisplayer.getUI().getInsertTabIndication(idx);
833
        scratchPoint.setLocation(0,0);
909
        scratchPoint.setLocation(0, 0);
834
        Point p = SwingUtilities.convertPoint(tabDisplayer, scratchPoint, container);
910
        Point p = SwingUtilities.convertPoint(tabDisplayer, scratchPoint, container);
835
        result.translate (-p.x, -p.y);
911
        result.translate(-p.x, -p.y);
836
        return appendContentBoundsTo(result);
912
        return appendContentBoundsTo(result);
837
    }
913
    }
838
914
839
    private Polygon appendContentBoundsTo (Polygon p) {
915
    private Polygon appendContentBoundsTo(Polygon p) {
840
        int width = contentDisplayer.getWidth();
916
        int width = contentDisplayer.getWidth();
841
        int height = contentDisplayer.getHeight();
917
        int height = contentDisplayer.getHeight();
842
918
Lines 844-852 Link Here
844
        int[] ypoints = new int[xpoints.length];
920
        int[] ypoints = new int[xpoints.length];
845
921
846
        //XXX not handling this correctly for non-top orientations
922
        //XXX not handling this correctly for non-top orientations
847
848
        int pos = 0;
923
        int pos = 0;
849
        Object orientation = tabDisplayer.getClientProperty (TabDisplayer.PROP_ORIENTATION);
924
        Object orientation = tabDisplayer.getClientProperty(TabDisplayer.PROP_ORIENTATION);
850
925
851
        int tabsHeight = tabDisplayer.getHeight();
926
        int tabsHeight = tabDisplayer.getHeight();
852
        if (orientation == null || orientation == TabDisplayer.ORIENTATION_NORTH) {
927
        if (orientation == null || orientation == TabDisplayer.ORIENTATION_NORTH) {
Lines 856-872 Link Here
856
931
857
            pos++;
932
            pos++;
858
933
859
            xpoints[pos] = p.xpoints[p.npoints-1];
934
            xpoints[pos] = p.xpoints[p.npoints - 1];
860
            ypoints[pos] = tabsHeight;
935
            ypoints[pos] = tabsHeight;
861
            pos++;
936
            pos++;
862
937
863
            for (int i=0; i < p.npoints-2; i++) {
938
            for (int i = 0; i < p.npoints - 2; i++) {
864
                xpoints [pos] = p.xpoints[i];
939
                xpoints[pos] = p.xpoints[i];
865
                ypoints [pos] = p.ypoints[i];
940
                ypoints[pos] = p.ypoints[i];
866
                pos++;
941
                pos++;
867
            }
942
            }
868
943
869
            xpoints[pos] = xpoints[pos-1];
944
            xpoints[pos] = xpoints[pos - 1];
870
            ypoints[pos] = tabsHeight;
945
            ypoints[pos] = tabsHeight;
871
946
872
            pos++;
947
            pos++;
Lines 877-883 Link Here
877
            pos++;
952
            pos++;
878
953
879
            xpoints[pos] = width - 1;
954
            xpoints[pos] = width - 1;
880
            ypoints[pos] = height -1;
955
            ypoints[pos] = height - 1;
881
956
882
            pos++;
957
            pos++;
883
958
Lines 905-911 Link Here
905
            //Search backward for the upper right corner - we only know
980
            //Search backward for the upper right corner - we only know
906
            //the location of the left upper corner
981
            //the location of the left upper corner
907
            int highestFound = Integer.MIN_VALUE;
982
            int highestFound = Integer.MIN_VALUE;
908
            for (int i = p.npoints-2; i >= 0; i--) {
983
            for (int i = p.npoints - 2; i >= 0; i--) {
909
                if (highestFound < p.ypoints[i]) {
984
                if (highestFound < p.ypoints[i]) {
910
                    upperRight = i;
985
                    upperRight = i;
911
                    highestFound = p.ypoints[i];
986
                    highestFound = p.ypoints[i];
Lines 914-930 Link Here
914
                }
989
                }
915
            }
990
            }
916
991
917
            int curr = upperRight-1;
992
            int curr = upperRight - 1;
918
            for (int i=p.npoints-1; i >= 0; i--) {
993
            for (int i = p.npoints - 1; i >= 0; i--) {
919
                xpoints[pos] = p.xpoints[curr];
994
                xpoints[pos] = p.xpoints[curr];
920
                if (ypoints[pos] == highestFound) {
995
                if (ypoints[pos] == highestFound) {
921
                    ypoints[pos] = Math.min (tabDisplayer.getLocation().y, p.ypoints[curr] + yxlate);
996
                    ypoints[pos] = Math.min(tabDisplayer.getLocation().y, p.ypoints[curr] + yxlate);
922
                } else {
997
                } else {
923
                    ypoints[pos] = p.ypoints[curr] + yxlate;
998
                    ypoints[pos] = p.ypoints[curr] + yxlate;
924
                }
999
                }
925
                pos++;
1000
                pos++;
926
                curr++;
1001
                curr++;
927
                if (curr == p.npoints-1) {
1002
                if (curr == p.npoints - 1) {
928
                    curr = 0;
1003
                    curr = 0;
929
                }
1004
                }
930
            }
1005
            }
Lines 937-957 Link Here
937
            ypoints = p.ypoints;
1012
            ypoints = p.ypoints;
938
        }
1013
        }
939
1014
940
        Polygon result = new EqualPolygon (xpoints, ypoints, xpoints.length);
1015
        Polygon result = new EqualPolygon(xpoints, ypoints, xpoints.length);
941
        return result;
1016
        return result;
942
    }
1017
    }
943
1018
1019
    @Override
944
    public Rectangle getContentArea() {
1020
    public Rectangle getContentArea() {
945
        return contentDisplayer.getBounds();
1021
        return contentDisplayer.getBounds();
946
    }
1022
    }
947
1023
1024
    @Override
948
    public Rectangle getTabsArea() {
1025
    public Rectangle getTabsArea() {
949
        return tabDisplayer.getBounds();
1026
        return tabDisplayer.getBounds();
950
    }
1027
    }
951
1028
1029
    @Override
952
    public int dropIndexOfPoint(Point p) {
1030
    public int dropIndexOfPoint(Point p) {
953
        Point p2 = SwingUtilities.convertPoint(container, p, tabDisplayer);
1031
        Point p2 = SwingUtilities.convertPoint(container, p, tabDisplayer);
954
        return tabDisplayer.getUI().dropIndexOfPoint (p2);
1032
        return tabDisplayer.getUI().dropIndexOfPoint(p2);
955
    }
1033
    }
956
1034
957
    public Rectangle getTabsArea(Rectangle dest) {
1035
    public Rectangle getTabsArea(Rectangle dest) {
Lines 963-993 Link Here
963
     * selection and model listeners
1041
     * selection and model listeners
964
     */
1042
     */
965
    protected class ContainerComponentListener extends ComponentAdapter {
1043
    protected class ContainerComponentListener extends ComponentAdapter {
1044
966
        public ContainerComponentListener() {
1045
        public ContainerComponentListener() {
967
        }
1046
        }
968
        
1047
969
        public void componentMoved (ComponentEvent e) {
1048
        @Override
1049
        public void componentMoved(ComponentEvent e) {
970
            if (container.getType() == TabbedContainer.TYPE_SLIDING) {
1050
            if (container.getType() == TabbedContainer.TYPE_SLIDING) {
971
                updateOrientation();
1051
                updateOrientation();
972
            }
1052
            }
973
        }
1053
        }
974
        
1054
975
        public void componentResized (ComponentEvent e) {
1055
        @Override
1056
        public void componentResized(ComponentEvent e) {
976
            if (container.getType() == TabbedContainer.TYPE_SLIDING) {
1057
            if (container.getType() == TabbedContainer.TYPE_SLIDING) {
977
                updateOrientation();
1058
                updateOrientation();
978
            }
1059
            }
979
        }
1060
        }
980
    }
1061
    }
981
    
1062
982
    private boolean bug4924561knownShowing = false;
1063
    private boolean bug4924561knownShowing = false;
1064
983
    /**
1065
    /**
984
     * Calls <code>initDisplayer()</code>, then <code>attachModelAndSelectionListeners</code>,
1066
     * Calls <code>initDisplayer()</code>, then
985
     * then <code>ensureSelectedComponentIsShowing</code>
1067
     * <code>attachModelAndSelectionListeners</code>, then
1068
     * <code>ensureSelectedComponentIsShowing</code>
986
     */
1069
     */
987
    private class ContainerHierarchyListener implements HierarchyListener {
1070
    private class ContainerHierarchyListener implements HierarchyListener {
1071
988
        public ContainerHierarchyListener() {
1072
        public ContainerHierarchyListener() {
989
        }
1073
        }
990
        
1074
1075
        @Override
991
        public void hierarchyChanged(HierarchyEvent e) {
1076
        public void hierarchyChanged(HierarchyEvent e) {
992
            if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {
1077
            if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {
993
                boolean showing = container.isShowing();
1078
                boolean showing = container.isShowing();
Lines 1010-1065 Link Here
1010
            }
1095
            }
1011
        }
1096
        }
1012
    }
1097
    }
1013
    
1098
1014
    private class ToolbarTabsLayout implements LayoutManager {
1099
    private class ToolbarTabsLayout implements LayoutManager {
1015
        
1100
1101
        @Override
1016
        public void layoutContainer(Container container) {
1102
        public void layoutContainer(Container container) {
1017
            Dimension tabSize = tabDisplayer.getPreferredSize();
1103
            Dimension tabSize = tabDisplayer.getPreferredSize();
1018
            Insets ins = container.getInsets();
1104
            Insets ins = container.getInsets();
1019
            int w = container.getWidth() - (ins.left + ins.right);
1105
            int w = container.getWidth() - (ins.left + ins.right);
1020
            tabDisplayer.setBounds (ins.left, ins.top, 
1106
            tabDisplayer.setBounds(ins.left, ins.top,
1021
                w,
1107
                    w,
1022
                tabSize.height);
1108
                    tabSize.height);
1023
            if( tabDisplayer.getModel().size() > 1 ) {
1109
            if (tabDisplayer.getModel().size() > 1) {
1024
                //#214427 - check the preferred size again, during the first pass
1110
                //#214427 - check the preferred size again, during the first pass
1025
                //the tab displayer may not know the available width
1111
                //the tab displayer may not know the available width
1026
                Dimension newTabSize = tabDisplayer.getPreferredSize();
1112
                Dimension newTabSize = tabDisplayer.getPreferredSize();
1027
                if( newTabSize.height != tabSize.height ) {
1113
                if (newTabSize.height != tabSize.height) {
1028
                    tabSize = newTabSize;
1114
                    tabSize = newTabSize;
1029
                    tabDisplayer.setBounds (ins.left, ins.top,
1115
                    tabDisplayer.setBounds(ins.left, ins.top,
1030
                        w,
1116
                            w,
1031
                        tabSize.height);
1117
                            tabSize.height);
1032
                }
1118
                }
1033
            }
1119
            }
1034
            contentDisplayer.setBounds(ins.left, 
1120
            contentDisplayer.setBounds(ins.left,
1035
                ins.top + tabSize.height, w,
1121
                    ins.top + tabSize.height, w,
1036
                container.getHeight() - (ins.top + ins.bottom + tabSize.height));
1122
                    container.getHeight() - (ins.top + ins.bottom + tabSize.height));
1037
        }
1123
        }
1038
        
1124
1125
        @Override
1039
        public Dimension minimumLayoutSize(Container container) {
1126
        public Dimension minimumLayoutSize(Container container) {
1040
            Dimension tabSize = tabDisplayer.getMinimumSize();
1127
            Dimension tabSize = tabDisplayer.getMinimumSize();
1041
            Dimension contentSize = contentDisplayer.getMinimumSize();
1128
            Dimension contentSize = contentDisplayer.getMinimumSize();
1042
            Insets ins = container.getInsets();
1129
            Insets ins = container.getInsets();
1043
            Dimension result = new Dimension(ins.left + ins.top, ins.right + ins.bottom);
1130
            Dimension result = new Dimension(ins.left + ins.top, ins.right + ins.bottom);
1044
            result.width += Math.max (tabSize.width, contentSize.width);
1131
            result.width += Math.max(tabSize.width, contentSize.width);
1045
            result.height += tabSize.height + contentSize.height;
1132
            result.height += tabSize.height + contentSize.height;
1046
            return result;
1133
            return result;
1047
        }
1134
        }
1048
        
1135
1136
        @Override
1049
        public Dimension preferredLayoutSize(Container container) {
1137
        public Dimension preferredLayoutSize(Container container) {
1050
            Dimension tabSize = tabDisplayer.getPreferredSize();
1138
            Dimension tabSize = tabDisplayer.getPreferredSize();
1051
            Dimension contentSize = contentDisplayer.getPreferredSize();
1139
            Dimension contentSize = contentDisplayer.getPreferredSize();
1052
            Insets ins = container.getInsets();
1140
            Insets ins = container.getInsets();
1053
            Dimension result = new Dimension(ins.left + ins.top, ins.right + ins.bottom);
1141
            Dimension result = new Dimension(ins.left + ins.top, ins.right + ins.bottom);
1054
            result.width += Math.max (tabSize.width, contentSize.width);
1142
            result.width += Math.max(tabSize.width, contentSize.width);
1055
            result.height += tabSize.height + contentSize.height;
1143
            result.height += tabSize.height + contentSize.height;
1056
            return result;
1144
            return result;
1057
        }
1145
        }
1058
        
1146
1147
        @Override
1059
        public void removeLayoutComponent(Component component) {
1148
        public void removeLayoutComponent(Component component) {
1060
            //do nothing
1149
            //do nothing
1061
        }
1150
        }
1062
        
1151
1152
        @Override
1063
        public void addLayoutComponent(String str, Component component) {
1153
        public void addLayoutComponent(String str, Component component) {
1064
            //do nothing
1154
            //do nothing
1065
        }
1155
        }
Lines 1071-1093 Link Here
1071
     * model
1161
     * model
1072
     */
1162
     */
1073
    protected class SelectionListener implements ChangeListener {
1163
    protected class SelectionListener implements ChangeListener {
1164
1074
        public SelectionListener() {
1165
        public SelectionListener() {
1075
        }
1166
        }
1076
1167
1168
        @Override
1077
        public void stateChanged(ChangeEvent e) {
1169
        public void stateChanged(ChangeEvent e) {
1078
            if (container.isShowing() 
1170
            if (container.isShowing()
1079
             //a special case for property sheet dialog window - the selection 
1171
                    //a special case for property sheet dialog window - the selection 
1080
             //change must be processed otherwise the tabbed container may have
1172
                    //change must be processed otherwise the tabbed container may have
1081
             //undefined preferred size so the property window will be too small
1173
                    //undefined preferred size so the property window will be too small
1082
             || container.getClientProperty("tc") != null) { //NOI18N
1174
                    || container.getClientProperty("tc") != null) { //NOI18N
1083
                int idx = tabDisplayer.getSelectionModel().getSelectedIndex();
1175
                int idx = tabDisplayer.getSelectionModel().getSelectedIndex();
1084
                if (idx != -1) {
1176
                if (idx != -1) {
1085
                    Component c = toComp(container.getModel().getTab(idx));
1177
                    Component c = toComp(container.getModel().getTab(idx));
1086
                    c.setBounds(0, 0, contentDisplayer.getWidth(),
1178
                    c.setBounds(0, 0, contentDisplayer.getWidth(),
1087
                                contentDisplayer.getHeight());
1179
                            contentDisplayer.getHeight());
1088
                    showComponentWithFxProvider(c);
1180
                    showComponentWithFxProvider(c);
1089
                } else {
1181
                } else {
1090
                    showComponent (null);
1182
                    showComponent(null);
1091
                }
1183
                }
1092
            }
1184
            }
1093
        }
1185
        }
Lines 1098-1103 Link Here
1098
     * displayer up-to-date with the contents of the data model.
1190
     * displayer up-to-date with the contents of the data model.
1099
     */
1191
     */
1100
    protected class ModelListener implements ComplexListDataListener {
1192
    protected class ModelListener implements ComplexListDataListener {
1193
1101
        public ModelListener() {
1194
        public ModelListener() {
1102
        }
1195
        }
1103
1196
Lines 1105-1110 Link Here
1105
         * DefaultTabDataModel will always call this method with an instance of
1198
         * DefaultTabDataModel will always call this method with an instance of
1106
         * ComplexListDataEvent.
1199
         * ComplexListDataEvent.
1107
         */
1200
         */
1201
        @Override
1108
        public void contentsChanged(ListDataEvent e) {
1202
        public void contentsChanged(ListDataEvent e) {
1109
            //Only need to reread components on setTab (does winsys even use it?)
1203
            //Only need to reread components on setTab (does winsys even use it?)
1110
            if (e instanceof ComplexListDataEvent) {
1204
            if (e instanceof ComplexListDataEvent) {
Lines 1115-1128 Link Here
1115
                            index);
1209
                            index);
1116
                    Component nue = toComp(tabDisplayer.getModel().getTab(index));
1210
                    Component nue = toComp(tabDisplayer.getModel().getTab(index));
1117
                    contentDisplayer.remove(comp);
1211
                    contentDisplayer.remove(comp);
1118
                    
1212
1119
                    boolean add = 
1213
                    boolean add
1120
                        container.getContentPolicy() == 
1214
                            = container.getContentPolicy()
1121
                        TabbedContainer.CONTENT_POLICY_ADD_ALL || 
1215
                            == TabbedContainer.CONTENT_POLICY_ADD_ALL
1122
                        index == 
1216
                            || index
1123
                        container.getSelectionModel().getSelectedIndex();
1217
                            == container.getSelectionModel().getSelectedIndex();
1124
                    
1218
1125
                    if (add) {
1219
                    if (add) {
1220
                        if (nue.getParent() != null) {
1221
                            nue.getParent().remove(nue);
1222
                        }
1126
                        contentDisplayer.add(nue, index);
1223
                        contentDisplayer.add(nue, index);
1127
                    }
1224
                    }
1128
                }
1225
                }
Lines 1134-1140 Link Here
1134
1231
1135
        /**
1232
        /**
1136
         * This method is called to scroll the selected tab into view if its
1233
         * This method is called to scroll the selected tab into view if its
1137
         * title changes (it may be scrolled offscreen).  NetBeans' editor uses
1234
         * title changes (it may be scrolled offscreen). NetBeans' editor uses
1138
         * this to ensure that the user can see what file they're editing when
1235
         * this to ensure that the user can see what file they're editing when
1139
         * the user starts typing (this triggers a * being appended to the tab
1236
         * the user starts typing (this triggers a * being appended to the tab
1140
         * title, thus triggering this call).
1237
         * title, thus triggering this call).
Lines 1156-1172 Link Here
1156
            }
1253
            }
1157
        }
1254
        }
1158
1255
1159
1256
        @Override
1160
        public void intervalAdded(ListDataEvent e) {
1257
        public void intervalAdded(ListDataEvent e) {
1161
            if (container.getContentPolicy() == TabbedContainer.CONTENT_POLICY_ADD_ALL) {
1258
            if (container.getContentPolicy() == TabbedContainer.CONTENT_POLICY_ADD_ALL) {
1162
                Component curC = null;
1259
                Component curC = null;
1163
                for (int i = e.getIndex0(); i <= e.getIndex1(); i++) {
1260
                for (int i = e.getIndex0(); i <= e.getIndex1(); i++) {
1164
                    curC = toComp(container.getModel().getTab(i));
1261
                    curC = toComp(container.getModel().getTab(i));
1262
                    if (curC.getParent() != null) {
1263
                        curC.getParent().remove(curC);
1264
                    }
1165
                    contentDisplayer.add(curC, "");
1265
                    contentDisplayer.add(curC, "");
1166
                }
1266
                }
1167
            }
1267
            }
1168
        }
1268
        }
1169
1269
1270
        @Override
1170
        public void intervalRemoved(ListDataEvent e) {
1271
        public void intervalRemoved(ListDataEvent e) {
1171
            //  we know that it must be complex data event
1272
            //  we know that it must be complex data event
1172
            ComplexListDataEvent clde = (ComplexListDataEvent) e;
1273
            ComplexListDataEvent clde = (ComplexListDataEvent) e;
Lines 1178-1194 Link Here
1178
            }
1279
            }
1179
        }
1280
        }
1180
1281
1282
        @Override
1181
        public void indicesAdded(ComplexListDataEvent e) {
1283
        public void indicesAdded(ComplexListDataEvent e) {
1182
            Component curC = null;
1284
            Component curC = null;
1183
            if (container.getContentPolicy() == TabbedContainer.CONTENT_POLICY_ADD_ALL) {
1285
            if (container.getContentPolicy() == TabbedContainer.CONTENT_POLICY_ADD_ALL) {
1184
                int[] indices = e.getIndices();
1286
                int[] indices = e.getIndices();
1185
                for (int i = 0; i < indices.length; i++) {
1287
                for (int i = 0; i < indices.length; i++) {
1186
                    curC = toComp(container.getModel().getTab(indices[i]));
1288
                    curC = toComp(container.getModel().getTab(indices[i]));
1289
                    if (curC.getParent() != null) {
1290
                        curC.getParent().remove(curC);
1291
                    }
1187
                    contentDisplayer.add(curC, "");
1292
                    contentDisplayer.add(curC, "");
1188
                }
1293
                }
1189
            }
1294
            }
1190
        }
1295
        }
1191
1296
1297
        @Override
1192
        public void indicesRemoved(ComplexListDataEvent e) {
1298
        public void indicesRemoved(ComplexListDataEvent e) {
1193
            int[] indices = e.getIndices();
1299
            int[] indices = e.getIndices();
1194
            TabData[] removedTabs = e.getAffectedItems();
1300
            TabData[] removedTabs = e.getAffectedItems();
Lines 1200-1205 Link Here
1200
            }
1306
            }
1201
        }
1307
        }
1202
1308
1309
        @Override
1203
        public void indicesChanged(ComplexListDataEvent e) {
1310
        public void indicesChanged(ComplexListDataEvent e) {
1204
            //XXX - if we keep contentPolicies, this could be simplified for
1311
            //XXX - if we keep contentPolicies, this could be simplified for
1205
            //the non ADD_ALL policies
1312
            //the non ADD_ALL policies
Lines 1245-1253 Link Here
1245
                            }
1352
                            }
1246
                        }
1353
                        }
1247
                    }
1354
                    }
1248
                    
1355
1249
                    if (container.getContentPolicy() == TabbedContainer.CONTENT_POLICY_ADD_ALL) {
1356
                    if (container.getContentPolicy() == TabbedContainer.CONTENT_POLICY_ADD_ALL) {
1250
                    
1357
1251
                        //See if we've got anything to add
1358
                        //See if we've got anything to add
1252
                        if (!added.isEmpty()) {
1359
                        if (!added.isEmpty()) {
1253
                            Iterator i = added.iterator();
1360
                            Iterator i = added.iterator();
Lines 1260-1266 Link Here
1260
                                //extra work
1367
                                //extra work
1261
                                if (!contentDisplayer.isAncestorOf(
1368
                                if (!contentDisplayer.isAncestorOf(
1262
                                        toComp(add))) {
1369
                                        toComp(add))) {
1263
                                    contentDisplayer.add(toComp(add), "");
1370
                                    Component curC = toComp(add);
1371
                                    if (curC.getParent() != null) {
1372
                                        curC.getParent().remove(curC);
1373
                                    }
1374
                                    contentDisplayer.add(curC, "");
1264
                                    changed = true;
1375
                                    changed = true;
1265
                                }
1376
                                }
1266
                            }
1377
                            }
Lines 1276-1287 Link Here
1276
        }
1387
        }
1277
    }
1388
    }
1278
1389
1279
    /** An action listener which listens on action events from the tab displayer (select, close, etc.)
1390
    /**
1280
     * and propagates them to the tabbed container's action posting mechanism, so listeners on it also
1391
     * An action listener which listens on action events from the tab displayer
1281
     * have an opportunity to veto undesired actions, or handle actions themselves.
1392
     * (select, close, etc.) and propagates them to the tabbed container's
1393
     * action posting mechanism, so listeners on it also have an opportunity to
1394
     * veto undesired actions, or handle actions themselves.
1282
     */
1395
     */
1283
    private class DisplayerActionListener implements ActionListener {
1396
    private class DisplayerActionListener implements ActionListener {
1284
        public void actionPerformed (ActionEvent ae) {
1397
1398
        @Override
1399
        public void actionPerformed(ActionEvent ae) {
1285
            TabActionEvent tae = (TabActionEvent) ae;
1400
            TabActionEvent tae = (TabActionEvent) ae;
1286
            if (!shouldPerformAction(tae.getActionCommand(), tae.getTabIndex(), tae.getMouseEvent())) {
1401
            if (!shouldPerformAction(tae.getActionCommand(), tae.getTabIndex(), tae.getMouseEvent())) {
1287
                tae.consume();
1402
                tae.consume();
Lines 1290-1405 Link Here
1290
    }
1405
    }
1291
1406
1292
    private class SlidingTabsLayout implements LayoutManager {
1407
    private class SlidingTabsLayout implements LayoutManager {
1293
        
1408
1409
        @Override
1294
        public void addLayoutComponent(String name, Component comp) {
1410
        public void addLayoutComponent(String name, Component comp) {
1295
            //do nothing
1411
            //do nothing
1296
        }
1412
        }
1297
        
1413
1414
        @Override
1298
        public void layoutContainer(Container parent) {
1415
        public void layoutContainer(Container parent) {
1299
            JComponent c = tabDisplayer;
1416
            JComponent c = tabDisplayer;
1300
            
1417
1301
            Object orientation = c.getClientProperty (
1418
            Object orientation = c.getClientProperty(
1302
                TabDisplayer.PROP_ORIENTATION);
1419
                    TabDisplayer.PROP_ORIENTATION);
1303
            
1420
1304
            Dimension d = tabDisplayer.getPreferredSize();
1421
            Dimension d = tabDisplayer.getPreferredSize();
1305
            Insets ins = container.getInsets();
1422
            Insets ins = container.getInsets();
1306
            int width = parent.getWidth() - (ins.left + ins.right);
1423
            int width = parent.getWidth() - (ins.left + ins.right);
1307
            int height = parent.getHeight() - (ins.top + ins.bottom);
1424
            int height = parent.getHeight() - (ins.top + ins.bottom);
1308
            
1425
1309
            if (orientation == TabDisplayer.ORIENTATION_NORTH) {
1426
            if (orientation == TabDisplayer.ORIENTATION_NORTH) {
1310
                c.setBounds (ins.left, ins.top, 
1427
                c.setBounds(ins.left, ins.top,
1311
                    width, d.height);
1428
                        width, d.height);
1312
                
1429
1313
                contentDisplayer.setBounds (ins.left, ins.top + d.height, 
1430
                contentDisplayer.setBounds(ins.left, ins.top + d.height,
1314
                    width, 
1431
                        width,
1315
                    parent.getHeight() - (d.height + ins.top + ins.bottom));
1432
                        parent.getHeight() - (d.height + ins.top + ins.bottom));
1316
                
1433
1317
            } else if (orientation == TabDisplayer.ORIENTATION_SOUTH) {
1434
            } else if (orientation == TabDisplayer.ORIENTATION_SOUTH) {
1318
                contentDisplayer.setBounds (ins.top, ins.left, width, 
1435
                contentDisplayer.setBounds(ins.top, ins.left, width,
1319
                    parent.getHeight() - (d.height + ins.top + ins.bottom));
1436
                        parent.getHeight() - (d.height + ins.top + ins.bottom));
1320
                
1437
1321
                c.setBounds (ins.left, parent.getHeight() - (d.height + ins.top + ins.bottom),
1438
                c.setBounds(ins.left, parent.getHeight() - (d.height + ins.top + ins.bottom),
1322
                    width, d.height);
1439
                        width, d.height);
1323
            } else if (orientation == TabDisplayer.ORIENTATION_EAST) {
1440
            } else if (orientation == TabDisplayer.ORIENTATION_EAST) {
1324
                contentDisplayer.setBounds (ins.left, ins.top, width - d.width,
1441
                contentDisplayer.setBounds(ins.left, ins.top, width - d.width,
1325
                    height);
1442
                        height);
1326
                
1443
1327
                c.setBounds (parent.getWidth() - (ins.right + d.width), ins.top, 
1444
                c.setBounds(parent.getWidth() - (ins.right + d.width), ins.top,
1328
                    d.width, height);
1445
                        d.width, height);
1329
                
1446
1330
            } else if (orientation == TabDisplayer.ORIENTATION_WEST) {
1447
            } else if (orientation == TabDisplayer.ORIENTATION_WEST) {
1331
                c.setBounds (ins.left, ins.top, d.width, height);
1448
                c.setBounds(ins.left, ins.top, d.width, height);
1332
                
1449
1333
                contentDisplayer.setBounds (ins.left + d.width, ins.top, 
1450
                contentDisplayer.setBounds(ins.left + d.width, ins.top,
1334
                    width - d.width, height);
1451
                        width - d.width, height);
1335
                
1452
1336
            } else {
1453
            } else {
1337
                throw new IllegalArgumentException ("Unknown orientation: " + orientation);
1454
                throw new IllegalArgumentException("Unknown orientation: " + orientation);
1338
            }
1455
            }
1339
        }
1456
        }
1340
        
1457
1458
        @Override
1341
        public Dimension minimumLayoutSize(Container parent) {
1459
        public Dimension minimumLayoutSize(Container parent) {
1342
            JComponent c = tabDisplayer;
1460
            JComponent c = tabDisplayer;
1343
            
1461
1344
            Object orientation = c.getClientProperty (
1462
            Object orientation = c.getClientProperty(
1345
                TabDisplayer.PROP_ORIENTATION);
1463
                    TabDisplayer.PROP_ORIENTATION);
1346
            
1464
1347
            Dimension tabSize = tabDisplayer.getPreferredSize();
1465
            Dimension tabSize = tabDisplayer.getPreferredSize();
1348
            Insets ins = container.getInsets();
1466
            Insets ins = container.getInsets();
1349
            
1467
1350
            Dimension result = new Dimension();
1468
            Dimension result = new Dimension();
1351
            
1469
1352
            Dimension contentSize = contentDisplayer.getPreferredSize();
1470
            Dimension contentSize = contentDisplayer.getPreferredSize();
1353
            if (tabDisplayer.getSelectionModel().getSelectedIndex() == -1) {
1471
            if (tabDisplayer.getSelectionModel().getSelectedIndex() == -1) {
1354
                contentSize.width = 0;
1472
                contentSize.width = 0;
1355
                contentSize.height = 0;
1473
                contentSize.height = 0;
1356
            }
1474
            }
1357
            
1475
1358
            if (orientation == TabDisplayer.ORIENTATION_NORTH || orientation == TabDisplayer.ORIENTATION_SOUTH) {
1476
            if (orientation == TabDisplayer.ORIENTATION_NORTH || orientation == TabDisplayer.ORIENTATION_SOUTH) {
1359
                result.height = ins.top + ins.bottom + contentSize.height + tabSize.height;
1477
                result.height = ins.top + ins.bottom + contentSize.height + tabSize.height;
1360
                result.width = ins.left + ins.right + Math.max (contentSize.width, tabSize.width);
1478
                result.width = ins.left + ins.right + Math.max(contentSize.width, tabSize.width);
1361
            } else {
1479
            } else {
1362
                result.width = ins.left + ins.right + contentSize.width + tabSize.width;
1480
                result.width = ins.left + ins.right + contentSize.width + tabSize.width;
1363
                result.height = ins.top + ins.bottom + Math.max (contentSize.height, tabSize.height);
1481
                result.height = ins.top + ins.bottom + Math.max(contentSize.height, tabSize.height);
1364
            }
1482
            }
1365
            return result;
1483
            return result;
1366
        }
1484
        }
1367
        
1485
1486
        @Override
1368
        public Dimension preferredLayoutSize(Container parent) {
1487
        public Dimension preferredLayoutSize(Container parent) {
1369
            return minimumLayoutSize(parent);
1488
            return minimumLayoutSize(parent);
1370
        }
1489
        }
1371
        
1490
1491
        @Override
1372
        public void removeLayoutComponent(Component comp) {
1492
        public void removeLayoutComponent(Component comp) {
1373
            //do nothing
1493
            //do nothing
1374
        }
1494
        }
1375
    }
1495
    }
1376
    
1496
1377
    /** A FxProvider which simply calls finish() from its start
1497
    /**
1378
     * method, providing no effects whatsoever */
1498
     * A FxProvider which simply calls finish() from its start method, providing
1499
     * no effects whatsoever
1500
     */
1379
    private final class NoOpFxProvider extends FxProvider {
1501
    private final class NoOpFxProvider extends FxProvider {
1380
        
1502
1503
        @Override
1381
        public void cleanup() {
1504
        public void cleanup() {
1382
            //Do nothing
1505
            //Do nothing
1383
        }
1506
        }
1384
        
1507
1508
        @Override
1385
        protected void doFinish() {
1509
        protected void doFinish() {
1386
            showComponent (comp);
1510
            showComponent(comp);
1387
            
1511
1388
        }
1512
        }
1389
        
1513
1514
        @Override
1390
        protected void doStart() {
1515
        protected void doStart() {
1391
            finish();
1516
            finish();
1392
        }
1517
        }
1393
    }
1518
    }
1394
    
1519
1395
    private final class ImageSlideFxProvider extends FxProvider implements ActionListener {
1520
    private final class ImageSlideFxProvider extends FxProvider implements ActionListener {
1521
1396
        private Timer timer = null;
1522
        private Timer timer = null;
1397
        private Component prevGlassPane = null;
1523
        private Component prevGlassPane = null;
1398
        private Dimension d = null;
1524
        private Dimension d = null;
1399
        
1525
1526
        @Override
1400
        protected void doStart() {
1527
        protected void doStart() {
1401
            if (timer == null) {
1528
            if (timer == null) {
1402
                timer = new Timer (TIMER, this);
1529
                timer = new Timer(TIMER, this);
1403
                timer.setRepeats(true);
1530
                timer.setRepeats(true);
1404
            }
1531
            }
1405
1532
Lines 1413-1429 Link Here
1413
1540
1414
            initSize();
1541
            initSize();
1415
            img = createImageOfComponent();
1542
            img = createImageOfComponent();
1416
            
1417
1543
1418
            ImageScalingGlassPane cp = getCustomGlassPane();
1544
            ImageScalingGlassPane cp = getCustomGlassPane();
1419
            root.setGlassPane (cp);
1545
            root.setGlassPane(cp);
1420
            cp.setIncrement (0.1f);
1546
            cp.setIncrement(0.1f);
1421
            cp.setBounds (root.getBounds());
1547
            cp.setBounds(root.getBounds());
1422
            cp.setVisible(true);
1548
            cp.setVisible(true);
1423
            cp.revalidate();
1549
            cp.revalidate();
1424
            timer.start();            
1550
            timer.start();
1425
        }
1551
        }
1426
        
1552
1553
        @Override
1427
        public void cleanup() {
1554
        public void cleanup() {
1428
            timer.stop();
1555
            timer.stop();
1429
            root.setGlassPane(prevGlassPane);
1556
            root.setGlassPane(prevGlassPane);
Lines 1433-1455 Link Here
1433
            }
1560
            }
1434
            img = null;
1561
            img = null;
1435
        }
1562
        }
1436
        
1563
1564
        @Override
1437
        protected void doFinish() {
1565
        protected void doFinish() {
1438
            showComponent (comp);
1566
            showComponent(comp);
1439
        }
1567
        }
1440
        
1568
1441
        private void initSize() {
1569
        private void initSize() {
1442
            d = comp.getPreferredSize();
1570
            d = comp.getPreferredSize();
1443
            
1571
1444
            Dimension d2 = contentDisplayer.getSize();
1572
            Dimension d2 = contentDisplayer.getSize();
1445
            
1446
            d.width = Math.max (d2.width, d.width);
1447
            d.height = Math.max (d2.height, d.height);
1448
1573
1449
            
1574
            d.width = Math.max(d2.width, d.width);
1450
            boolean flip = orientation == TabDisplayer.ORIENTATION_EAST || 
1575
            d.height = Math.max(d2.height, d.height);
1451
                orientation == TabDisplayer.ORIENTATION_WEST;
1576
1452
            
1577
            boolean flip = orientation == TabDisplayer.ORIENTATION_EAST
1578
                    || orientation == TabDisplayer.ORIENTATION_WEST;
1579
1453
            if (d.width == 0 || d.height == 0) {
1580
            if (d.width == 0 || d.height == 0) {
1454
                if (flip) {
1581
                if (flip) {
1455
                    d.width = root.getWidth();
1582
                    d.width = root.getWidth();
Lines 1460-1473 Link Here
1460
                }
1587
                }
1461
            } else {
1588
            } else {
1462
                if (flip) {
1589
                if (flip) {
1463
                    d.height = Math.max (d.height, tabDisplayer.getHeight());
1590
                    d.height = Math.max(d.height, tabDisplayer.getHeight());
1464
                } else {
1591
                } else {
1465
                    d.width = Math.max (d.width, tabDisplayer.getWidth());
1592
                    d.width = Math.max(d.width, tabDisplayer.getWidth());
1466
                }
1593
                }
1467
            }
1594
            }
1468
        }        
1595
        }
1469
1596
1470
        private BufferedImage img = null;
1597
        private BufferedImage img = null;
1598
1471
        private BufferedImage createImageOfComponent() {
1599
        private BufferedImage createImageOfComponent() {
1472
            if (USE_SWINGPAINTING) {
1600
            if (USE_SWINGPAINTING) {
1473
                return null;
1601
                return null;
Lines 1478-1507 Link Here
1478
                finish();
1606
                finish();
1479
            }
1607
            }
1480
1608
1481
            BufferedImage img =
1609
            BufferedImage img
1482
                GraphicsEnvironment.getLocalGraphicsEnvironment().
1610
                    = GraphicsEnvironment.getLocalGraphicsEnvironment().
1483
                    getDefaultScreenDevice().getDefaultConfiguration().
1611
                    getDefaultScreenDevice().getDefaultConfiguration().
1484
                    createCompatibleImage(d.width, d.height);
1612
                    createCompatibleImage(d.width, d.height);
1485
            
1613
1486
            Graphics2D g2d = img.createGraphics();
1614
            Graphics2D g2d = img.createGraphics();
1487
            JComponent c = tabDisplayer;
1615
            JComponent c = tabDisplayer;
1488
            
1616
1489
            c.setBounds (0, 0, d.width, d.height);
1617
            c.setBounds(0, 0, d.width, d.height);
1490
            comp.paint (g2d);
1618
            comp.paint(g2d);
1491
1619
1492
            return img;
1620
            return img;
1493
        }        
1621
        }
1494
        
1622
1623
        @Override
1495
        public void actionPerformed(java.awt.event.ActionEvent e) {
1624
        public void actionPerformed(java.awt.event.ActionEvent e) {
1496
            float inc = customGlassPane.getIncrement();
1625
            float inc = customGlassPane.getIncrement();
1497
            if (inc >= 1.0f) {
1626
            if (inc >= 1.0f) {
1498
                finish();
1627
                finish();
1499
            } else {
1628
            } else {
1500
                customGlassPane.setIncrement (inc + INCREMENT);
1629
                customGlassPane.setIncrement(inc + INCREMENT);
1501
            }
1630
            }
1502
        }
1631
        }
1503
        
1632
1504
        private ImageScalingGlassPane customGlassPane = null;
1633
        private ImageScalingGlassPane customGlassPane = null;
1634
1505
        private ImageScalingGlassPane getCustomGlassPane() {
1635
        private ImageScalingGlassPane getCustomGlassPane() {
1506
            if (customGlassPane == null) {
1636
            if (customGlassPane == null) {
1507
                customGlassPane = new ImageScalingGlassPane();
1637
                customGlassPane = new ImageScalingGlassPane();
Lines 1509-1555 Link Here
1509
            }
1639
            }
1510
            return customGlassPane;
1640
            return customGlassPane;
1511
        }
1641
        }
1512
        
1642
1513
        private class ImageScalingGlassPane extends JPanel {
1643
        private class ImageScalingGlassPane extends JPanel {
1644
1514
            private float inc = 0f;
1645
            private float inc = 0f;
1515
            private Rectangle rect = new Rectangle();
1646
            private Rectangle rect = new Rectangle();
1516
            private Rectangle r2 = new Rectangle();
1647
            private Rectangle r2 = new Rectangle();
1517
            private boolean changed = true;
1648
            private boolean changed = true;
1518
            
1649
1519
            private void setIncrement (float inc) {
1650
            private void setIncrement(float inc) {
1520
                this.inc = inc;
1651
                this.inc = inc;
1521
                changed = true;
1652
                changed = true;
1522
                if (isShowing()) {
1653
                if (isShowing()) {
1523
                    Rectangle r = getImageBounds();
1654
                    Rectangle r = getImageBounds();
1524
                    if (SYNCHRONOUS_PAINTING) {
1655
                    if (SYNCHRONOUS_PAINTING) {
1525
                        paintImmediately (r.x, r.y, r.width, r.height);
1656
                        paintImmediately(r.x, r.y, r.width, r.height);
1526
                    } else {
1657
                    } else {
1527
                        repaint(r.x, r.y, r.width, r.height);
1658
                        repaint(r.x, r.y, r.width, r.height);
1528
                    }
1659
                    }
1529
                }
1660
                }
1530
            }
1661
            }
1531
            
1662
1532
            private float getIncrement () {
1663
            private float getIncrement() {
1533
                return inc;
1664
                return inc;
1534
            }
1665
            }
1535
            
1666
1536
            private Rectangle getImageBounds() {
1667
            private Rectangle getImageBounds() {
1537
                if (!changed) {
1668
                if (!changed) {
1538
                    return rect;
1669
                    return rect;
1539
                }
1670
                }
1540
                Component c = tabDisplayer;
1671
                Component c = tabDisplayer;
1541
                r2.setBounds (0, 0, c.getWidth(), c.getHeight());
1672
                r2.setBounds(0, 0, c.getWidth(), c.getHeight());
1542
                
1673
1543
                Rectangle dispBounds = SwingUtilities.convertRectangle(c, r2, 
1674
                Rectangle dispBounds = SwingUtilities.convertRectangle(c, r2,
1544
                    this);
1675
                        this);
1545
                
1676
1546
                if (orientation == TabDisplayer.ORIENTATION_WEST) {
1677
                if (orientation == TabDisplayer.ORIENTATION_WEST) {
1547
                    rect.x = dispBounds.x + dispBounds.width;
1678
                    rect.x = dispBounds.x + dispBounds.width;
1548
                    rect.y = dispBounds.y;
1679
                    rect.y = dispBounds.y;
1549
                    rect.width = Math.round (inc * d.width);
1680
                    rect.width = Math.round(inc * d.width);
1550
                    rect.height = dispBounds.height;
1681
                    rect.height = dispBounds.height;
1551
                } else if (orientation == TabDisplayer.ORIENTATION_EAST) {
1682
                } else if (orientation == TabDisplayer.ORIENTATION_EAST) {
1552
                    rect.width = Math.round (inc * d.width);
1683
                    rect.width = Math.round(inc * d.width);
1553
                    rect.height = dispBounds.height;
1684
                    rect.height = dispBounds.height;
1554
                    rect.x = dispBounds.x - rect.width;
1685
                    rect.x = dispBounds.x - rect.width;
1555
                    rect.y = dispBounds.y;
1686
                    rect.y = dispBounds.y;
Lines 1567-1573 Link Here
1567
                changed = false;
1698
                changed = false;
1568
                return rect;
1699
                return rect;
1569
            }
1700
            }
1570
            
1701
1702
            @Override
1571
            public void paint(Graphics g) {
1703
            public void paint(Graphics g) {
1572
                try {
1704
                try {
1573
                    if (USE_SWINGPAINTING) {
1705
                    if (USE_SWINGPAINTING) {
Lines 1577-1592 Link Here
1577
                        Composite comp = null;
1709
                        Composite comp = null;
1578
                        if (true) {
1710
                        if (true) {
1579
                            comp = g2d.getComposite();
1711
                            comp = g2d.getComposite();
1580
                            g2d.setComposite (AlphaComposite.getInstance(AlphaComposite.SRC_OVER, Math.min(0.99f, inc)));
1712
                            g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, Math.min(0.99f, inc)));
1581
                        }
1713
                        }
1582
                        Rectangle r = getImageBounds();
1714
                        Rectangle r = getImageBounds();
1583
                        if (NO_SCALE) {
1715
                        if (NO_SCALE) {
1584
                            AffineTransform at = AffineTransform.getTranslateInstance(r.x, r.y);
1716
                            AffineTransform at = AffineTransform.getTranslateInstance(r.x, r.y);
1585
                            g2d.drawRenderedImage(img, at);
1717
                            g2d.drawRenderedImage(img, at);
1586
                        } else {
1718
                        } else {
1587
                            g2d.drawImage (img, r.x, r.y, r.x + r.width,
1719
                            g2d.drawImage(img, r.x, r.y, r.x + r.width,
1588
                                r.y + r.height, 0, 0, d.width, d.height,
1720
                                    r.y + r.height, 0, 0, d.width, d.height,
1589
                                getBackground(), null);
1721
                                    getBackground(), null);
1590
                        }
1722
                        }
1591
                        if (comp != null) {
1723
                        if (comp != null) {
1592
                            g2d.setComposite(comp);
1724
                            g2d.setComposite(comp);
Lines 1600-1615 Link Here
1600
            }
1732
            }
1601
        }
1733
        }
1602
    }
1734
    }
1603
    
1604
1735
1605
    private final class LiveComponentSlideFxProvider extends FxProvider implements ActionListener {
1736
    private final class LiveComponentSlideFxProvider extends FxProvider implements ActionListener {
1737
1606
        private Timer timer = null;
1738
        private Timer timer = null;
1607
        private Component prevGlassPane = null;
1739
        private Component prevGlassPane = null;
1608
        private Dimension d = null;
1740
        private Dimension d = null;
1609
1741
1742
        @Override
1610
        protected void doStart() {
1743
        protected void doStart() {
1611
            if (timer == null) {
1744
            if (timer == null) {
1612
                timer = new Timer (TIMER, this);
1745
                timer = new Timer(TIMER, this);
1613
                timer.setRepeats(true);
1746
                timer.setRepeats(true);
1614
            }
1747
            }
1615
1748
Lines 1622-1646 Link Here
1622
1755
1623
            initSize();
1756
            initSize();
1624
            LiveComponentResizingGlassPane cp = getCustomGlassPane();
1757
            LiveComponentResizingGlassPane cp = getCustomGlassPane();
1625
            root.setGlassPane (cp);
1758
            root.setGlassPane(cp);
1626
            cp.setIncrement (0.1f);
1759
            cp.setIncrement(0.1f);
1627
            cp.setBounds (root.getBounds());
1760
            cp.setBounds(root.getBounds());
1628
            cp.setVisible(true);
1761
            cp.setVisible(true);
1629
            cp.revalidate();
1762
            cp.revalidate();
1630
            timer.start();
1763
            timer.start();
1631
        }
1764
        }
1632
        
1765
1633
        private void initSize() {
1766
        private void initSize() {
1634
            d = comp.getPreferredSize();
1767
            d = comp.getPreferredSize();
1635
            
1768
1636
            Dimension d2 = contentDisplayer.getSize();
1769
            Dimension d2 = contentDisplayer.getSize();
1637
            
1770
1638
            d.width = Math.max (d2.width, d.width);
1771
            d.width = Math.max(d2.width, d.width);
1639
            d.height = Math.max (d2.height, d.height);
1772
            d.height = Math.max(d2.height, d.height);
1640
            
1773
1641
            boolean flip = orientation == TabDisplayer.ORIENTATION_EAST || 
1774
            boolean flip = orientation == TabDisplayer.ORIENTATION_EAST
1642
                orientation == TabDisplayer.ORIENTATION_WEST;
1775
                    || orientation == TabDisplayer.ORIENTATION_WEST;
1643
            
1776
1644
            if (d.width == 0 || d.height == 0) {
1777
            if (d.width == 0 || d.height == 0) {
1645
                if (flip) {
1778
                if (flip) {
1646
                    d.width = root.getWidth();
1779
                    d.width = root.getWidth();
Lines 1651-1684 Link Here
1651
                }
1784
                }
1652
            } else {
1785
            } else {
1653
                if (flip) {
1786
                if (flip) {
1654
                    d.height = Math.max (d.height, tabDisplayer.getHeight());
1787
                    d.height = Math.max(d.height, tabDisplayer.getHeight());
1655
                } else {
1788
                } else {
1656
                    d.width = Math.max (d.width, tabDisplayer.getWidth());
1789
                    d.width = Math.max(d.width, tabDisplayer.getWidth());
1657
                }
1790
                }
1658
            }
1791
            }
1659
        }
1792
        }
1660
        
1793
1794
        @Override
1661
        public void cleanup() {
1795
        public void cleanup() {
1662
            timer.stop();
1796
            timer.stop();
1663
            root.setGlassPane(prevGlassPane);
1797
            root.setGlassPane(prevGlassPane);
1664
            prevGlassPane.setVisible(false);
1798
            prevGlassPane.setVisible(false);
1665
            customGlassPane.remove(comp);
1799
            customGlassPane.remove(comp);
1666
        }
1800
        }
1667
        
1801
1802
        @Override
1668
        protected void doFinish() {
1803
        protected void doFinish() {
1669
            showComponent (comp);
1804
            showComponent(comp);
1670
        }
1805
        }
1671
        
1806
1807
        @Override
1672
        public void actionPerformed(java.awt.event.ActionEvent e) {
1808
        public void actionPerformed(java.awt.event.ActionEvent e) {
1673
            float inc = customGlassPane.getIncrement();
1809
            float inc = customGlassPane.getIncrement();
1674
            if (inc >= 1.0f) {
1810
            if (inc >= 1.0f) {
1675
                finish();
1811
                finish();
1676
            } else {
1812
            } else {
1677
                customGlassPane.setIncrement (inc + INCREMENT);
1813
                customGlassPane.setIncrement(inc + INCREMENT);
1678
            }
1814
            }
1679
        }
1815
        }
1680
        
1816
1681
        private LiveComponentResizingGlassPane customGlassPane = null;
1817
        private LiveComponentResizingGlassPane customGlassPane = null;
1818
1682
        private LiveComponentResizingGlassPane getCustomGlassPane() {
1819
        private LiveComponentResizingGlassPane getCustomGlassPane() {
1683
            if (customGlassPane == null) {
1820
            if (customGlassPane == null) {
1684
                customGlassPane = new LiveComponentResizingGlassPane();
1821
                customGlassPane = new LiveComponentResizingGlassPane();
Lines 1686-1699 Link Here
1686
            }
1823
            }
1687
            return customGlassPane;
1824
            return customGlassPane;
1688
        }
1825
        }
1689
        
1826
1690
        private class LiveComponentResizingGlassPane extends JPanel {
1827
        private class LiveComponentResizingGlassPane extends JPanel {
1828
1691
            private float inc = 0f;
1829
            private float inc = 0f;
1692
            private Rectangle rect = new Rectangle();
1830
            private Rectangle rect = new Rectangle();
1693
            private Rectangle r2 = new Rectangle();
1831
            private Rectangle r2 = new Rectangle();
1694
            private boolean changed = true;
1832
            private boolean changed = true;
1695
            
1833
1696
            private void setIncrement (float inc) {
1834
            private void setIncrement(float inc) {
1697
                this.inc = inc;
1835
                this.inc = inc;
1698
                changed = true;
1836
                changed = true;
1699
                if (isShowing()) {
1837
                if (isShowing()) {
Lines 1704-1736 Link Here
1704
                }
1842
                }
1705
                doLayout();
1843
                doLayout();
1706
            }
1844
            }
1707
            
1845
1846
            @Override
1708
            public void doLayout() {
1847
            public void doLayout() {
1709
                Rectangle r = getImageBounds();
1848
                Rectangle r = getImageBounds();
1710
                comp.setBounds (r.x, r.y, r.width, r.height);
1849
                comp.setBounds(r.x, r.y, r.width, r.height);
1711
            }
1850
            }
1712
            
1851
1713
            private float getIncrement () {
1852
            private float getIncrement() {
1714
                return inc;
1853
                return inc;
1715
            }
1854
            }
1716
            
1855
1717
            private Rectangle getImageBounds() {
1856
            private Rectangle getImageBounds() {
1718
                if (!changed) {
1857
                if (!changed) {
1719
                    return rect;
1858
                    return rect;
1720
                }
1859
                }
1721
                Component c = tabDisplayer;
1860
                Component c = tabDisplayer;
1722
                r2.setBounds (0, 0, c.getWidth(), c.getHeight());
1861
                r2.setBounds(0, 0, c.getWidth(), c.getHeight());
1723
                
1862
1724
                Rectangle dispBounds = SwingUtilities.convertRectangle(c, r2, 
1863
                Rectangle dispBounds = SwingUtilities.convertRectangle(c, r2,
1725
                    this);
1864
                        this);
1726
                
1865
1727
                if (orientation == TabDisplayer.ORIENTATION_WEST) {
1866
                if (orientation == TabDisplayer.ORIENTATION_WEST) {
1728
                    rect.x = dispBounds.x + dispBounds.width;
1867
                    rect.x = dispBounds.x + dispBounds.width;
1729
                    rect.y = dispBounds.y;
1868
                    rect.y = dispBounds.y;
1730
                    rect.width = Math.round (inc * d.width);
1869
                    rect.width = Math.round(inc * d.width);
1731
                    rect.height = dispBounds.height;
1870
                    rect.height = dispBounds.height;
1732
                } else if (orientation == TabDisplayer.ORIENTATION_EAST) {
1871
                } else if (orientation == TabDisplayer.ORIENTATION_EAST) {
1733
                    rect.width = Math.round (inc * d.width);
1872
                    rect.width = Math.round(inc * d.width);
1734
                    rect.height = dispBounds.height;
1873
                    rect.height = dispBounds.height;
1735
                    rect.x = dispBounds.x - rect.width;
1874
                    rect.x = dispBounds.x - rect.width;
1736
                    rect.y = dispBounds.y;
1875
                    rect.y = dispBounds.y;
Lines 1749-1798 Link Here
1749
                return rect;
1888
                return rect;
1750
            }
1889
            }
1751
        }
1890
        }
1752
    }    
1891
    }
1753
    
1892
1754
//*** A bunch of options for testing
1893
//*** A bunch of options for testing
1755
    
1894
    /**
1756
    /** Sysprop to turn off all sliding effects */
1895
     * Sysprop to turn off all sliding effects
1757
    static final boolean NO_EFFECTS = Boolean.getBoolean ("nb.tabcontrol.no.fx"); //NOI18N
1896
     */
1758
    /** Sysprop to turn off scaling of the slide image */
1897
    static final boolean NO_EFFECTS = Boolean.getBoolean("nb.tabcontrol.no.fx"); //NOI18N
1759
    static final boolean NO_SCALE = Boolean.getBoolean ("nb.tabcontrol.fx.no.scaling"); //NOI18N
1898
    /**
1760
    /** Sysprop to turn use SwingUtilities.paintComponent() instead of an image buffer for sliding effects */
1899
     * Sysprop to turn off scaling of the slide image
1761
    static final boolean USE_SWINGPAINTING = Boolean.getBoolean ("nb.tabcontrol.fx.swingpainting"); //NOI18N
1900
     */
1762
    /** Sysprop to turn add the component being scaled to the glasspane and alter its size on a 
1901
    static final boolean NO_SCALE = Boolean.getBoolean("nb.tabcontrol.fx.no.scaling"); //NOI18N
1763
     * timer to accomplish growing the component */
1902
    /**
1764
    static final boolean ADD_TO_GLASSPANE = Boolean.getBoolean ("nb.tabcontrol.fx.use.resizing"); //NOI18N
1903
     * Sysprop to turn use SwingUtilities.paintComponent() instead of an image
1765
    /** For those who <strong>really</strong> love the sliding effect and want to see it on all
1904
     * buffer for sliding effects
1766
     * tab controls of all types */
1905
     */
1767
    static final boolean EFFECTS_EVERYWHERE = Boolean.getBoolean ("nb.tabcontrol.fx.everywhere") ||
1906
    static final boolean USE_SWINGPAINTING = Boolean.getBoolean("nb.tabcontrol.fx.swingpainting"); //NOI18N
1768
        Boolean.getBoolean("nb.tabcontrol.fx.gratuitous"); //NOI18N
1907
    /**
1769
    
1908
     * Sysprop to turn add the component being scaled to the glasspane and alter
1770
    /** Also have the scaled image be partially transparent as it's drawn */
1909
     * its size on a timer to accomplish growing the component
1771
    static final boolean USE_ALPHA = Boolean.getBoolean ("nb.tabcontrol.fx.use.alpha") ||
1910
     */
1772
        Boolean.getBoolean("nb.tabcontrol.fx.gratuitous"); //NOI18N
1911
    static final boolean ADD_TO_GLASSPANE = Boolean.getBoolean("nb.tabcontrol.fx.use.resizing"); //NOI18N
1773
    
1912
    /**
1774
    static  boolean SYNCHRONOUS_PAINTING = Boolean.getBoolean ("nb.tabcontrol.fx.synchronous"); //NOI18N
1913
     * For those who <strong>really</strong> love the sliding effect and want to
1775
    
1914
     * see it on all tab controls of all types
1915
     */
1916
    static final boolean EFFECTS_EVERYWHERE = Boolean.getBoolean("nb.tabcontrol.fx.everywhere")
1917
            || Boolean.getBoolean("nb.tabcontrol.fx.gratuitous"); //NOI18N
1918
1919
    /**
1920
     * Also have the scaled image be partially transparent as it's drawn
1921
     */
1922
    static final boolean USE_ALPHA = Boolean.getBoolean("nb.tabcontrol.fx.use.alpha")
1923
            || Boolean.getBoolean("nb.tabcontrol.fx.gratuitous"); //NOI18N
1924
1925
    static boolean SYNCHRONOUS_PAINTING = Boolean.getBoolean("nb.tabcontrol.fx.synchronous"); //NOI18N
1926
1776
    static float INCREMENT = 0.07f;
1927
    static float INCREMENT = 0.07f;
1777
    
1928
1778
    static int TIMER = 25;
1929
    static int TIMER = 25;
1930
1779
    static {
1931
    static {
1780
        boolean gratuitous = Boolean.getBoolean("nb.tabcontrol.fx.gratuitous"); //NOI18N
1932
        boolean gratuitous = Boolean.getBoolean("nb.tabcontrol.fx.gratuitous"); //NOI18N
1781
        String s = System.getProperty ("nb.tabcontrol.fx.increment"); //NOI18N
1933
        String s = System.getProperty("nb.tabcontrol.fx.increment"); //NOI18N
1782
        if (s != null) {
1934
        if (s != null) {
1783
            try {
1935
            try {
1784
                INCREMENT = Float.parseFloat(s);
1936
                INCREMENT = Float.parseFloat(s);
1785
            } catch (Exception e) {
1937
            } catch (Exception e) {
1786
                System.err.println("Bad float value specified: \"" + s +"\""); //NOI18N
1938
                System.err.println("Bad float value specified: \"" + s + "\""); //NOI18N
1787
            }
1939
            }
1788
        } else if (gratuitous) {
1940
        } else if (gratuitous) {
1789
            INCREMENT = 0.02f;
1941
            INCREMENT = 0.02f;
1790
        }
1942
        }
1791
        
1943
1792
        s = System.getProperty ("nb.tabcontrol.fx.timer"); //NOI18N
1944
        s = System.getProperty("nb.tabcontrol.fx.timer"); //NOI18N
1793
        if (s != null) {
1945
        if (s != null) {
1794
            try {
1946
            try {
1795
                TIMER = Integer.parseInt (s);
1947
                TIMER = Integer.parseInt(s);
1796
            } catch (Exception e) {
1948
            } catch (Exception e) {
1797
                System.err.println("Bad integer value specified: \"" + s + "\""); //NOI18N
1949
                System.err.println("Bad integer value specified: \"" + s + "\""); //NOI18N
1798
            }
1950
            }
Lines 1803-1864 Link Here
1803
            SYNCHRONOUS_PAINTING = true;
1955
            SYNCHRONOUS_PAINTING = true;
1804
        }
1956
        }
1805
    }
1957
    }
1806
    
1958
1807
    private static final class ForwardingMouseListener implements MouseListener {
1959
    private static final class ForwardingMouseListener implements MouseListener {
1960
1808
        private final Container c;
1961
        private final Container c;
1809
        public ForwardingMouseListener (Container c) {
1962
1963
        public ForwardingMouseListener(Container c) {
1810
            this.c = c;
1964
            this.c = c;
1811
        }
1965
        }
1812
        public void mousePressed (MouseEvent me) {
1966
1813
            forward (me);
1967
        @Override
1968
        public void mousePressed(MouseEvent me) {
1969
            forward(me);
1814
        }
1970
        }
1815
        
1971
1816
        public void mouseReleased (MouseEvent me) {
1972
        @Override
1817
            forward (me);
1973
        public void mouseReleased(MouseEvent me) {
1974
            forward(me);
1818
        }
1975
        }
1819
        
1976
1820
        public void mouseClicked (MouseEvent me) {
1977
        @Override
1821
            forward (me);
1978
        public void mouseClicked(MouseEvent me) {
1979
            forward(me);
1822
        }
1980
        }
1823
        
1981
1824
        public void mouseEntered (MouseEvent me) {
1982
        @Override
1825
            forward (me);
1983
        public void mouseEntered(MouseEvent me) {
1984
            forward(me);
1826
        }
1985
        }
1827
        
1986
1828
        public void mouseExited (MouseEvent me) {
1987
        @Override
1829
            forward (me);
1988
        public void mouseExited(MouseEvent me) {
1989
            forward(me);
1830
        }
1990
        }
1831
        
1991
1832
        private void forward (MouseEvent me) {
1992
        private void forward(MouseEvent me) {
1833
            MouseListener[] ml = c.getMouseListeners();
1993
            MouseListener[] ml = c.getMouseListeners();
1834
            if (ml.length == 0 || me.isConsumed()) {
1994
            if (ml.length == 0 || me.isConsumed()) {
1835
                return;
1995
                return;
1836
            }
1996
            }
1837
            MouseEvent me2 = SwingUtilities.convertMouseEvent(
1997
            MouseEvent me2 = SwingUtilities.convertMouseEvent(
1838
                (Component) me.getSource(), me, c);
1998
                    (Component) me.getSource(), me, c);
1839
            
1999
1840
            for (int i=0; i < ml.length; i++) {
2000
            for (int i = 0; i < ml.length; i++) {
1841
                switch (me2.getID()) {
2001
                switch (me2.getID()) {
1842
                    case MouseEvent.MOUSE_ENTERED :
2002
                    case MouseEvent.MOUSE_ENTERED:
1843
                        ml[i].mouseEntered(me2);
2003
                        ml[i].mouseEntered(me2);
1844
                        break;
2004
                        break;
1845
                    case MouseEvent.MOUSE_EXITED :
2005
                    case MouseEvent.MOUSE_EXITED:
1846
                        ml[i].mouseExited(me2);
2006
                        ml[i].mouseExited(me2);
1847
                        break;
2007
                        break;
1848
                    case MouseEvent.MOUSE_PRESSED :
2008
                    case MouseEvent.MOUSE_PRESSED:
1849
                        ml[i].mousePressed(me2);
2009
                        ml[i].mousePressed(me2);
1850
                        break;
2010
                        break;
1851
                    case MouseEvent.MOUSE_RELEASED :
2011
                    case MouseEvent.MOUSE_RELEASED:
1852
                        ml[i].mouseReleased(me2);
2012
                        ml[i].mouseReleased(me2);
1853
                        break;
2013
                        break;
1854
                    case MouseEvent.MOUSE_CLICKED :
2014
                    case MouseEvent.MOUSE_CLICKED:
1855
                        ml[i].mouseClicked(me2);
2015
                        ml[i].mouseClicked(me2);
1856
                        break;
2016
                        break;
1857
                    default :
2017
                    default:
1858
                        assert false;
2018
                        assert false;
1859
                }
2019
                }
1860
            }
2020
            }
1861
        }
2021
        }
1862
        
2022
1863
    }
2023
    }
1864
}
2024
}
(-)a/o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/plaf/StackLayout.java (-3 / +8 lines)
Lines 56-63 Link Here
56
 *
56
 *
57
 * @author Dafe Simonek
57
 * @author Dafe Simonek
58
 */
58
 */
59
class StackLayout implements LayoutManager {
59
public class StackLayout implements LayoutManager {
60
    
60
61
    // #100486 - hold visibleComp weakly, because removeLayoutComponent may not
61
    // #100486 - hold visibleComp weakly, because removeLayoutComponent may not
62
    // be called and then visibleComp is not freed. See StackLayoutTest for details.
62
    // be called and then visibleComp is not freed. See StackLayoutTest for details.
63
    /**
63
    /**
Lines 75-80 Link Here
75
        Component comp = getVisibleComponent();
75
        Component comp = getVisibleComponent();
76
        if (comp != c) {
76
        if (comp != c) {
77
            if (!parent.isAncestorOf(c) && c != null) {
77
            if (!parent.isAncestorOf(c) && c != null) {
78
                if (c.getParent() != null) {
79
                    c.getParent().remove(c);
80
                }
78
                parent.add(c);
81
                parent.add(c);
79
            }
82
            }
80
            synchronized (parent.getTreeLock()) {
83
            synchronized (parent.getTreeLock()) {
Lines 107-112 Link Here
107
     * ********** Implementation of LayoutManager interface *********
110
     * ********** Implementation of LayoutManager interface *********
108
     */
111
     */
109
112
113
    @Override
110
    public void addLayoutComponent(String name, Component comp) {
114
    public void addLayoutComponent(String name, Component comp) {
111
        synchronized (comp.getTreeLock()) {
115
        synchronized (comp.getTreeLock()) {
112
            comp.setVisible(false);
116
            comp.setVisible(false);
Lines 136-141 Link Here
136
    }
140
    }
137
}*/
141
}*/
138
    
142
    
143
    @Override
139
    public void removeLayoutComponent(Component comp) {
144
    public void removeLayoutComponent(Component comp) {
140
        synchronized (comp.getTreeLock()) {
145
        synchronized (comp.getTreeLock()) {
141
            if (comp == getVisibleComponent()) {
146
            if (comp == getVisibleComponent()) {
Lines 147-152 Link Here
147
        }
152
        }
148
    }
153
    }
149
154
155
    @Override
150
    public void layoutContainer(Container parent) {
156
    public void layoutContainer(Container parent) {
151
        Component visibleComp = getVisibleComponent();
157
        Component visibleComp = getVisibleComponent();
152
        if (visibleComp != null) {
158
        if (visibleComp != null) {
Lines 177-181 Link Here
177
    private static Dimension getEmptySize() {
183
    private static Dimension getEmptySize() {
178
        return new Dimension(50, 50);
184
        return new Dimension(50, 50);
179
    }
185
    }
180
181
}
186
}

Return to bug 253699