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 44576
Collapse All | Expand All

(-)RefactoringPanelContainer.java (-1 / +16 lines)
Lines 15-23 Link Here
15
import java.awt.BorderLayout;
15
import java.awt.BorderLayout;
16
import java.awt.Image;
16
import java.awt.Image;
17
import java.awt.event.MouseEvent;
17
import java.awt.event.MouseEvent;
18
import java.beans.PropertyChangeListener;
18
import java.text.MessageFormat;
19
import java.text.MessageFormat;
19
import javax.swing.JLabel;
20
import javax.swing.JLabel;
20
import javax.swing.JPanel;
21
import javax.swing.JPanel;
22
import javax.swing.event.ChangeListener;
21
import org.openide.awt.MouseUtils;
23
import org.openide.awt.MouseUtils;
22
import org.openide.util.HelpCtx;
24
import org.openide.util.HelpCtx;
23
import org.openide.util.Utilities;
25
import org.openide.util.Utilities;
Lines 42-47 Link Here
42
    private JPopupMenuPlus pop;
44
    private JPopupMenuPlus pop;
43
    /** Popup menu listener */
45
    /** Popup menu listener */
44
    private PopupListener listener;
46
    private PopupListener listener;
47
    private CloseListener closeL;
45
    private boolean isRefactoring;
48
    private boolean isRefactoring;
46
    private static Image REFACTORING_BADGE = Utilities.loadImage( "org/netbeans/modules/refactoring/resources/refactoringpreview.png" ); // NOI18N
49
    private static Image REFACTORING_BADGE = Utilities.loadImage( "org/netbeans/modules/refactoring/resources/refactoringpreview.png" ); // NOI18N
47
    private static Image USAGES_BADGE = Utilities.loadImage( "org/netbeans/modules/refactoring/resources/findusages.png" ); // NOI18N
50
    private static Image USAGES_BADGE = Utilities.loadImage( "org/netbeans/modules/refactoring/resources/findusages.png" ); // NOI18N
Lines 61-66 Link Here
61
        pop.add(new CloseAll());
64
        pop.add(new CloseAll());
62
        pop.add(new CloseAllButCurrent());
65
        pop.add(new CloseAllButCurrent());
63
        listener = new PopupListener();
66
        listener = new PopupListener();
67
        closeL = new CloseListener();
64
        this.isRefactoring = isRefactoring;
68
        this.isRefactoring = isRefactoring;
65
        setFocusCycleRoot(true);
69
        setFocusCycleRoot(true);
66
        JLabel label = new JLabel(NbBundle.getMessage(RefactoringPanelContainer.class, "LBL_NoUsages"));
70
        JLabel label = new JLabel(NbBundle.getMessage(RefactoringPanelContainer.class, "LBL_NoUsages"));
Lines 81-88 Link Here
81
                add(panel, BorderLayout.CENTER);
85
                add(panel, BorderLayout.CENTER);
82
            } else {
86
            } else {
83
                remove(comp);
87
                remove(comp);
84
                JTabbedPane pane = new JTabbedPane();
88
                JTabbedPane pane = new CloseButtonTabbedPane();
85
                pane.addMouseListener(listener);
89
                pane.addMouseListener(listener);
90
                pane.addPropertyChangeListener(closeL);
86
                add(pane, BorderLayout.CENTER);
91
                add(pane, BorderLayout.CENTER);
87
                pane.add(comp);
92
                pane.add(comp);
88
                pane.add(panel);
93
                pane.add(panel);
Lines 125-130 Link Here
125
            if (tabs.getComponentCount() == 1) {
130
            if (tabs.getComponentCount() == 1) {
126
                Component c = tabs.getComponent(0);
131
                Component c = tabs.getComponent(0);
127
                tabs.removeMouseListener(listener);
132
                tabs.removeMouseListener(listener);
133
                tabs.removePropertyChangeListener(closeL);
128
                remove(tabs);
134
                remove(tabs);
129
                add(c, BorderLayout.CENTER);
135
                add(c, BorderLayout.CENTER);
130
            }
136
            }
Lines 201-206 Link Here
201
        return PERSISTENCE_ALWAYS;
207
        return PERSISTENCE_ALWAYS;
202
    }
208
    }
203
    
209
    
210
    private class CloseListener implements PropertyChangeListener {
211
        
212
        public void propertyChange(java.beans.PropertyChangeEvent evt) {
213
            if (CloseButtonTabbedPane.PROP_CLOSE.equals(evt.getPropertyName())) {
214
                removePanel((JPanel) evt.getNewValue());
215
            }
216
        }
217
        
218
    }
204
    /**
219
    /**
205
    * Class to showing popup menu
220
    * Class to showing popup menu
206
    */
221
    */
(-)CloseButtonTabbedPane.java (+446 lines)
Added Link Here
1
/*
2
 *                 Sun Public License Notice
3
 *
4
 * The contents of this file are subject to the Sun Public License
5
 * Version 1.0 (the "License"). You may not use this file except in
6
 * compliance with the License. A copy of the License is available at
7
 * http://www.sun.com/
8
 *
9
 * The Original Code is NetBeans. The Initial Developer of the Original
10
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2004 Sun
11
 * Microsystems, Inc. All Rights Reserved.
12
 */
13
14
package org.netbeans.modules.refactoring.ui;
15
16
import java.awt.Component;
17
import org.openide.windows.TopComponent;
18
import org.openide.util.Utilities;
19
import org.openide.ErrorManager;
20
21
import javax.swing.*;
22
import javax.swing.event.ChangeEvent;
23
import javax.swing.event.ChangeListener;
24
import javax.swing.plaf.ColorUIResource;
25
import javax.swing.plaf.basic.BasicTabbedPaneUI;
26
import java.awt.*;
27
import java.awt.event.AWTEventListener;
28
import java.awt.event.MouseEvent;
29
30
// #21380.
31
/**
32
 * Copy of original CloseButtonTabbedPane from the NetBeans 3.4 winsys.  Old code never dies.
33
 *
34
 * !!! jbecicka comment: 
35
 * !!! This class was copy/pasted from org.netbeans.core.output2.ui
36
 * !!! See issue 44576
37
 * !!! Remove this class as soon as issue 55845 is fixed
38
 *
39
 * @author Tran Duc Trung
40
 *
41
 */
42
final class CloseButtonTabbedPane extends JTabbedPane implements ChangeListener, Runnable {
43
44
    private final Image closeTabImage =
45
        org.openide.util.Utilities.loadImage("org/netbeans/core/output2/resources/tabclose.gif"); // NOI18N
46
    private final Image closeTabInactiveImage =
47
        org.openide.util.Utilities.loadImage("org/netbeans/core/output2/resources/tabcloseinactive.gif"); // NOI18N
48
49
    public static final String PROP_CLOSE = "close";
50
51
    CloseButtonTabbedPane() {
52
        addChangeListener(this);
53
        CloseButtonListener.install();
54
        //Bugfix #28263: Disable focus.
55
        setFocusable(false);
56
        setBorder(javax.swing.BorderFactory.createEmptyBorder());
57
        setFocusCycleRoot(true);
58
        setFocusTraversalPolicy(new CBTPPolicy());
59
    }
60
61
    private Component sel() {
62
        Component c = getSelectedComponent();
63
        return c == null ? this : c;
64
    }
65
66
    private class CBTPPolicy extends FocusTraversalPolicy {
67
        public Component getComponentAfter(Container aContainer, Component aComponent) {
68
            return sel();
69
        }
70
71
        public Component getComponentBefore(Container aContainer, Component aComponent) {
72
            return sel();
73
        }
74
75
        public Component getFirstComponent(Container aContainer) {
76
            return sel();
77
        }
78
79
        public Component getLastComponent(Container aContainer) {
80
            return sel();
81
        }
82
83
        public Component getDefaultComponent(Container aContainer) {
84
            return sel();
85
        }
86
    }
87
88
    public int tabForCoordinate(int x, int y) {
89
        return getUI().tabForCoordinate(this, x, y);
90
    }
91
92
    private int pressedCloseButtonIndex = -1;
93
    private int mouseOverCloseButtonIndex = -1;
94
    private boolean draggedOut = false;
95
96
    public void stateChanged (ChangeEvent e) {
97
        reset();
98
    }
99
    
100
    public Component add (Component c) {
101
        Component result = super.add(c);
102
        String s = c.getName();
103
        if (s != null) {
104
            s += " ";
105
        }
106
        setTitleAt (getComponentCount() - 1, s);
107
        return result;
108
    }
109
110
    public void setTitleAt(int idx, String title) {
111
        String nue = title.indexOf("</html>") != -1 ? //NOI18N
112
            Utilities.replaceString(title, "</html>", "&nbsp;&nbsp;</html>") //NOI18N
113
            : title + "  ";
114
        if (!title.equals(getTitleAt(idx))) {
115
            super.setTitleAt(idx, nue);
116
        }
117
    }
118
119
    private void reset() {
120
        setMouseOverCloseButtonIndex(-1);
121
        setPressedCloseButtonIndex(-1);
122
        draggedOut = false;
123
    }
124
125
    private Rectangle getCloseButtonBoundsAt(int i) {
126
        Rectangle b = getBoundsAt(i);
127
        if (b == null)
128
            return null;
129
        else {
130
            b = new Rectangle(b);
131
            fixGetBoundsAt(b);
132
133
            Dimension tabsz = getSize();
134
            if (b.x + b.width >= tabsz.width
135
                || b.y + b.height >= tabsz.height)
136
                return null;
137
138
            return new Rectangle(b.x + b.width - 13,
139
                                 b.y + b.height / 2 - 5,
140
                                 8,
141
                                 8);
142
        }
143
    }
144
145
146
    /** Checks whether current L&F sets used keys for colors.
147
     * If not puts default values. */
148
    private static void checkUIColors() {
149
        if(UIManager.getColor("Button.shadow") == null) { // NOI18N
150
            UIManager.put("Button.shadow", // NOI18N
151
                new ColorUIResource(153, 153, 153));
152
        }
153
        if(UIManager.getColor("Button.darkShadow") == null) { // NOI18N
154
            UIManager.put("Button.darkShadow", // NOI18N
155
                new ColorUIResource(102, 102, 102));
156
        }
157
        if(UIManager.getColor("Button.highlight") == null) { // NOI18N
158
            UIManager.put("Button.highlight", // NOI18N
159
                new ColorUIResource(Color.white));
160
        }
161
        if(UIManager.getColor("Button.background") == null) { // NOI18N
162
            UIManager.put("Button.background", // NOI18N
163
                new ColorUIResource(204, 204, 204));
164
        }
165
    }
166
    
167
    public void paint(Graphics g) {
168
        super.paint(g);
169
170
        // #29181 All L&F doesn't support the colors used.
171
        checkUIColors();
172
173
        // Have a look at
174
        // http://ui.netbeans.org/docs/ui/closeButton/closeButtonUISpec.html
175
        // to see how the buttons are specified to be drawn.
176
177
        int selectedIndex = getSelectedIndex();
178
        for (int i = 0, n = getTabCount(); i < n; i++) {
179
            Rectangle r = getCloseButtonBoundsAt(i);
180
            if (r == null)
181
                continue;
182
            
183
            if(i == pressedCloseButtonIndex && !draggedOut) {
184
                g.setColor(UIManager.getColor("Button.shadow")); //NOI18N
185
                g.fillRect(r.x , r.y, r.width, r.height);
186
            }
187
            
188
            if (i != selectedIndex)
189
                g.drawImage(closeTabInactiveImage, r.x + 2, r.y + 2, this);
190
            else
191
                g.drawImage(closeTabImage, r.x + 2, r.y + 2, this);
192
            
193
            if (i == mouseOverCloseButtonIndex
194
            || (i == pressedCloseButtonIndex && draggedOut)) {
195
                g.setColor(UIManager.getColor("Button.darkShadow")); //NOI18N
196
                g.drawRect(r.x, r.y, r.width, r.height);
197
                g.setColor(i == selectedIndex
198
                    ? UIManager.getColor("Button.highlight") //NOI18N
199
                    : UIManager.getColor("Button.background")); //NOI18N
200
                g.drawRect(r.x + 1, r.y + 1, r.width, r.height);
201
                
202
                // Draw the dots.
203
                g.setColor (UIManager.getColor ("Button.highlight").brighter()); //NOI18N
204
                g.drawLine(r.x + r.width, r.y + 1, r.x + r.width, r.y + 1);
205
                g.drawLine(r.x + 1, r.y + r.height, r.x + 1, r.y + r.height);
206
            } else if (i == pressedCloseButtonIndex) {
207
                g.setColor(UIManager.getColor("Button.shadow")); //NOI18N
208
                g.drawRect(r.x, r.y, r.width, r.height);
209
                g.setColor(i == selectedIndex
210
                    ? UIManager.getColor("Button.highlight") //NOI18N
211
                    : UIManager.getColor("Button.background")); //NOI18N
212
                g.drawLine(r.x + 1,
213
                           r.y + r.height + 1,
214
                           r.x + r.width + 1,
215
                           r.y + r.height + 1);
216
                g.drawLine(r.x + r.width + 1,
217
                           r.y + 1,
218
                           r.x + r.width + 1,
219
                           r.y + r.height + 1);
220
                
221
                // Draw the lines.
222
                g.setColor(UIManager.getColor("Button.background")); //NOI18N
223
                g.drawLine(r.x + 1, r.y + 1, r.x + r.width, r.y + 1);
224
                g.drawLine(r.x + 1, r.y + 1, r.x + 1, r.y + r.height);
225
            }
226
        }
227
    }
228
229
    private void setPressedCloseButtonIndex(int index) {
230
        if (pressedCloseButtonIndex == index)
231
            return;
232
233
        if (pressedCloseButtonIndex >= 0
234
        && pressedCloseButtonIndex < getTabCount()) {
235
            Rectangle r = getCloseButtonBoundsAt(pressedCloseButtonIndex);
236
            repaint(r.x, r.y, r.width + 2, r.height + 2);
237
238
            JComponent c = (JComponent)
239
                getComponentAt(pressedCloseButtonIndex);
240
            setToolTipTextAt(pressedCloseButtonIndex, c.getToolTipText());
241
        }
242
243
        pressedCloseButtonIndex = index;
244
245
        if (pressedCloseButtonIndex >= 0
246
        && pressedCloseButtonIndex < getTabCount()) {
247
            Rectangle r = getCloseButtonBoundsAt(pressedCloseButtonIndex);
248
            repaint(r.x, r.y, r.width + 2, r.height + 2);
249
            setMouseOverCloseButtonIndex(-1);
250
            setToolTipTextAt(pressedCloseButtonIndex, null);
251
        }
252
    }
253
254
    private void setMouseOverCloseButtonIndex(int index) {
255
        if (mouseOverCloseButtonIndex == index)
256
            return;
257
258
        if (mouseOverCloseButtonIndex >= 0
259
        && mouseOverCloseButtonIndex < getTabCount()) {
260
            Rectangle r = getCloseButtonBoundsAt(mouseOverCloseButtonIndex);
261
            repaint(r.x, r.y, r.width + 2, r.height + 2);
262
            JComponent c =  (JComponent)
263
                getComponentAt(mouseOverCloseButtonIndex);
264
            setToolTipTextAt(mouseOverCloseButtonIndex, c.getToolTipText());
265
        }
266
267
        mouseOverCloseButtonIndex = index;
268
269
        if (mouseOverCloseButtonIndex >= 0
270
        && mouseOverCloseButtonIndex < getTabCount()) {
271
            Rectangle r = getCloseButtonBoundsAt(mouseOverCloseButtonIndex);
272
            repaint(r.x, r.y, r.width + 2, r.height + 2);
273
            setPressedCloseButtonIndex(-1);
274
            setToolTipTextAt(mouseOverCloseButtonIndex, null);
275
        }
276
    }
277
278
    private void fireCloseRequest(Component c) {
279
        firePropertyChange(PROP_CLOSE, null, c);
280
    }
281
282
    public static void fixGetBoundsAt(Rectangle b) {
283
        if (b.y < 0)
284
            b.y = -b.y;
285
        if (b.x < 0)
286
            b.x = -b.x;
287
    }
288
289
    public static int findTabForCoordinate(JTabbedPane tab, int x, int y) {
290
        for (int i = 0; i < tab.getTabCount(); i++) {
291
            Rectangle b = tab.getBoundsAt(i);
292
            if (b != null) {
293
                b = new Rectangle(b);
294
                fixGetBoundsAt(b);
295
296
                if (b.contains(x, y)) {
297
                    return i;
298
                }
299
            }
300
        }
301
        return -1;
302
    }
303
    
304
    boolean closingTab = false;
305
    public void doLayout() {
306
        //JDK 1.5, Win L&F - we cannot do the layout synchronously when we've
307
        //just removed a tab - the layout will have out of sync cache data
308
        if (closingTab) {
309
            SwingUtilities.invokeLater (this);
310
        } else {
311
            super.doLayout();
312
        }
313
    }
314
    
315
    public void run() {
316
        doLayout();
317
        closingTab = false;
318
        repaint();
319
    }
320
321
    protected void processMouseEvent (MouseEvent me) {
322
        try {
323
            super.processMouseEvent (me);
324
        } catch (ArrayIndexOutOfBoundsException aioobe) {
325
            //Bug in BasicTabbedPaneUI$Handler:  The focusIndex field is not
326
            //updated when tabs are removed programmatically, so it will try to
327
            //repaint a tab that's not there
328
            ErrorManager.getDefault().annotate(aioobe, "Suppressed " + //NOI18N
329
                    "AIOOBE bug in BasicTabbedPaneUI"); //NOI18N
330
            ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, aioobe);
331
        }
332
    }
333
334
335
    private static class CloseButtonListener implements AWTEventListener
336
    {
337
        private static boolean installed = false;
338
339
        private CloseButtonListener() {}
340
341
        private static synchronized void install() {
342
            if (installed)
343
                return;
344
345
            installed = true;
346
            Toolkit.getDefaultToolkit().addAWTEventListener(
347
                new CloseButtonListener(),
348
                AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK);
349
        }
350
351
        public void eventDispatched (AWTEvent ev) {
352
            MouseEvent e = (MouseEvent) ev;
353
354
            Component c = (Component) e.getSource();
355
            while (c != null && !(c instanceof CloseButtonTabbedPane))
356
                c = c.getParent();
357
            if (c == null)
358
                return;
359
            final CloseButtonTabbedPane tab = (CloseButtonTabbedPane) c;
360
361
            Point p = SwingUtilities.convertPoint((Component) e.getSource(),
362
                                                  e.getPoint(),
363
                                                  tab);
364
365
            if (e.getID() == MouseEvent.MOUSE_CLICKED) {
366
                //Not interested in clicked, and it can cause an NPE
367
                return;
368
            }
369
            
370
            int index = findTabForCoordinate(tab, p.x, p.y);
371
372
            Rectangle r = null;
373
            if (index >= 0)
374
                r = tab.getCloseButtonBoundsAt(index);
375
            if (r == null)
376
                r = new Rectangle(0,0,0,0);
377
378
            switch(e.getID()) {
379
                case MouseEvent.MOUSE_PRESSED:
380
                    if (r.contains(p)) {
381
                        tab.setPressedCloseButtonIndex(index);
382
                        tab.draggedOut = false;
383
                        e.consume();
384
                        return;
385
                    }
386
                    break;
387
388
                case MouseEvent.MOUSE_RELEASED:
389
                    if (r.contains(p) && tab.pressedCloseButtonIndex >= 0) {
390
                        tab.closingTab = true;
391
                        Component tc =
392
                            tab.getComponentAt(tab.pressedCloseButtonIndex);
393
                        tab.reset();
394
395
                        tab.fireCloseRequest(tc);
396
                        e.consume();
397
                        return;
398
                    }
399
                    else {
400
                        tab.reset();
401
                    }
402
                    break;
403
404
                case MouseEvent.MOUSE_ENTERED:
405
                    break;
406
407
                case MouseEvent.MOUSE_EXITED:
408
                    //tab.reset();
409
410
                    // XXX(-ttran) when the user clicks on the close button on
411
                    // an unfocused (internal) frame the focus is transferred
412
                    // to the frame and an unexpected MOUSE_EXITED event is
413
                    // fired.  If we call reset() at every MOUSE_EXITED event
414
                    // then when the mouse button is released the tab is not
415
                    // closed.  See bug #24450
416
                    
417
                    break;
418
419
                case MouseEvent.MOUSE_MOVED:
420
                    if (r.contains(p)) {
421
                        tab.setMouseOverCloseButtonIndex(index);
422
                        tab.draggedOut = false;
423
                        e.consume();
424
                        return;
425
                    }
426
                    else if (tab.mouseOverCloseButtonIndex >= 0) {
427
                        tab.setMouseOverCloseButtonIndex(-1);
428
                        tab.draggedOut = false;
429
                        e.consume();
430
                    }
431
                    break;
432
433
                case MouseEvent.MOUSE_DRAGGED:
434
                    if (tab.pressedCloseButtonIndex >= 0) {
435
                        if (tab.draggedOut != !r.contains(p)) {
436
                            tab.draggedOut = !r.contains(p);
437
                            tab.repaint(r.x, r.y, r.width + 2, r.height + 2);
438
                        }
439
                        e.consume();
440
                        return;
441
                    }
442
                    break;
443
            }
444
        }
445
    }
446
}

Return to bug 44576