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

(-)a/jumpto/src/org/netbeans/modules/jumpto/type/GoToPanel.java (-583 / +586 lines)
Lines 1-583 Link Here
1
/*
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
3
 *
4
 * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
4
 * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
5
 *
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
7
 * Other names may be trademarks of their respective owners.
8
 *
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
26
 *
27
 * Contributor(s):
27
 * Contributor(s):
28
 *
28
 *
29
 * The Original Software is NetBeans. The Initial Developer of the Original
29
 * The Original Software is NetBeans. The Initial Developer of the Original
30
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
30
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
31
 * Microsystems, Inc. All Rights Reserved.
31
 * Microsystems, Inc. All Rights Reserved.
32
 *
32
 * 
33
 * If you wish your version of this file to be governed by only the CDDL
33
 * markiewb@netbeans.org
34
 * or only the GPL Version 2, indicate your decision by adding
34
 *
35
 * "[Contributor] elects to include this software in this distribution
35
 * If you wish your version of this file to be governed by only the CDDL
36
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
36
 * or only the GPL Version 2, indicate your decision by adding
37
 * single choice of license, a recipient has the option to distribute
37
 * "[Contributor] elects to include this software in this distribution
38
 * your version of this file under either the CDDL, the GPL Version 2 or
38
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
39
 * to extend the choice of license to its licensees as provided above.
39
 * single choice of license, a recipient has the option to distribute
40
 * However, if you add GPL Version 2 code and therefore, elected the GPL
40
 * your version of this file under either the CDDL, the GPL Version 2 or
41
 * Version 2 license, then the option applies only if the new code is
41
 * to extend the choice of license to its licensees as provided above.
42
 * made subject to such option by the copyright holder.
42
 * However, if you add GPL Version 2 code and therefore, elected the GPL
43
 */
43
 * Version 2 license, then the option applies only if the new code is
44
44
 * made subject to such option by the copyright holder.
45
package org.netbeans.modules.jumpto.type;
45
 */
46
46
47
import java.awt.Color;
47
package org.netbeans.modules.jumpto.type;
48
import java.awt.event.ActionEvent;
48
49
import java.awt.event.ItemEvent;
49
import java.awt.Color;
50
import java.awt.event.ItemListener;
50
import java.awt.event.ActionEvent;
51
import java.awt.event.KeyEvent;
51
import java.awt.event.ItemEvent;
52
import java.awt.event.MouseListener;
52
import java.awt.event.ItemListener;
53
import java.io.IOException;
53
import java.awt.event.KeyEvent;
54
import java.util.Collections;
54
import java.awt.event.MouseListener;
55
import java.util.LinkedList;
55
import java.io.IOException;
56
import java.util.List;
56
import java.util.Collections;
57
import javax.swing.Action;
57
import java.util.LinkedList;
58
import javax.swing.BorderFactory;
58
import java.util.List;
59
import javax.swing.Icon;
59
import javax.swing.Action;
60
import javax.swing.InputMap;
60
import javax.swing.BorderFactory;
61
import javax.swing.JLabel;
61
import javax.swing.Icon;
62
import javax.swing.JList;
62
import javax.swing.InputMap;
63
import javax.swing.KeyStroke;
63
import javax.swing.JLabel;
64
import javax.swing.ListCellRenderer;
64
import javax.swing.JList;
65
import javax.swing.ListModel;
65
import javax.swing.KeyStroke;
66
import javax.swing.ListSelectionModel;
66
import javax.swing.ListCellRenderer;
67
import javax.swing.SwingConstants;
67
import javax.swing.ListModel;
68
import javax.swing.SwingUtilities;
68
import javax.swing.ListSelectionModel;
69
import javax.swing.event.DocumentEvent;
69
import javax.swing.SwingConstants;
70
import javax.swing.event.DocumentListener;
70
import javax.swing.SwingUtilities;
71
import javax.swing.event.ListSelectionEvent;
71
import javax.swing.event.DocumentEvent;
72
import javax.swing.event.ListSelectionListener;
72
import javax.swing.event.DocumentListener;
73
import javax.swing.text.BadLocationException;
73
import javax.swing.event.ListSelectionEvent;
74
import org.netbeans.modules.jumpto.SearchHistory;
74
import javax.swing.event.ListSelectionListener;
75
import org.netbeans.spi.jumpto.type.TypeDescriptor;
75
import javax.swing.text.BadLocationException;
76
import org.openide.filesystems.FileObject;
76
import javax.swing.text.Document;
77
import org.openide.filesystems.FileUtil;
77
import org.netbeans.modules.jumpto.SearchHistory;
78
import org.openide.util.ImageUtilities;
78
import org.netbeans.spi.jumpto.type.TypeDescriptor;
79
import org.openide.util.NbBundle;
79
import org.openide.filesystems.FileObject;
80
80
import org.openide.filesystems.FileUtil;
81
/**
81
import org.openide.util.ImageUtilities;
82
 *
82
import org.openide.util.NbBundle;
83
 * @author  Petr Hrebejk
83
84
 */
84
/**
85
public class GoToPanel extends javax.swing.JPanel {
85
 *
86
            
86
 * @author  Petr Hrebejk
87
    private static Icon WAIT_ICON = ImageUtilities.loadImageIcon("org/netbeans/modules/jumpto/resources/wait.gif", false); // NOI18N
87
 */
88
    private static Icon WARN_ICON = ImageUtilities.loadImageIcon("org/netbeans/modules/jumpto/resources/warning.png", false); // NOI18N
88
public class GoToPanel extends javax.swing.JPanel {
89
        
89
            
90
    private static final int BRIGHTER_COLOR_COMPONENT = 10;
90
    private static Icon WAIT_ICON = ImageUtilities.loadImageIcon("org/netbeans/modules/jumpto/resources/wait.gif", false); // NOI18N
91
    private ContentProvider contentProvider;
91
    private static Icon WARN_ICON = ImageUtilities.loadImageIcon("org/netbeans/modules/jumpto/resources/warning.png", false); // NOI18N
92
    private boolean containsScrollPane;
92
        
93
    JLabel messageLabel;
93
    private static final int BRIGHTER_COLOR_COMPONENT = 10;
94
    private Iterable<? extends TypeDescriptor> selectedTypes = Collections.emptyList();
94
    private ContentProvider contentProvider;
95
    
95
    private boolean containsScrollPane;
96
    private String oldText;
96
    JLabel messageLabel;
97
    
97
    private Iterable<? extends TypeDescriptor> selectedTypes = Collections.emptyList();
98
    // Time when the serach stared (for debugging purposes)
98
    
99
    long time = -1;
99
    private String oldText;
100
100
    
101
    private final SearchHistory searchHistory;
101
    // Time when the serach stared (for debugging purposes)
102
102
    long time = -1;
103
    // handling http://netbeans.org/bugzilla/show_bug.cgi?id=203512
103
104
    // if the whole search argument (in the name JTextField) is selected and something is pasted in it's place,
104
    private final SearchHistory searchHistory;
105
    // notify the DocumentListener because it will first call removeUpdate() and then inserteUpdate().
105
106
    // When removeUpdate() is called we should not call update() because it messes the messageLabel's text.
106
    // handling http://netbeans.org/bugzilla/show_bug.cgi?id=203512
107
    private boolean pastedFromClipboard = false;
107
    // if the whole search argument (in the name JTextField) is selected and something is pasted in it's place,
108
    
108
    // notify the DocumentListener because it will first call removeUpdate() and then inserteUpdate().
109
    /** Creates new form GoToPanel */
109
    // When removeUpdate() is called we should not call update() because it messes the messageLabel's text.
110
    public GoToPanel( ContentProvider contentProvider, boolean multiSelection ) throws IOException {
110
    private boolean pastedFromClipboard = false;
111
        this.contentProvider = contentProvider;
111
    
112
        initComponents();
112
    /** Creates new form GoToPanel */
113
        containsScrollPane = true;
113
    public GoToPanel( ContentProvider contentProvider, boolean multiSelection ) throws IOException {
114
                
114
        this.contentProvider = contentProvider;
115
        matchesList.setSelectionMode( multiSelection ? ListSelectionModel.MULTIPLE_INTERVAL_SELECTION : ListSelectionModel.SINGLE_SELECTION);
115
        initComponents();
116
        //matchesList.setPrototypeCellValue("12345678901234567890123456789012345678901234567890123456789012345678901234567890");        
116
        containsScrollPane = true;
117
        matchesList.addListSelectionListener(null);
117
                
118
        
118
        matchesList.setSelectionMode( multiSelection ? ListSelectionModel.MULTIPLE_INTERVAL_SELECTION : ListSelectionModel.SINGLE_SELECTION);
119
        Color bgColorBrighter = new Color(
119
        //matchesList.setPrototypeCellValue("12345678901234567890123456789012345678901234567890123456789012345678901234567890");        
120
                                    Math.min(getBackground().getRed() + BRIGHTER_COLOR_COMPONENT, 255),
120
        matchesList.addListSelectionListener(null);
121
                                    Math.min(getBackground().getGreen() + BRIGHTER_COLOR_COMPONENT, 255),
121
        
122
                                    Math.min(getBackground().getBlue() + BRIGHTER_COLOR_COMPONENT, 255)
122
        Color bgColorBrighter = new Color(
123
                            );
123
                                    Math.min(getBackground().getRed() + BRIGHTER_COLOR_COMPONENT, 255),
124
        
124
                                    Math.min(getBackground().getGreen() + BRIGHTER_COLOR_COMPONENT, 255),
125
        messageLabel = new JLabel();
125
                                    Math.min(getBackground().getBlue() + BRIGHTER_COLOR_COMPONENT, 255)
126
        messageLabel.setBackground(bgColorBrighter);
126
                            );
127
        messageLabel.setHorizontalAlignment(SwingConstants.CENTER);
127
        
128
        messageLabel.setEnabled(true);
128
        messageLabel = new JLabel();
129
        messageLabel.setText(NbBundle.getMessage(GoToPanel.class, "TXT_NoTypesFound")); // NOI18N
129
        messageLabel.setBackground(bgColorBrighter);
130
        messageLabel.setFont(matchesList.getFont());
130
        messageLabel.setHorizontalAlignment(SwingConstants.CENTER);
131
        
131
        messageLabel.setEnabled(true);
132
        // matchesList.setBackground( bgColorBrighter );
132
        messageLabel.setText(NbBundle.getMessage(GoToPanel.class, "TXT_NoTypesFound")); // NOI18N
133
        // matchesScrollPane1.setBackground( bgColorBrighter );
133
        messageLabel.setFont(matchesList.getFont());
134
        matchesList.setCellRenderer( contentProvider.getListCellRenderer( matchesList ) );
134
        
135
        contentProvider.setListModel( this, null );
135
        // matchesList.setBackground( bgColorBrighter );
136
        
136
        // matchesScrollPane1.setBackground( bgColorBrighter );
137
        PatternListener pl = new PatternListener( this );
137
        matchesList.setCellRenderer( contentProvider.getListCellRenderer( matchesList, nameField.getDocument()));
138
        nameField.getDocument().addDocumentListener(pl);
138
        contentProvider.setListModel( this, null );
139
        caseSensitive.setSelected(UiOptions.GoToTypeDialog.getCaseSensitive());
139
        
140
        caseSensitive.addItemListener(pl);
140
        PatternListener pl = new PatternListener( this );
141
        matchesList.addListSelectionListener(pl);                       
141
        nameField.getDocument().addDocumentListener(pl);
142
142
        caseSensitive.setSelected(UiOptions.GoToTypeDialog.getCaseSensitive());
143
        searchHistory = new SearchHistory(GoToPanel.class, nameField);
143
        caseSensitive.addItemListener(pl);
144
    }
144
        matchesList.addListSelectionListener(pl);                       
145
145
146
    @Override
146
        searchHistory = new SearchHistory(GoToPanel.class, nameField);
147
    public void removeNotify() {
147
    }
148
        searchHistory.saveHistory();
148
149
        super.removeNotify();
149
    @Override
150
    }
150
    public void removeNotify() {
151
151
        searchHistory.saveHistory();
152
    /** Sets the model from different therad
152
        super.removeNotify();
153
     */
153
    }
154
    public void setModel( final ListModel model ) { 
154
155
        // XXX measure time here
155
    /** Sets the model from different therad
156
        SwingUtilities.invokeLater(new Runnable() {
156
     */
157
           public void run() {
157
    public void setModel( final ListModel model ) { 
158
               if (model.getSize() > 0 || getText() == null || getText().trim().length() == 0 ) {
158
        // XXX measure time here
159
                   matchesList.setModel(model);
159
        SwingUtilities.invokeLater(new Runnable() {
160
                   matchesList.setSelectedIndex(0);
160
           public void run() {
161
                   setListPanelContent(null,false);
161
               if (model.getSize() > 0 || getText() == null || getText().trim().length() == 0 ) {
162
                   if ( time != -1 ) {
162
                   matchesList.setModel(model);
163
                       GoToTypeAction.LOGGER.fine("Real search time " + (System.currentTimeMillis() - time) + " ms.");
163
                   matchesList.setSelectedIndex(0);
164
                       time = -1;
164
                   setListPanelContent(null,false);
165
                   }
165
                   if ( time != -1 ) {
166
               }
166
                       GoToTypeAction.LOGGER.fine("Real search time " + (System.currentTimeMillis() - time) + " ms.");
167
               else {
167
                       time = -1;
168
                   setListPanelContent( NbBundle.getMessage(GoToPanel.class, "TXT_NoTypesFound") ,false ); // NOI18N
168
                   }
169
               }
169
               }
170
           }
170
               else {
171
       });
171
                   setListPanelContent( NbBundle.getMessage(GoToPanel.class, "TXT_NoTypesFound") ,false ); // NOI18N
172
    }
172
               }
173
    
173
           }
174
    /** Sets the initial text to find in case the user did not start typing yet. */
174
       });
175
    public void setInitialText( final String text ) {
175
    }
176
        oldText = text;
176
    
177
        SwingUtilities.invokeLater( new Runnable() {
177
    /** Sets the initial text to find in case the user did not start typing yet. */
178
            public void run() {
178
    public void setInitialText( final String text ) {
179
                String textInField = nameField.getText();
179
        oldText = text;
180
                if ( textInField == null || textInField.trim().length() == 0 ) {
180
        SwingUtilities.invokeLater( new Runnable() {
181
                    nameField.setText(text);
181
            public void run() {
182
                    nameField.setCaretPosition(text.length());
182
                String textInField = nameField.getText();
183
                    nameField.setSelectionStart(0);
183
                if ( textInField == null || textInField.trim().length() == 0 ) {
184
                    nameField.setSelectionEnd(text.length());
184
                    nameField.setText(text);
185
                }
185
                    nameField.setCaretPosition(text.length());
186
            }
186
                    nameField.setSelectionStart(0);
187
        });
187
                    nameField.setSelectionEnd(text.length());
188
    }
188
                }
189
    
189
            }
190
    public void setSelectedTypes() {
190
        });
191
        final List<TypeDescriptor> types = new LinkedList<TypeDescriptor>();
191
    }
192
        for (Object td : matchesList.getSelectedValues()) {
192
    
193
            types.add((TypeDescriptor)td);
193
    public void setSelectedTypes() {
194
        }
194
        final List<TypeDescriptor> types = new LinkedList<TypeDescriptor>();
195
        selectedTypes = Collections.unmodifiableCollection(types);
195
        for (Object td : matchesList.getSelectedValues()) {
196
    }
196
            types.add((TypeDescriptor)td);
197
    
197
        }
198
    public Iterable<? extends TypeDescriptor> getSelectedTypes() {
198
        selectedTypes = Collections.unmodifiableCollection(types);
199
        return selectedTypes;
199
    }
200
    }
200
    
201
201
    public Iterable<? extends TypeDescriptor> getSelectedTypes() {
202
    void setWarning(String warningMessage) {
202
        return selectedTypes;
203
        if (warningMessage != null) {
203
    }
204
            jLabelWarning.setIcon(WARN_ICON);
204
205
            jLabelWarning.setBorder(BorderFactory.createEmptyBorder(3, 1, 1, 1));
205
    void setWarning(String warningMessage) {
206
        } else {
206
        if (warningMessage != null) {
207
                jLabelWarning.setIcon(null);
207
            jLabelWarning.setIcon(WARN_ICON);
208
                jLabelWarning.setBorder(null);
208
            jLabelWarning.setBorder(BorderFactory.createEmptyBorder(3, 1, 1, 1));
209
        }
209
        } else {
210
        jLabelWarning.setText(warningMessage);
210
                jLabelWarning.setIcon(null);
211
    }
211
                jLabelWarning.setBorder(null);
212
    
212
        }
213
    //handling http://netbeans.org/bugzilla/show_bug.cgi?id=178555
213
        jLabelWarning.setText(warningMessage);
214
    public void setMouseListener(MouseListener warningMouseListener) {
214
    }
215
        if (messageLabel.getMouseListeners().length == 0) {
215
    
216
            messageLabel.addMouseListener(warningMouseListener);
216
    //handling http://netbeans.org/bugzilla/show_bug.cgi?id=178555
217
        }
217
    public void setMouseListener(MouseListener warningMouseListener) {
218
    }
218
        if (messageLabel.getMouseListeners().length == 0) {
219
            
219
            messageLabel.addMouseListener(warningMouseListener);
220
    /** This method is called from within the constructor to
220
        }
221
     * initialize the form.
221
    }
222
     * WARNING: Do NOT modify this code. The content of this method is
222
            
223
     * always regenerated by the Form Editor.
223
    /** This method is called from within the constructor to
224
     */
224
     * initialize the form.
225
    @SuppressWarnings("deprecation")
225
     * WARNING: Do NOT modify this code. The content of this method is
226
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
226
     * always regenerated by the Form Editor.
227
    private void initComponents() {
227
     */
228
        java.awt.GridBagConstraints gridBagConstraints;
228
    @SuppressWarnings("deprecation")
229
229
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
230
        jLabelText = new javax.swing.JLabel();
230
    private void initComponents() {
231
        nameField = new javax.swing.JTextField();
231
        java.awt.GridBagConstraints gridBagConstraints;
232
        jLabelList = new javax.swing.JLabel();
232
233
        listPanel = new javax.swing.JPanel();
233
        jLabelText = new javax.swing.JLabel();
234
        matchesScrollPane1 = new javax.swing.JScrollPane();
234
        nameField = new javax.swing.JTextField();
235
        matchesList = new javax.swing.JList();
235
        jLabelList = new javax.swing.JLabel();
236
        jLabelWarning = new javax.swing.JLabel();
236
        listPanel = new javax.swing.JPanel();
237
        caseSensitive = new javax.swing.JCheckBox();
237
        matchesScrollPane1 = new javax.swing.JScrollPane();
238
        jLabelLocation = new javax.swing.JLabel();
238
        matchesList = new javax.swing.JList();
239
        jTextFieldLocation = new javax.swing.JTextField();
239
        jLabelWarning = new javax.swing.JLabel();
240
240
        caseSensitive = new javax.swing.JCheckBox();
241
        setBorder(javax.swing.BorderFactory.createEmptyBorder(8, 8, 8, 8));
241
        jLabelLocation = new javax.swing.JLabel();
242
        setFocusable(false);
242
        jTextFieldLocation = new javax.swing.JTextField();
243
        setNextFocusableComponent(nameField);
243
244
        setLayout(new java.awt.GridBagLayout());
244
        setBorder(javax.swing.BorderFactory.createEmptyBorder(8, 8, 8, 8));
245
245
        setFocusable(false);
246
        jLabelText.setLabelFor(nameField);
246
        setNextFocusableComponent(nameField);
247
        org.openide.awt.Mnemonics.setLocalizedText(jLabelText, org.openide.util.NbBundle.getMessage(GoToPanel.class, "TXT_GoToType_TypeName_Label")); // NOI18N
247
        setLayout(new java.awt.GridBagLayout());
248
        gridBagConstraints = new java.awt.GridBagConstraints();
248
249
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
249
        jLabelText.setLabelFor(nameField);
250
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
250
        org.openide.awt.Mnemonics.setLocalizedText(jLabelText, org.openide.util.NbBundle.getMessage(GoToPanel.class, "TXT_GoToType_TypeName_Label")); // NOI18N
251
        gridBagConstraints.anchor = java.awt.GridBagConstraints.SOUTHWEST;
251
        gridBagConstraints = new java.awt.GridBagConstraints();
252
        gridBagConstraints.weightx = 1.0;
252
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
253
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 4, 0);
253
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
254
        add(jLabelText, gridBagConstraints);
254
        gridBagConstraints.anchor = java.awt.GridBagConstraints.SOUTHWEST;
255
        jLabelText.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(GoToPanel.class, "GoToPanel.jLabelText.AccessibleContext.accessibleDescription")); // NOI18N
255
        gridBagConstraints.weightx = 1.0;
256
256
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 4, 0);
257
        nameField.setFont(new java.awt.Font("Monospaced", 0, getFontSize()));
257
        add(jLabelText, gridBagConstraints);
258
        nameField.setBorder(javax.swing.BorderFactory.createEtchedBorder());
258
        jLabelText.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(GoToPanel.class, "GoToPanel.jLabelText.AccessibleContext.accessibleDescription")); // NOI18N
259
        nameField.addActionListener(new java.awt.event.ActionListener() {
259
260
            public void actionPerformed(java.awt.event.ActionEvent evt) {
260
        nameField.setFont(new java.awt.Font("Monospaced", 0, getFontSize()));
261
                nameFieldActionPerformed(evt);
261
        nameField.setBorder(javax.swing.BorderFactory.createEtchedBorder());
262
            }
262
        nameField.addActionListener(new java.awt.event.ActionListener() {
263
        });
263
            public void actionPerformed(java.awt.event.ActionEvent evt) {
264
        nameField.addKeyListener(new java.awt.event.KeyAdapter() {
264
                nameFieldActionPerformed(evt);
265
            public void keyPressed(java.awt.event.KeyEvent evt) {
265
            }
266
                nameFieldKeyPressed(evt);
266
        });
267
            }
267
        nameField.addKeyListener(new java.awt.event.KeyAdapter() {
268
            public void keyReleased(java.awt.event.KeyEvent evt) {
268
            public void keyPressed(java.awt.event.KeyEvent evt) {
269
                nameFieldKeyReleased(evt);
269
                nameFieldKeyPressed(evt);
270
            }
270
            }
271
            public void keyTyped(java.awt.event.KeyEvent evt) {
271
            public void keyReleased(java.awt.event.KeyEvent evt) {
272
                nameFieldKeyTyped(evt);
272
                nameFieldKeyReleased(evt);
273
            }
273
            }
274
        });
274
            public void keyTyped(java.awt.event.KeyEvent evt) {
275
        gridBagConstraints = new java.awt.GridBagConstraints();
275
                nameFieldKeyTyped(evt);
276
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
276
            }
277
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
277
        });
278
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 8, 0);
278
        gridBagConstraints = new java.awt.GridBagConstraints();
279
        add(nameField, gridBagConstraints);
279
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
280
280
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
281
        jLabelList.setLabelFor(matchesList);
281
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 8, 0);
282
        org.openide.awt.Mnemonics.setLocalizedText(jLabelList, org.openide.util.NbBundle.getMessage(GoToPanel.class, "TXT_GoToType_MatchesList_Label")); // NOI18N
282
        add(nameField, gridBagConstraints);
283
        gridBagConstraints = new java.awt.GridBagConstraints();
283
284
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
284
        jLabelList.setLabelFor(matchesList);
285
        gridBagConstraints.anchor = java.awt.GridBagConstraints.SOUTHWEST;
285
        org.openide.awt.Mnemonics.setLocalizedText(jLabelList, org.openide.util.NbBundle.getMessage(GoToPanel.class, "TXT_GoToType_MatchesList_Label")); // NOI18N
286
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 4, 0);
286
        gridBagConstraints = new java.awt.GridBagConstraints();
287
        add(jLabelList, gridBagConstraints);
287
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
288
288
        gridBagConstraints.anchor = java.awt.GridBagConstraints.SOUTHWEST;
289
        listPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
289
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 4, 0);
290
        listPanel.setName("dataPanel"); // NOI18N
290
        add(jLabelList, gridBagConstraints);
291
        listPanel.setLayout(new java.awt.BorderLayout());
291
292
292
        listPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
293
        matchesScrollPane1.setBorder(null);
293
        listPanel.setName("dataPanel"); // NOI18N
294
        matchesScrollPane1.setFocusable(false);
294
        listPanel.setLayout(new java.awt.BorderLayout());
295
295
296
        matchesList.setFont(new java.awt.Font("Monospaced", 0, getFontSize()));
296
        matchesScrollPane1.setBorder(null);
297
        matchesList.setVisibleRowCount(15);
297
        matchesScrollPane1.setFocusable(false);
298
        matchesList.addMouseListener(new java.awt.event.MouseAdapter() {
298
299
            public void mouseReleased(java.awt.event.MouseEvent evt) {
299
        matchesList.setFont(new java.awt.Font("Monospaced", 0, getFontSize()));
300
                matchesListMouseReleased(evt);
300
        matchesList.setVisibleRowCount(15);
301
            }
301
        matchesList.addMouseListener(new java.awt.event.MouseAdapter() {
302
        });
302
            public void mouseReleased(java.awt.event.MouseEvent evt) {
303
        matchesScrollPane1.setViewportView(matchesList);
303
                matchesListMouseReleased(evt);
304
        matchesList.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(GoToPanel.class, "ACSD_GoToListName")); // NOI18N
304
            }
305
        matchesList.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(GoToPanel.class, "GoToPanel.matchesList.AccessibleContext.accessibleDescription")); // NOI18N
305
        });
306
306
        matchesScrollPane1.setViewportView(matchesList);
307
        listPanel.add(matchesScrollPane1, java.awt.BorderLayout.CENTER);
307
        matchesList.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(GoToPanel.class, "ACSD_GoToListName")); // NOI18N
308
308
        matchesList.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(GoToPanel.class, "GoToPanel.matchesList.AccessibleContext.accessibleDescription")); // NOI18N
309
        jLabelWarning.setFocusable(false);
309
310
        listPanel.add(jLabelWarning, java.awt.BorderLayout.PAGE_END);
310
        listPanel.add(matchesScrollPane1, java.awt.BorderLayout.CENTER);
311
311
312
        gridBagConstraints = new java.awt.GridBagConstraints();
312
        jLabelWarning.setFocusable(false);
313
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
313
        listPanel.add(jLabelWarning, java.awt.BorderLayout.PAGE_END);
314
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
314
315
        gridBagConstraints.weightx = 1.0;
315
        gridBagConstraints = new java.awt.GridBagConstraints();
316
        gridBagConstraints.weighty = 1.0;
316
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
317
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 8, 0);
317
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
318
        add(listPanel, gridBagConstraints);
318
        gridBagConstraints.weightx = 1.0;
319
319
        gridBagConstraints.weighty = 1.0;
320
        org.openide.awt.Mnemonics.setLocalizedText(caseSensitive, org.openide.util.NbBundle.getMessage(GoToPanel.class, "TXT_GoToType_CaseSensitive")); // NOI18N
320
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 8, 0);
321
        gridBagConstraints = new java.awt.GridBagConstraints();
321
        add(listPanel, gridBagConstraints);
322
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
322
323
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
323
        org.openide.awt.Mnemonics.setLocalizedText(caseSensitive, org.openide.util.NbBundle.getMessage(GoToPanel.class, "TXT_GoToType_CaseSensitive")); // NOI18N
324
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 4, 0);
324
        gridBagConstraints = new java.awt.GridBagConstraints();
325
        add(caseSensitive, gridBagConstraints);
325
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
326
        caseSensitive.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(GoToPanel.class, "GoToPanel.caseSensitive.AccessibleContext.accessibleDescription")); // NOI18N
326
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
327
327
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 4, 0);
328
        jLabelLocation.setText(org.openide.util.NbBundle.getMessage(GoToPanel.class, "LBL_GoToType_LocationJLabel")); // NOI18N
328
        add(caseSensitive, gridBagConstraints);
329
        gridBagConstraints = new java.awt.GridBagConstraints();
329
        caseSensitive.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(GoToPanel.class, "GoToPanel.caseSensitive.AccessibleContext.accessibleDescription")); // NOI18N
330
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
330
331
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
331
        jLabelLocation.setText(org.openide.util.NbBundle.getMessage(GoToPanel.class, "LBL_GoToType_LocationJLabel")); // NOI18N
332
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 4, 0);
332
        gridBagConstraints = new java.awt.GridBagConstraints();
333
        add(jLabelLocation, gridBagConstraints);
333
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
334
334
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
335
        jTextFieldLocation.setEditable(false);
335
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 4, 0);
336
        jTextFieldLocation.setFocusable(false);
336
        add(jLabelLocation, gridBagConstraints);
337
        gridBagConstraints = new java.awt.GridBagConstraints();
337
338
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
338
        jTextFieldLocation.setEditable(false);
339
        gridBagConstraints.gridheight = java.awt.GridBagConstraints.REMAINDER;
339
        jTextFieldLocation.setFocusable(false);
340
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
340
        gridBagConstraints = new java.awt.GridBagConstraints();
341
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
341
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
342
        add(jTextFieldLocation, gridBagConstraints);
342
        gridBagConstraints.gridheight = java.awt.GridBagConstraints.REMAINDER;
343
    }// </editor-fold>//GEN-END:initComponents
343
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
344
344
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
345
    private void matchesListMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_matchesListMouseReleased
345
        add(jTextFieldLocation, gridBagConstraints);
346
        if ( evt.getClickCount() == 2 ) {
346
    }// </editor-fold>//GEN-END:initComponents
347
            nameFieldActionPerformed( null );
347
348
        }
348
    private void matchesListMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_matchesListMouseReleased
349
    }//GEN-LAST:event_matchesListMouseReleased
349
        if ( evt.getClickCount() == 2 ) {
350
350
            nameFieldActionPerformed( null );
351
    private void nameFieldKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_nameFieldKeyTyped
351
        }
352
        if (boundScrollingKey(evt)) {
352
    }//GEN-LAST:event_matchesListMouseReleased
353
            delegateScrollingKey(evt);
353
354
        }
354
    private void nameFieldKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_nameFieldKeyTyped
355
    }//GEN-LAST:event_nameFieldKeyTyped
355
        if (boundScrollingKey(evt)) {
356
356
            delegateScrollingKey(evt);
357
    private void nameFieldKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_nameFieldKeyReleased
357
        }
358
        if (boundScrollingKey(evt)) {
358
    }//GEN-LAST:event_nameFieldKeyTyped
359
            delegateScrollingKey(evt);
359
360
        }
360
    private void nameFieldKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_nameFieldKeyReleased
361
    }//GEN-LAST:event_nameFieldKeyReleased
361
        if (boundScrollingKey(evt)) {
362
362
            delegateScrollingKey(evt);
363
    private void nameFieldKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_nameFieldKeyPressed
363
        }
364
        if (boundScrollingKey(evt)) {
364
    }//GEN-LAST:event_nameFieldKeyReleased
365
            delegateScrollingKey(evt);
365
366
        } else {
366
    private void nameFieldKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_nameFieldKeyPressed
367
            //handling http://netbeans.org/bugzilla/show_bug.cgi?id=203512
367
        if (boundScrollingKey(evt)) {
368
            Object o = nameField.getInputMap().get(KeyStroke.getKeyStrokeForEvent(evt));
368
            delegateScrollingKey(evt);
369
            if (o instanceof String) {
369
        } else {
370
                String action = (String) o;
370
            //handling http://netbeans.org/bugzilla/show_bug.cgi?id=203512
371
                if ("paste-from-clipboard".equals(action)) {
371
            Object o = nameField.getInputMap().get(KeyStroke.getKeyStrokeForEvent(evt));
372
                    String selectedTxt = nameField.getSelectedText();
372
            if (o instanceof String) {
373
                    String txt = nameField.getText();
373
                String action = (String) o;
374
                    if (selectedTxt != null && txt != null) {
374
                if ("paste-from-clipboard".equals(action)) {
375
                        if (selectedTxt.length() == txt.length()) {
375
                    String selectedTxt = nameField.getSelectedText();
376
                            pastedFromClipboard = true;
376
                    String txt = nameField.getText();
377
                        }
377
                    if (selectedTxt != null && txt != null) {
378
                    }
378
                        if (selectedTxt.length() == txt.length()) {
379
                }
379
                            pastedFromClipboard = true;
380
            }
380
                        }
381
        }
381
                    }
382
    }//GEN-LAST:event_nameFieldKeyPressed
382
                }
383
383
            }
384
    private void nameFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_nameFieldActionPerformed
384
        }
385
        if (contentProvider.hasValidContent()) {
385
    }//GEN-LAST:event_nameFieldKeyPressed
386
            contentProvider.closeDialog();
386
387
            setSelectedTypes();
387
    private void nameFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_nameFieldActionPerformed
388
        }
388
        if (contentProvider.hasValidContent()) {
389
    }//GEN-LAST:event_nameFieldActionPerformed
389
            contentProvider.closeDialog();
390
    
390
            setSelectedTypes();
391
    
391
        }
392
    // Variables declaration - do not modify//GEN-BEGIN:variables
392
    }//GEN-LAST:event_nameFieldActionPerformed
393
    private javax.swing.JCheckBox caseSensitive;
393
    
394
    private javax.swing.JLabel jLabelList;
394
    
395
    private javax.swing.JLabel jLabelLocation;
395
    // Variables declaration - do not modify//GEN-BEGIN:variables
396
    private javax.swing.JLabel jLabelText;
396
    private javax.swing.JCheckBox caseSensitive;
397
    private javax.swing.JLabel jLabelWarning;
397
    private javax.swing.JLabel jLabelList;
398
    private javax.swing.JTextField jTextFieldLocation;
398
    private javax.swing.JLabel jLabelLocation;
399
    private javax.swing.JPanel listPanel;
399
    private javax.swing.JLabel jLabelText;
400
    private javax.swing.JList matchesList;
400
    private javax.swing.JLabel jLabelWarning;
401
    private javax.swing.JScrollPane matchesScrollPane1;
401
    private javax.swing.JTextField jTextFieldLocation;
402
    javax.swing.JTextField nameField;
402
    private javax.swing.JPanel listPanel;
403
    // End of variables declaration//GEN-END:variables
403
    private javax.swing.JList matchesList;
404
        
404
    private javax.swing.JScrollPane matchesScrollPane1;
405
    
405
    javax.swing.JTextField nameField;
406
    private String getText() {
406
    // End of variables declaration//GEN-END:variables
407
        try {
407
        
408
            String text = nameField.getDocument().getText(0, nameField.getDocument().getLength());
408
    
409
            return text;
409
    private String getText() {
410
        }
410
        try {
411
        catch( BadLocationException ex ) {
411
            String text = nameField.getDocument().getText(0, nameField.getDocument().getLength());
412
            return null;
412
            return text;
413
        }
413
        }
414
    }
414
        catch( BadLocationException ex ) {
415
    
415
            return null;
416
    private int getFontSize () {
416
        }
417
        return this.jLabelList.getFont().getSize();
417
    }
418
    }
418
    
419
    
419
    private int getFontSize () {
420
    public boolean isCaseSensitive () {
420
        return this.jLabelList.getFont().getSize();
421
        return this.caseSensitive.isSelected();
421
    }
422
    }
422
    
423
    
423
    public boolean isCaseSensitive () {
424
    void setListPanelContent( String message ,boolean waitIcon ) {
424
        return this.caseSensitive.isSelected();
425
        
425
    }
426
        if ( message == null && !containsScrollPane ) {
426
    
427
           listPanel.remove( messageLabel );
427
    void setListPanelContent( String message ,boolean waitIcon ) {
428
           listPanel.add( matchesScrollPane1 );
428
        
429
           containsScrollPane = true;
429
        if ( message == null && !containsScrollPane ) {
430
           revalidate();
430
           listPanel.remove( messageLabel );
431
           repaint();
431
           listPanel.add( matchesScrollPane1 );
432
        }        
432
           containsScrollPane = true;
433
        else if ( message != null ) { 
433
           revalidate();
434
           jTextFieldLocation.setText(""); 
434
           repaint();
435
           //handling http://netbeans.org/bugzilla/show_bug.cgi?id=178555
435
        }        
436
            messageLabel.setText(waitIcon
436
        else if ( message != null ) { 
437
                    ? "<html>" + message + "&nbsp;&nbsp;&nbsp;&nbsp;<a href=\"http://www.netbeans.org\">"+NbBundle.getMessage(GoToPanel.class, "TXT_CancelSearch")+"</a></html>" //NOI18N
437
           jTextFieldLocation.setText(""); 
438
                    : message);
438
           //handling http://netbeans.org/bugzilla/show_bug.cgi?id=178555
439
           messageLabel.setIcon( waitIcon ? WAIT_ICON : null);
439
            messageLabel.setText(waitIcon
440
           if ( containsScrollPane ) {
440
                    ? "<html>" + message + "&nbsp;&nbsp;&nbsp;&nbsp;<a href=\"http://www.netbeans.org\">"+NbBundle.getMessage(GoToPanel.class, "TXT_CancelSearch")+"</a></html>" //NOI18N
441
               listPanel.remove( matchesScrollPane1 );
441
                    : message);
442
               listPanel.add( messageLabel );
442
           messageLabel.setIcon( waitIcon ? WAIT_ICON : null);
443
               containsScrollPane = false;
443
           if ( containsScrollPane ) {
444
           }
444
               listPanel.remove( matchesScrollPane1 );
445
           revalidate();
445
               listPanel.add( messageLabel );
446
           repaint();
446
               containsScrollPane = false;
447
       }                
447
           }
448
    }
448
           revalidate();
449
    
449
           repaint();
450
    private String listActionFor(KeyEvent ev) {
450
       }                
451
        InputMap map = matchesList.getInputMap();
451
    }
452
        Object o = map.get(KeyStroke.getKeyStrokeForEvent(ev));
452
    
453
        if (o instanceof String) {
453
    private String listActionFor(KeyEvent ev) {
454
            return (String)o;
454
        InputMap map = matchesList.getInputMap();
455
        } else {
455
        Object o = map.get(KeyStroke.getKeyStrokeForEvent(ev));
456
            return null;
456
        if (o instanceof String) {
457
        }
457
            return (String)o;
458
    }
458
        } else {
459
459
            return null;
460
    private boolean boundScrollingKey(KeyEvent ev) {
460
        }
461
        String action = listActionFor(ev);
461
    }
462
        // See BasicListUI, MetalLookAndFeel:
462
463
        return "selectPreviousRow".equals(action) || // NOI18N
463
    private boolean boundScrollingKey(KeyEvent ev) {
464
        "selectNextRow".equals(action) || // NOI18N
464
        String action = listActionFor(ev);
465
        "selectPreviousRowExtendSelection".equals(action) ||    //NOI18N
465
        // See BasicListUI, MetalLookAndFeel:
466
        "selectNextRowExtendSelection".equals(action) || //NOI18N
466
        return "selectPreviousRow".equals(action) || // NOI18N
467
        "scrollUp".equals(action) || // NOI18N
467
        "selectNextRow".equals(action) || // NOI18N
468
        "scrollDown".equals(action); // NOI18N
468
        "selectPreviousRowExtendSelection".equals(action) ||    //NOI18N
469
    }
469
        "selectNextRowExtendSelection".equals(action) || //NOI18N
470
470
        "scrollUp".equals(action) || // NOI18N
471
    private void delegateScrollingKey(KeyEvent ev) {
471
        "scrollDown".equals(action); // NOI18N
472
        String action = listActionFor(ev);
472
    }
473
        
473
474
        // Wrap around
474
    private void delegateScrollingKey(KeyEvent ev) {
475
        if ( "selectNextRow".equals(action) && 
475
        String action = listActionFor(ev);
476
            matchesList.getSelectedIndex() == matchesList.getModel().getSize() -1 ) {
476
        
477
            matchesList.setSelectedIndex(0);
477
        // Wrap around
478
            matchesList.ensureIndexIsVisible(0);
478
        if ( "selectNextRow".equals(action) && 
479
            return;
479
            matchesList.getSelectedIndex() == matchesList.getModel().getSize() -1 ) {
480
        }
480
            matchesList.setSelectedIndex(0);
481
        else if ( "selectPreviousRow".equals(action) &&
481
            matchesList.ensureIndexIsVisible(0);
482
                  matchesList.getSelectedIndex() == 0 ) {
482
            return;
483
            int last = matchesList.getModel().getSize() - 1;
483
        }
484
            matchesList.setSelectedIndex(last);
484
        else if ( "selectPreviousRow".equals(action) &&
485
            matchesList.ensureIndexIsVisible(last);
485
                  matchesList.getSelectedIndex() == 0 ) {
486
            return;
486
            int last = matchesList.getModel().getSize() - 1;
487
        }        
487
            matchesList.setSelectedIndex(last);
488
        // Plain delegation        
488
            matchesList.ensureIndexIsVisible(last);
489
        Action a = matchesList.getActionMap().get(action);
489
            return;
490
        if (a != null) {
490
        }        
491
            a.actionPerformed(new ActionEvent(matchesList, 0, action));
491
        // Plain delegation        
492
        }
492
        Action a = matchesList.getActionMap().get(action);
493
    }
493
        if (a != null) {
494
    
494
            a.actionPerformed(new ActionEvent(matchesList, 0, action));
495
    private static class PatternListener implements DocumentListener, ItemListener, ListSelectionListener {
495
        }
496
               
496
    }
497
        private final GoToPanel dialog;
497
498
        
498
    private static class PatternListener implements DocumentListener, ItemListener, ListSelectionListener {
499
        
499
               
500
        PatternListener( GoToPanel dialog ) {
500
        private final GoToPanel dialog;
501
            this.dialog = dialog;
501
        
502
        }
502
        
503
        
503
        PatternListener( GoToPanel dialog ) {
504
        PatternListener( DocumentEvent e, GoToPanel dialog ) {
504
            this.dialog = dialog;
505
            this.dialog = dialog;
505
        }
506
        }
506
        
507
        
507
        PatternListener( DocumentEvent e, GoToPanel dialog ) {
508
        // DocumentListener ----------------------------------------------------
508
            this.dialog = dialog;
509
        
509
        }
510
        public void changedUpdate( DocumentEvent e ) {            
510
        
511
            update();
511
        // DocumentListener ----------------------------------------------------
512
        }
512
        
513
513
        public void changedUpdate( DocumentEvent e ) {            
514
        public void removeUpdate( DocumentEvent e ) {
514
            update();
515
            // handling http://netbeans.org/bugzilla/show_bug.cgi?id=203512
515
        }
516
            if (dialog.pastedFromClipboard) {
516
517
                dialog.pastedFromClipboard = false;
517
        public void removeUpdate( DocumentEvent e ) {
518
            } else {
518
            // handling http://netbeans.org/bugzilla/show_bug.cgi?id=203512
519
                update();
519
            if (dialog.pastedFromClipboard) {
520
            }
520
                dialog.pastedFromClipboard = false;
521
        }
521
            } else {
522
522
                update();
523
        public void insertUpdate( DocumentEvent e ) {
523
            }
524
            update();
524
        }
525
        }
525
526
        
526
        public void insertUpdate( DocumentEvent e ) {
527
        // Item Listener -------------------------------------------------------
527
            update();
528
        
528
        }
529
        public void itemStateChanged (final ItemEvent e) {
529
        
530
            UiOptions.GoToTypeDialog.setCaseSensitive(dialog.isCaseSensitive());
530
        // Item Listener -------------------------------------------------------
531
            update();
531
        
532
        }
532
        public void itemStateChanged (final ItemEvent e) {
533
        
533
            UiOptions.GoToTypeDialog.setCaseSensitive(dialog.isCaseSensitive());
534
        // ListSelectionListener -----------------------------------------------
534
            update();
535
        
535
        }
536
        public void valueChanged(ListSelectionEvent ev) {
536
        
537
            // got "Not computed yet" text sometimes
537
        // ListSelectionListener -----------------------------------------------
538
            Object obj = dialog.matchesList.getSelectedValue();
538
        
539
            
539
        public void valueChanged(ListSelectionEvent ev) {
540
            if (obj instanceof TypeDescriptor) {
540
            // got "Not computed yet" text sometimes
541
                TypeDescriptor selectedValue = ((TypeDescriptor) obj);
541
            Object obj = dialog.matchesList.getSelectedValue();
542
                if ( selectedValue != null ) {
542
            
543
                    String fileName = "";
543
            if (obj instanceof TypeDescriptor) {
544
                    FileObject fo = selectedValue.getFileObject();
544
                TypeDescriptor selectedValue = ((TypeDescriptor) obj);
545
                    if (fo != null) {
545
                if ( selectedValue != null ) {
546
                        fileName = FileUtil.getFileDisplayName(fo);
546
                    String fileName = "";
547
                    }
547
                    FileObject fo = selectedValue.getFileObject();
548
                    dialog.jTextFieldLocation.setText(fileName);
548
                    if (fo != null) {
549
                }
549
                        fileName = FileUtil.getFileDisplayName(fo);
550
                else {
550
                    }
551
                    dialog.jTextFieldLocation.setText("");
551
                    dialog.jTextFieldLocation.setText(fileName);
552
                }
552
                }
553
            } else {
553
                else {
554
                dialog.jTextFieldLocation.setText("");
554
                    dialog.jTextFieldLocation.setText("");
555
         }
555
                }
556
        }
556
            } else {
557
        
557
                dialog.jTextFieldLocation.setText("");
558
        private void update() {
558
         }
559
            dialog.time = System.currentTimeMillis();
559
        }
560
            String text = dialog.getText();
560
        
561
            if ( dialog.oldText == null || dialog.oldText.trim().length() == 0 || !text.startsWith(dialog.oldText) ) {
561
        private void update() {
562
                dialog.setListPanelContent(NbBundle.getMessage(GoToPanel.class, "TXT_Searching"),true); // NOI18N
562
            dialog.time = System.currentTimeMillis();
563
                }
563
            String text = dialog.getText();
564
            dialog.oldText = text;
564
            if ( dialog.oldText == null || dialog.oldText.trim().length() == 0 || !text.startsWith(dialog.oldText) ) {
565
            dialog.contentProvider.setListModel(dialog,text);            
565
                dialog.setListPanelContent(NbBundle.getMessage(GoToPanel.class, "TXT_Searching"),true); // NOI18N
566
        }
566
                }
567
                                         
567
            dialog.oldText = text;
568
    }
568
            dialog.contentProvider.setListModel(dialog,text);            
569
             
569
        }
570
        
570
                                         
571
    public static interface ContentProvider {
571
    }
572
        
572
             
573
        public ListCellRenderer getListCellRenderer( JList list );
573
        
574
        
574
    public static interface ContentProvider {
575
        public void setListModel( GoToPanel panel, String text );
575
        
576
        
576
        public ListCellRenderer getListCellRenderer( JList list, Document document);
577
        public void closeDialog();
577
        
578
        
578
        public void setListModel( GoToPanel panel, String text );
579
        public boolean hasValidContent ();
579
        
580
                
580
        public void closeDialog();
581
    }
581
        
582
    
582
        public boolean hasValidContent ();
583
}
583
584
    }
585
586
}
(-)a/jumpto/src/org/netbeans/modules/jumpto/type/GoToTypeAction.java (-864 / +904 lines)
Lines 1-864 Link Here
1
/*
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
3
 *
4
 * Copyright 1997-2011 Oracle and/or its affiliates. All rights reserved.
4
 * Copyright 1997-2011 Oracle and/or its affiliates. All rights reserved.
5
 *
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
7
 * Other names may be trademarks of their respective owners.
8
 *
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
26
 *
27
 * Contributor(s):
27
 * Contributor(s):
28
 *
28
 *
29
 * The Original Software is NetBeans. The Initial Developer of the Original
29
 * The Original Software is NetBeans. The Initial Developer of the Original
30
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2011 Sun
30
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2011 Sun
31
 * Microsystems, Inc. All Rights Reserved.
31
 * Microsystems, Inc. All Rights Reserved.
32
 *
32
 * 
33
 * If you wish your version of this file to be governed by only the CDDL
33
 * markiewb@netbeans.org
34
 * or only the GPL Version 2, indicate your decision by adding
34
 *
35
 * "[Contributor] elects to include this software in this distribution
35
 * If you wish your version of this file to be governed by only the CDDL
36
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
36
 * or only the GPL Version 2, indicate your decision by adding
37
 * single choice of license, a recipient has the option to distribute
37
 * "[Contributor] elects to include this software in this distribution
38
 * your version of this file under either the CDDL, the GPL Version 2 or
38
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
39
 * to extend the choice of license to its licensees as provided above.
39
 * single choice of license, a recipient has the option to distribute
40
 * However, if you add GPL Version 2 code and therefore, elected the GPL
40
 * your version of this file under either the CDDL, the GPL Version 2 or
41
 * Version 2 license, then the option applies only if the new code is
41
 * to extend the choice of license to its licensees as provided above.
42
 * made subject to such option by the copyright holder.
42
 * However, if you add GPL Version 2 code and therefore, elected the GPL
43
 */
43
 * Version 2 license, then the option applies only if the new code is
44
44
 * made subject to such option by the copyright holder.
45
package org.netbeans.modules.jumpto.type;
45
 */
46
46
47
import org.netbeans.spi.jumpto.type.SearchType;
47
package org.netbeans.modules.jumpto.type;
48
import org.netbeans.spi.jumpto.type.TypeProvider;
48
49
import org.netbeans.spi.jumpto.type.TypeDescriptor;
49
import org.netbeans.spi.jumpto.type.SearchType;
50
import java.awt.BorderLayout;
50
import org.netbeans.spi.jumpto.type.TypeProvider;
51
import java.awt.Component;
51
import org.netbeans.spi.jumpto.type.TypeDescriptor;
52
import java.awt.Color;
52
import java.awt.BorderLayout;
53
import java.awt.Container;
53
import java.awt.Component;
54
import java.awt.Dialog;
54
import java.awt.Color;
55
import java.awt.Dimension;
55
import java.awt.Container;
56
import java.awt.GridBagConstraints;
56
import java.awt.Dialog;
57
import java.awt.GridBagLayout;
57
import java.awt.Dimension;
58
import java.awt.Insets;
58
import java.awt.GridBagConstraints;
59
import java.awt.Rectangle;
59
import java.awt.GridBagLayout;
60
import java.awt.event.ActionEvent;
60
import java.awt.Insets;
61
import java.awt.event.ActionListener;
61
import java.awt.Rectangle;
62
import java.awt.event.MouseListener;
62
import java.awt.event.ActionEvent;
63
import java.awt.event.WindowAdapter;
63
import java.awt.event.ActionListener;
64
import java.awt.event.WindowEvent;
64
import java.awt.event.MouseListener;
65
import java.io.ByteArrayOutputStream;
65
import java.awt.event.WindowAdapter;
66
import java.io.DataOutputStream;
66
import java.awt.event.WindowEvent;
67
import java.io.IOException;
67
import java.io.ByteArrayOutputStream;
68
import java.util.ArrayList;
68
import java.io.DataOutputStream;
69
import java.util.Arrays;
69
import java.io.IOException;
70
import java.util.Collection;
70
import java.util.ArrayList;
71
import java.util.Collections;
71
import java.util.Arrays;
72
import java.util.List;
72
import java.util.Collection;
73
import java.util.logging.Level;
73
import java.util.Collections;
74
import java.util.logging.Logger;
74
import java.util.List;
75
import java.util.regex.Pattern;
75
import java.util.logging.Level;
76
import javax.swing.AbstractAction;
76
import java.util.logging.Logger;
77
import javax.swing.DefaultListModel;
77
import java.util.regex.Pattern;
78
import javax.swing.JButton;
78
import javax.swing.AbstractAction;
79
import javax.swing.ListCellRenderer;
79
import javax.swing.DefaultListModel;
80
import javax.swing.JEditorPane;
80
import javax.swing.JButton;
81
import javax.swing.JLabel;
81
import javax.swing.ListCellRenderer;
82
import javax.swing.JList;
82
import javax.swing.JEditorPane;
83
import javax.swing.JPanel;
83
import javax.swing.JLabel;
84
import javax.swing.JViewport;
84
import javax.swing.JList;
85
import javax.swing.ListModel;
85
import javax.swing.JPanel;
86
import javax.swing.SwingUtilities;
86
import javax.swing.JViewport;
87
import javax.swing.event.ChangeEvent;
87
import javax.swing.ListModel;
88
import org.netbeans.api.jumpto.type.TypeBrowser;
88
import javax.swing.SwingUtilities;
89
import org.netbeans.api.project.ui.OpenProjects;
89
import javax.swing.event.ChangeEvent;
90
import org.netbeans.modules.jumpto.EntitiesListCellRenderer;
90
import javax.swing.event.DocumentEvent;
91
import org.netbeans.modules.jumpto.file.LazyListModel;
91
import javax.swing.event.DocumentListener;
92
import org.netbeans.modules.sampler.Sampler;
92
import javax.swing.text.BadLocationException;
93
import org.openide.DialogDescriptor;
93
import javax.swing.text.Document;
94
import org.openide.DialogDisplayer;
94
import org.netbeans.api.jumpto.type.TypeBrowser;
95
import org.openide.ErrorManager;
95
import org.netbeans.api.project.ui.OpenProjects;
96
import org.openide.cookies.EditorCookie;
96
import org.netbeans.modules.jumpto.EntitiesListCellRenderer;
97
import org.openide.filesystems.FileObject;
97
import org.netbeans.modules.jumpto.file.LazyListModel;
98
import org.openide.filesystems.FileUtil;
98
import org.netbeans.modules.sampler.Sampler;
99
import org.openide.nodes.Node;
99
import org.openide.DialogDescriptor;
100
import org.openide.text.NbDocument;
100
import org.openide.DialogDisplayer;
101
import org.openide.util.Exceptions;
101
import org.openide.ErrorManager;
102
import org.openide.util.HelpCtx;
102
import org.openide.cookies.EditorCookie;
103
import org.openide.util.ImageUtilities;
103
import org.openide.filesystems.FileObject;
104
import org.openide.util.Lookup;
104
import org.openide.filesystems.FileUtil;
105
import org.openide.util.NbBundle;
105
import org.openide.nodes.Node;
106
import org.openide.util.RequestProcessor;
106
import org.openide.text.NbDocument;
107
import org.openide.util.Utilities;
107
import org.openide.util.Exceptions;
108
import org.openide.windows.TopComponent;
108
import org.openide.util.HelpCtx;
109
109
import org.openide.util.ImageUtilities;
110
/** 
110
import org.openide.util.Lookup;
111
 * XXX split into action and support class, left this just to minimize diff
111
import org.openide.util.NbBundle;
112
 * XXX Icons
112
import org.openide.util.RequestProcessor;
113
 * XXX Don't look for all projects (do it lazy in filter or renderer)
113
import org.openide.util.Utilities;
114
 * @author Petr Hrebejk
114
import org.openide.windows.TopComponent;
115
 */
115
116
public class GoToTypeAction extends AbstractAction implements GoToPanel.ContentProvider, LazyListModel.Filter {
116
/**
117
    
117
 * XXX split into action and support class, left this just to minimize diff
118
    static final Logger LOGGER = Logger.getLogger(GoToTypeAction.class.getName()); // Used from the panel as well
118
 * XXX Icons
119
    
119
 * XXX Don't look for all projects (do it lazy in filter or renderer)
120
    private SearchType nameKind;
120
 * @author Petr Hrebejk
121
    private static ListModel EMPTY_LIST_MODEL = new DefaultListModel();
121
 */
122
    private static final RequestProcessor rp = new RequestProcessor ("GoToTypeAction-RequestProcessor",1);      //NOI18N
122
public class GoToTypeAction extends AbstractAction implements GoToPanel.ContentProvider, LazyListModel.Filter {
123
    private static final RequestProcessor PROFILE_RP = new RequestProcessor("GoToTypeAction-Profile",1);        //NOI18N
123
124
    private Worker running;
124
    static final Logger LOGGER = Logger.getLogger(GoToTypeAction.class.getName()); // Used from the panel as well
125
    private RequestProcessor.Task task;
125
    
126
    GoToPanel panel;
126
    private SearchType nameKind;
127
    private Dialog dialog;
127
    private static ListModel EMPTY_LIST_MODEL = new DefaultListModel();
128
    private JButton okButton;
128
    private static final RequestProcessor rp = new RequestProcessor ("GoToTypeAction-RequestProcessor",1);      //NOI18N
129
    private Collection<? extends TypeProvider> typeProviders;
129
    private static final RequestProcessor PROFILE_RP = new RequestProcessor("GoToTypeAction-Profile",1);        //NOI18N
130
    private final Collection<? extends TypeProvider> implicitTypeProviders;
130
    private Worker running;
131
    private final TypeBrowser.Filter typeFilter;
131
    private RequestProcessor.Task task;
132
    private final String title;
132
    GoToPanel panel;
133
    private final boolean multiSelection;
133
    private Dialog dialog;
134
134
    private JButton okButton;
135
    /** Creates a new instance of OpenTypeAction */
135
    private Collection<? extends TypeProvider> typeProviders;
136
    public GoToTypeAction() {
136
    private final Collection<? extends TypeProvider> implicitTypeProviders;
137
        this(
137
    private final TypeBrowser.Filter typeFilter;
138
            NbBundle.getMessage( GoToTypeAction.class, "DLG_GoToType" ),
138
    private final String title;
139
            null,
139
    private final boolean multiSelection;
140
            true
140
141
        );
141
    /** Creates a new instance of OpenTypeAction */
142
    }
142
    public GoToTypeAction() {
143
    
143
        this(
144
    public GoToTypeAction(String title, TypeBrowser.Filter typeFilter, boolean multiSelection, TypeProvider... typeProviders) {
144
            NbBundle.getMessage( GoToTypeAction.class, "DLG_GoToType" ),
145
        super( NbBundle.getMessage( GoToTypeAction.class,"TXT_GoToType") );
145
                null,
146
        putValue("PopupMenuText", NbBundle.getBundle(GoToTypeAction.class).getString("editor-popup-TXT_GoToType")); // NOI18N
146
            true
147
        this.title = title;
147
        );
148
        this.typeFilter = typeFilter;
148
    }
149
        this.implicitTypeProviders = typeProviders.length == 0 ? null : Collections.unmodifiableCollection(Arrays.asList(typeProviders));
149
150
        this.multiSelection = multiSelection;
150
    public GoToTypeAction(String title, TypeBrowser.Filter typeFilter, boolean multiSelection, TypeProvider... typeProviders) {
151
    }
151
        super( NbBundle.getMessage( GoToTypeAction.class,"TXT_GoToType") );
152
    
152
        putValue("PopupMenuText", NbBundle.getBundle(GoToTypeAction.class).getString("editor-popup-TXT_GoToType")); // NOI18N
153
    @Override
153
        this.title = title;
154
    public void actionPerformed( ActionEvent e ) {
154
        this.typeFilter = typeFilter;
155
        for (TypeDescriptor td : getSelectedTypes()) {
155
        this.implicitTypeProviders = typeProviders.length == 0 ? null : Collections.unmodifiableCollection(Arrays.asList(typeProviders));
156
            td.open();
156
        this.multiSelection = multiSelection;
157
        }
157
    }
158
    }
158
159
            
159
    @Override
160
    public Iterable<? extends TypeDescriptor> getSelectedTypes() {
160
    public void actionPerformed( ActionEvent e ) {
161
        return getSelectedTypes(true);
161
        for (TypeDescriptor td : getSelectedTypes()) {
162
    }
162
            td.open();
163
    
163
        }
164
    public Iterable<? extends TypeDescriptor> getSelectedTypes(final boolean visible) {
164
    }
165
        return getSelectedTypes(visible, null);
165
166
    }
166
    public Iterable<? extends TypeDescriptor> getSelectedTypes() {
167
167
        return getSelectedTypes(true);
168
    public Iterable<? extends TypeDescriptor> getSelectedTypes(final boolean visible, String initSearchText) {
168
    }
169
        Iterable<? extends TypeDescriptor> result = Collections.emptyList();
169
170
        try {
170
    public Iterable<? extends TypeDescriptor> getSelectedTypes(final boolean visible) {
171
            panel = new GoToPanel(this, multiSelection);
171
        return getSelectedTypes(visible, null);
172
            dialog = createDialog(panel);
172
    }
173
173
174
            if (initSearchText != null) {
174
    public Iterable<? extends TypeDescriptor> getSelectedTypes(final boolean visible, String initSearchText) {
175
                panel.setInitialText(initSearchText);
175
        Iterable<? extends TypeDescriptor> result = Collections.emptyList();
176
            } else {
176
        try {
177
                Node[] arr = TopComponent.getRegistry ().getActivatedNodes();
177
            panel = new GoToPanel(this, multiSelection);
178
                if (arr.length > 0) {
178
            dialog = createDialog(panel);
179
                    EditorCookie ec = arr[0].getCookie (EditorCookie.class);
179
180
                    if (ec != null) {
180
            if (initSearchText != null) {
181
                        JEditorPane recentPane = NbDocument.findRecentEditorPane(ec);
181
                panel.setInitialText(initSearchText);
182
                        if (recentPane != null) {
182
            } else {
183
                            initSearchText = org.netbeans.editor.Utilities.getSelectionOrIdentifier(recentPane);
183
                Node[] arr = TopComponent.getRegistry ().getActivatedNodes();
184
                            if (initSearchText != null && org.openide.util.Utilities.isJavaIdentifier(initSearchText)) {
184
                if (arr.length > 0) {
185
                                panel.setInitialText(initSearchText);
185
                    EditorCookie ec = arr[0].getCookie (EditorCookie.class);
186
                            } else {
186
                    if (ec != null) {
187
                                panel.setInitialText(arr[0].getName());
187
                        JEditorPane recentPane = NbDocument.findRecentEditorPane(ec);
188
                            }
188
                        if (recentPane != null) {
189
                        }
189
                            initSearchText = org.netbeans.editor.Utilities.getSelectionOrIdentifier(recentPane);
190
                    }
190
                            if (initSearchText != null && org.openide.util.Utilities.isJavaIdentifier(initSearchText)) {
191
                }
191
                                panel.setInitialText(initSearchText);
192
            }
192
                            } else {
193
            
193
                                panel.setInitialText(arr[0].getName());
194
            dialog.setVisible(visible);
194
                            }
195
            result = panel.getSelectedTypes();
195
                        }
196
196
                    }
197
        } catch (IOException ex) {
197
                }
198
            ErrorManager.getDefault().notify(ex);
198
            }
199
        }
199
200
        return result;
200
            dialog.setVisible(visible);
201
    }
201
            result = panel.getSelectedTypes();
202
    
202
203
    @Override
203
        } catch (IOException ex) {
204
    public boolean isEnabled () {
204
            ErrorManager.getDefault().notify(ex);
205
        return OpenProjects.getDefault().getOpenProjects().length>0;
205
        }
206
    }
206
        return result;
207
    
207
    }
208
    @Override
208
209
    public boolean accept(Object obj) {
209
    @Override
210
        return typeFilter == null ? true : typeFilter.accept((TypeDescriptor) obj);
210
    public boolean isEnabled () {
211
    }
211
        return OpenProjects.getDefault().getOpenProjects().length>0;
212
    
212
    }
213
    @Override
213
214
    public void scheduleUpdate(Runnable run) {
214
    @Override
215
        SwingUtilities.invokeLater(run);
215
    public boolean accept(Object obj) {
216
    }
216
        return typeFilter == null ? true : typeFilter.accept((TypeDescriptor) obj);
217
    
217
    }
218
    // Implementation of content provider --------------------------------------
218
219
    
219
    @Override
220
    
220
    public void scheduleUpdate(Runnable run) {
221
    @Override
221
        SwingUtilities.invokeLater(run);
222
    public ListCellRenderer getListCellRenderer( JList list ) {
222
    }
223
        return new Renderer( list );        
223
224
    }
224
    // Implementation of content provider --------------------------------------
225
    
225
226
    
226
    
227
    @Override
227
    @Override
228
    public void setListModel( GoToPanel panel, String text ) {
228
    public ListCellRenderer getListCellRenderer(JList list, Document nameFieldDocument) {
229
        assert SwingUtilities.isEventDispatchThread();
229
230
        if (okButton != null) {
230
        Renderer renderer = new Renderer(list);
231
            okButton.setEnabled (false);
231
        //notify the render of the changed search text
232
        } 
232
        nameFieldDocument.addDocumentListener(renderer);
233
        //handling http://netbeans.org/bugzilla/show_bug.cgi?id=178555
233
234
        //add a MouseListener to the messageLabel JLabel so that the search can be cancelled without exiting the dialog
234
        return renderer;
235
        final GoToPanel goToPanel = panel;
235
    }
236
        final MouseListener warningMouseListener = new java.awt.event.MouseAdapter() {
236
237
237
    
238
            @Override
238
    @Override
239
            public void mouseClicked(java.awt.event.MouseEvent evt) {
239
    public void setListModel( GoToPanel panel, String text ) {
240
                if (running != null) {
240
        assert SwingUtilities.isEventDispatchThread();
241
                    running.cancel();
241
        if (okButton != null) {
242
                    task.cancel();
242
            okButton.setEnabled (false);
243
                    running = null;
243
        }
244
                }
244
        //handling http://netbeans.org/bugzilla/show_bug.cgi?id=178555
245
                goToPanel.setListPanelContent(NbBundle.getMessage(GoToPanel.class, "TXT_SearchCanceled"),false); // NOI18N
245
        //add a MouseListener to the messageLabel JLabel so that the search can be cancelled without exiting the dialog
246
            }
246
        final GoToPanel goToPanel = panel;
247
        };
247
        final MouseListener warningMouseListener = new java.awt.event.MouseAdapter() {
248
        panel.setMouseListener(warningMouseListener);
248
249
        if ( running != null ) {
249
            @Override
250
            running.cancel();
250
            public void mouseClicked(java.awt.event.MouseEvent evt) {
251
            task.cancel();
251
                if (running != null) {
252
            running = null;
252
                    running.cancel();
253
        }
253
                    task.cancel();
254
        
254
                    running = null;
255
        if ( text == null ) {
255
                }
256
            panel.setModel(EMPTY_LIST_MODEL);
256
                goToPanel.setListPanelContent(NbBundle.getMessage(GoToPanel.class, "TXT_SearchCanceled"),false); // NOI18N
257
            return;
257
            }
258
        }
258
        };
259
        
259
        panel.setMouseListener(warningMouseListener);
260
        boolean exact = text.endsWith(" "); // NOI18N
260
        if ( running != null ) {
261
        
261
            running.cancel();
262
        text = text.trim();
262
            task.cancel();
263
        
263
            running = null;
264
        if ( text.length() == 0) {
264
        }
265
            panel.setModel(EMPTY_LIST_MODEL);
265
266
            return;
266
        if ( text == null ) {
267
        }
267
            panel.setModel(EMPTY_LIST_MODEL);
268
        
268
            return;
269
        int wildcard = containsWildCard(text);
269
        }
270
                
270
271
        if (exact) {
271
        boolean exact = text.endsWith(" "); // NOI18N
272
            //nameKind = panel.isCaseSensitive() ? SearchType.EXACT_NAME : SearchType.CASE_INSENSITIVE_EXACT_NAME;
272
273
            nameKind = SearchType.EXACT_NAME;
273
        text = text.trim();
274
        }
274
275
        else if ((isAllUpper(text) && text.length() > 1) || isCamelCase(text)) {
275
        if ( text.length() == 0) {
276
            nameKind = SearchType.CAMEL_CASE;
276
            panel.setModel(EMPTY_LIST_MODEL);
277
        }
277
            return;
278
        else if (wildcard != -1) {
278
        }
279
            nameKind = panel.isCaseSensitive() ? SearchType.REGEXP : SearchType.CASE_INSENSITIVE_REGEXP;                
279
280
        }
280
        int wildcard = containsWildCard(text);
281
        else {            
281
282
            nameKind = panel.isCaseSensitive() ? SearchType.PREFIX : SearchType.CASE_INSENSITIVE_PREFIX;
282
        if (exact) {
283
        }
283
            //nameKind = panel.isCaseSensitive() ? SearchType.EXACT_NAME : SearchType.CASE_INSENSITIVE_EXACT_NAME;
284
        
284
            nameKind = SearchType.EXACT_NAME;
285
        // Compute in other thread        
285
        }
286
        running = new Worker( text );
286
        else if ((isAllUpper(text) && text.length() > 1) || isCamelCase(text)) {
287
        task = rp.post( running, 220);
287
            nameKind = SearchType.CAMEL_CASE;
288
        if ( panel.time != -1 ) {
288
        }
289
            LOGGER.log( Level.FINE, "Worker posted after {0} ms.", System.currentTimeMillis() - panel.time ); //NOI18N
289
        else if (wildcard != -1) {
290
        }
290
            nameKind = panel.isCaseSensitive() ? SearchType.REGEXP : SearchType.CASE_INSENSITIVE_REGEXP;
291
    }
291
        }
292
    
292
        else {            
293
    @Override
293
            nameKind = panel.isCaseSensitive() ? SearchType.PREFIX : SearchType.CASE_INSENSITIVE_PREFIX;
294
    public void closeDialog() {
294
        }
295
        // Closing event can be sent several times.
295
        
296
        if (dialog == null ) { // #172568
296
        // Compute in other thread        
297
            return; // OK - the dialog has already been closed.
297
        running = new Worker( text );
298
        }
298
        task = rp.post( running, 220);
299
        dialog.setVisible( false );
299
        if ( panel.time != -1 ) {
300
        cleanup();
300
            LOGGER.log( Level.FINE, "Worker posted after {0} ms.", System.currentTimeMillis() - panel.time ); //NOI18N
301
    }
301
        }
302
    
302
    }
303
    @Override
303
304
    public boolean hasValidContent () {
304
    @Override
305
        return this.okButton != null && this.okButton.isEnabled();
305
    public void closeDialog() {
306
    }
306
        // Closing event can be sent several times.
307
    
307
        if (dialog == null ) { // #172568
308
    // Private methods ---------------------------------------------------------
308
            return; // OK - the dialog has already been closed.
309
        
309
        }
310
    public static boolean isAllUpper( String text ) {
310
        dialog.setVisible( false );
311
        for( int i = 0; i < text.length(); i++ ) {
311
        cleanup();
312
            if ( !Character.isUpperCase( text.charAt( i ) ) ) {
312
    }
313
                return false;
313
314
            }
314
    @Override
315
        }
315
    public boolean hasValidContent () {
316
        
316
        return this.okButton != null && this.okButton.isEnabled();
317
        return true;
317
    }
318
    }
318
319
    
319
    // Private methods ---------------------------------------------------------
320
    public static int containsWildCard( String text ) {
320
        
321
        for( int i = 0; i < text.length(); i++ ) {
321
    public static boolean isAllUpper( String text ) {
322
            if ( text.charAt( i ) == '?' || text.charAt( i ) == '*' ) { // NOI18N
322
        for( int i = 0; i < text.length(); i++ ) {
323
                return i;                
323
            if ( !Character.isUpperCase( text.charAt( i ) ) ) {
324
            }
324
                return false;
325
        }        
325
            }
326
        return -1;
326
        }
327
    }
327
328
    
328
        return true;
329
    private static Pattern camelCasePattern = Pattern.compile("(?:\\p{javaUpperCase}(?:\\p{javaLowerCase}|\\p{Digit}|\\.|\\$)*){2,}"); // NOI18N
329
    }
330
    
330
331
    public static boolean isCamelCase(String text) {
331
    public static int containsWildCard( String text ) {
332
         return camelCasePattern.matcher(text).matches();
332
        for( int i = 0; i < text.length(); i++ ) {
333
    }
333
            if ( text.charAt( i ) == '?' || text.charAt( i ) == '*' ) { // NOI18N
334
    
334
                return i;
335
    
335
            }
336
    /** Creates the dialog to show
336
        }
337
     */
337
        return -1;
338
   private Dialog createDialog( final GoToPanel panel) {
338
    }
339
       
339
    
340
        okButton = new JButton (NbBundle.getMessage(GoToTypeAction.class, "CTL_OK"));
340
    private static Pattern camelCasePattern = Pattern.compile("(?:\\p{javaUpperCase}(?:\\p{javaLowerCase}|\\p{Digit}|\\.|\\$)*){2,}"); // NOI18N
341
        okButton.getAccessibleContext().setAccessibleDescription(okButton.getText());
341
342
        okButton.setEnabled (false);
342
    public static boolean isCamelCase(String text) {
343
        panel.getAccessibleContext().setAccessibleName( NbBundle.getMessage( GoToTypeAction.class, "AN_GoToType") ); //NOI18N
343
        return camelCasePattern.matcher(text).matches();
344
        panel.getAccessibleContext().setAccessibleDescription( NbBundle.getMessage( GoToTypeAction.class, "AD_GoToType") ); //NOI18N
344
    }
345
                        
345
346
        DialogDescriptor dialogDescriptor = new DialogDescriptor(
346
    
347
            panel,                             // innerPane
347
    /** Creates the dialog to show
348
            title, // displayName
348
     */
349
            true,
349
   private Dialog createDialog( final GoToPanel panel) {
350
            new Object[] {okButton, DialogDescriptor.CANCEL_OPTION},
350
351
            okButton,
351
        okButton = new JButton (NbBundle.getMessage(GoToTypeAction.class, "CTL_OK"));
352
            DialogDescriptor.DEFAULT_ALIGN,
352
        okButton.getAccessibleContext().setAccessibleDescription(okButton.getText());
353
            HelpCtx.DEFAULT_HELP,
353
        okButton.setEnabled (false);
354
            new DialogButtonListener( panel ) );                                 // Action listener
354
        panel.getAccessibleContext().setAccessibleName( NbBundle.getMessage( GoToTypeAction.class, "AN_GoToType") ); //NOI18N
355
        
355
        panel.getAccessibleContext().setAccessibleDescription( NbBundle.getMessage( GoToTypeAction.class, "AD_GoToType") ); //NOI18N
356
         dialogDescriptor.setClosingOptions(new Object[] {okButton, DialogDescriptor.CANCEL_OPTION});
356
357
            
357
        DialogDescriptor dialogDescriptor = new DialogDescriptor(
358
        // panel.addPropertyChangeListener( new HelpCtxChangeListener( dialogDescriptor, helpCtx ) );
358
            panel,                             // innerPane
359
//        if ( panel instanceof HelpCtx.Provider ) {
359
                title, // displayName
360
//            dialogDescriptor.setHelpCtx( ((HelpCtx.Provider)panel).getHelpCtx() );
360
                true,
361
//        }
361
            new Object[] {okButton, DialogDescriptor.CANCEL_OPTION},
362
        
362
                okButton,
363
        Dialog d = DialogDisplayer.getDefault().createDialog( dialogDescriptor );
363
                DialogDescriptor.DEFAULT_ALIGN,
364
        
364
                HelpCtx.DEFAULT_HELP,
365
        // Set size when needed
365
            new DialogButtonListener( panel ) );                                 // Action listener
366
        final int width = UiOptions.GoToTypeDialog.getWidth();
366
367
        final int height = UiOptions.GoToTypeDialog.getHeight();
367
         dialogDescriptor.setClosingOptions(new Object[] {okButton, DialogDescriptor.CANCEL_OPTION});
368
        if (width != -1 && height != -1) {
368
369
            d.setPreferredSize(new Dimension(width,height));
369
        // panel.addPropertyChangeListener( new HelpCtxChangeListener( dialogDescriptor, helpCtx ) );
370
        }
370
//        if ( panel instanceof HelpCtx.Provider ) {
371
        
371
//            dialogDescriptor.setHelpCtx( ((HelpCtx.Provider)panel).getHelpCtx() );
372
        // Center the dialog after the size changed.
372
//        }
373
        Rectangle r = Utilities.getUsableScreenBounds();
373
374
        int maxW = (r.width * 9) / 10;
374
        Dialog d = DialogDisplayer.getDefault().createDialog( dialogDescriptor );
375
        int maxH = (r.height * 9) / 10;
375
376
        final Dimension dim = d.getPreferredSize();
376
        // Set size when needed
377
        dim.width = Math.min(dim.width, maxW);
377
        final int width = UiOptions.GoToTypeDialog.getWidth();
378
        dim.height = Math.min(dim.height, maxH);
378
        final int height = UiOptions.GoToTypeDialog.getHeight();
379
        d.setBounds(Utilities.findCenterBounds(dim));
379
        if (width != -1 && height != -1) {
380
        initialDimension = dim;
380
            d.setPreferredSize(new Dimension(width,height));
381
        d.addWindowListener(new WindowAdapter() {
381
        }
382
            public @Override void windowClosed(WindowEvent e) {
382
383
                cleanup();
383
        // Center the dialog after the size changed.
384
            }
384
        Rectangle r = Utilities.getUsableScreenBounds();
385
        });
385
        int maxW = (r.width * 9) / 10;
386
        
386
        int maxH = (r.height * 9) / 10;
387
        return d;
387
        final Dimension dim = d.getPreferredSize();
388
388
        dim.width = Math.min(dim.width, maxW);
389
    } 
389
        dim.height = Math.min(dim.height, maxH);
390
   
390
        d.setBounds(Utilities.findCenterBounds(dim));
391
    private Dimension initialDimension;
391
        initialDimension = dim;
392
    
392
        d.addWindowListener(new WindowAdapter() {
393
    private void cleanup() {    
393
            public @Override void windowClosed(WindowEvent e) {
394
        assert SwingUtilities.isEventDispatchThread();
394
                cleanup();
395
        if ( GoToTypeAction.this.dialog != null ) { // Closing event for some reson sent twice
395
            }
396
        
396
        });
397
            // Save dialog size only when changed
397
398
            final int currentWidth = dialog.getWidth();
398
        return d;
399
            final int currentHeight = dialog.getHeight();
399
400
            if (initialDimension != null && (initialDimension.width != currentWidth || initialDimension.height != currentHeight)) {
400
    }
401
                UiOptions.GoToTypeDialog.setHeight(currentHeight);
401
   
402
                UiOptions.GoToTypeDialog.setWidth(currentWidth);
402
    private Dimension initialDimension;
403
            }
403
404
            initialDimension = null;
404
    private void cleanup() {
405
            // Clean caches
405
        assert SwingUtilities.isEventDispatchThread();
406
            GoToTypeAction.this.dialog.dispose();
406
        if ( GoToTypeAction.this.dialog != null ) { // Closing event for some reson sent twice
407
            GoToTypeAction.this.dialog = null;                                    
407
408
            //1st) Cancel current task
408
            // Save dialog size only when changed
409
            if ( running != null ) {
409
            final int currentWidth = dialog.getWidth();
410
                running.cancel();
410
            final int currentHeight = dialog.getHeight();
411
                task.cancel();
411
            if (initialDimension != null && (initialDimension.width != currentWidth || initialDimension.height != currentHeight)) {
412
                running = null;
412
                UiOptions.GoToTypeDialog.setHeight(currentHeight);
413
            }
413
                UiOptions.GoToTypeDialog.setWidth(currentWidth);
414
            //2nd do clean up in the same thread as init to prevent races
414
            }
415
            rp.submit(new Runnable(){
415
            initialDimension = null;
416
                @Override
416
            // Clean caches
417
                public void run() {
417
            GoToTypeAction.this.dialog.dispose();
418
                    assert rp.isRequestProcessorThread();
418
            GoToTypeAction.this.dialog = null;
419
                    if (typeProviders != null) {
419
            //1st) Cancel current task
420
                        for (TypeProvider provider : typeProviders) {
420
            if ( running != null ) {
421
                            provider.cleanup();
421
                running.cancel();
422
                        }
422
                task.cancel();
423
                        typeProviders = null;
423
                running = null;
424
                    }
424
            }
425
                }
425
            //2nd do clean up in the same thread as init to prevent races
426
            });            
426
            rp.submit(new Runnable(){
427
        }
427
                @Override
428
    }
428
                public void run() {
429
    
429
                    assert rp.isRequestProcessorThread();
430
    // Private classes ---------------------------------------------------------
430
                    if (typeProviders != null) {
431
       
431
                        for (TypeProvider provider : typeProviders) {
432
    
432
                            provider.cleanup();
433
    
433
                        }
434
    private class Worker implements Runnable {
434
                        typeProviders = null;
435
        
435
                    }
436
        private volatile boolean isCanceled = false;
436
                }
437
        private volatile TypeProvider current;
437
            });
438
        private final String text;
438
        }
439
        
439
    }
440
        private final long createTime;
440
441
        
441
    // Private classes ---------------------------------------------------------
442
        public Worker( String text ) {
442
443
            this.text = text;
443
    
444
            this.createTime = System.currentTimeMillis();
444
    
445
            LOGGER.log( Level.FINE, "Worker for {0} - created after {1} ms.",   //NOI18N
445
    private class Worker implements Runnable {
446
                    new Object[]{
446
447
                        text,
447
        private volatile boolean isCanceled = false;
448
                        System.currentTimeMillis() - panel.time
448
        private volatile TypeProvider current;
449
                    });
449
        private final String text;
450
        }
450
        
451
451
        private final long createTime;
452
        @Override
452
453
        public void run() {
453
        public Worker( String text ) {
454
            for (;;) {
454
            this.text = text;
455
                final int[] retry = new int[1];
455
            this.createTime = System.currentTimeMillis();
456
456
            LOGGER.log( Level.FINE, "Worker for {0} - created after {1} ms.",   //NOI18N
457
                Profile profile = initializeProfiling();
457
                    new Object[]{
458
                try {
458
                        text,
459
                    LOGGER.log( Level.FINE, "Worker for {0} - started {1} ms.",     //NOI18N
459
                        System.currentTimeMillis() - panel.time
460
                            new Object[]{
460
                    });
461
                                text,
461
        }
462
                                System.currentTimeMillis() - createTime
462
463
                            });
463
        @Override
464
464
        public void run() {
465
                    final List<? extends TypeDescriptor> types = getTypeNames(text, retry);
465
            for (;;) {
466
                    if ( isCanceled ) {
466
                final int[] retry = new int[1];
467
                        LOGGER.log( Level.FINE, "Worker for {0} exited after cancel {1} ms.",   //NOI18N
467
468
                                new Object[]{
468
                Profile profile = initializeProfiling();
469
                                    text,
469
                try {
470
                                    System.currentTimeMillis() - createTime
470
                    LOGGER.log( Level.FINE, "Worker for {0} - started {1} ms.",     //NOI18N
471
                                });
471
                            new Object[]{
472
                        return;
472
                                text,
473
                    }
473
                                System.currentTimeMillis() - createTime
474
                    ListModel model = Models.fromList(types);
474
                            });
475
                    if (typeFilter != null) {
475
476
                        model = LazyListModel.create(model, GoToTypeAction.this, 0.1, "Not computed yet");  
476
                    final List<? extends TypeDescriptor> types = getTypeNames(text, retry);
477
                    }
477
                    if ( isCanceled ) {
478
                    final ListModel fmodel = model;
478
                        LOGGER.log( Level.FINE, "Worker for {0} exited after cancel {1} ms.",   //NOI18N
479
                    if ( isCanceled ) {
479
                                new Object[]{
480
                        LOGGER.log( Level.FINE, "Worker for {0} exited after cancel {1} ms.",   //NOI18N
480
                                    text,
481
                                new Object[]{
481
                                    System.currentTimeMillis() - createTime
482
                                    text,
482
                                });
483
                                    System.currentTimeMillis() - createTime
483
                        return;
484
                                });
484
                    }
485
                        return;
485
                    ListModel model = Models.fromList(types);
486
                    }
486
                    if (typeFilter != null) {
487
487
                        model = LazyListModel.create(model, GoToTypeAction.this, 0.1, "Not computed yet");
488
                    if ( !isCanceled && fmodel != null ) {
488
                    }
489
                        LOGGER.log( Level.FINE, "Worker for text {0} finished after {1} ms.",   //NOI18N
489
                    final ListModel fmodel = model;
490
                                new Object[]{
490
                    if ( isCanceled ) {
491
                                    text,
491
                        LOGGER.log( Level.FINE, "Worker for {0} exited after cancel {1} ms.",   //NOI18N
492
                                    System.currentTimeMillis() - createTime
492
                                new Object[]{
493
                                });
493
                                    text,
494
                        SwingUtilities.invokeLater(new Runnable() {
494
                                    System.currentTimeMillis() - createTime
495
                            @Override
495
                                });
496
                            public void run() {
496
                        return;
497
                                panel.setModel(fmodel);
497
                    }
498
                                if (okButton != null && !types.isEmpty()) {
498
499
                                    okButton.setEnabled (true);
499
                    if ( !isCanceled && fmodel != null ) {
500
                                }
500
                        LOGGER.log( Level.FINE, "Worker for text {0} finished after {1} ms.",   //NOI18N
501
                            }
501
                                new Object[]{
502
                        });
502
                                    text,
503
                    }
503
                                    System.currentTimeMillis() - createTime
504
                } finally {
504
                                });
505
                    if (profile != null) {
505
                        SwingUtilities.invokeLater(new Runnable() {
506
                        try {
506
                            @Override
507
                            profile.stop();
507
                            public void run() {
508
                        } catch (Exception ex) {
508
                                panel.setModel(fmodel);
509
                            LOGGER.log(Level.INFO, "Cannot stop profiling", ex);    //NOI18N
509
                                if (okButton != null && !types.isEmpty()) {
510
                        }
510
                                    okButton.setEnabled (true);
511
                    }
511
                                }
512
                }
512
                            }
513
513
                        });
514
                if (retry[0] > 0) {
514
                    }
515
                    try {
515
                } finally {
516
                        Thread.sleep(retry[0]);
516
                    if (profile != null) {
517
                    } catch (InterruptedException ex) {
517
                        try {
518
                        Exceptions.printStackTrace(ex);
518
                            profile.stop();
519
                    }
519
                        } catch (Exception ex) {
520
                } else {
520
                            LOGGER.log(Level.INFO, "Cannot stop profiling", ex);    //NOI18N
521
                    return;
521
                        }
522
                }
522
                    }
523
            } // for
523
                }
524
        }
524
525
        
525
                if (retry[0] > 0) {
526
        public void cancel() {
526
                    try {
527
            if ( panel.time != -1 ) {
527
                        Thread.sleep(retry[0]);
528
                LOGGER.log( Level.FINE, "Worker for text {0} canceled after {1} ms.",   //NOI18N
528
                    } catch (InterruptedException ex) {
529
                        new Object[]{
529
                        Exceptions.printStackTrace(ex);
530
                            text,
530
                    }
531
                            System.currentTimeMillis() - createTime
531
                } else {
532
                        });
532
                    return;
533
            }
533
                }
534
            TypeProvider _provider;
534
            } // for
535
            synchronized (this) {
535
        }
536
                isCanceled = true;
536
537
                _provider = current;
537
        public void cancel() {
538
            }
538
            if ( panel.time != -1 ) {
539
            if (_provider != null) {
539
                LOGGER.log( Level.FINE, "Worker for text {0} canceled after {1} ms.",   //NOI18N
540
                _provider.cancel();
540
                        new Object[]{
541
            }
541
                            text,
542
        }
542
                            System.currentTimeMillis() - createTime
543
543
                        });
544
        @SuppressWarnings("unchecked")
544
            }
545
        private List<? extends TypeDescriptor> getTypeNames(String text, int[] retry) {
545
            TypeProvider _provider;
546
            // TODO: Search twice, first for current project, then for all projects
546
            synchronized (this) {
547
            List<TypeDescriptor> items;
547
                isCanceled = true;
548
            // Multiple providers: merge results
548
                _provider = current;
549
            items = new ArrayList<TypeDescriptor>(128);
549
            }
550
            String[] message = new String[1];
550
            if (_provider != null) {
551
            TypeProvider.Context context = TypeProviderAccessor.DEFAULT.createContext(null, text, nameKind);
551
                _provider.cancel();
552
            TypeProvider.Result result = TypeProviderAccessor.DEFAULT.createResult(items, message);
552
            }
553
            assert rp.isRequestProcessorThread();
553
        }
554
            if (typeProviders == null) {
554
555
                typeProviders = implicitTypeProviders != null ? implicitTypeProviders : Lookup.getDefault().lookupAll(TypeProvider.class);
555
        @SuppressWarnings("unchecked")
556
            }
556
        private List<? extends TypeDescriptor> getTypeNames(String text, int[] retry) {
557
            for (TypeProvider provider : typeProviders) {
557
            // TODO: Search twice, first for current project, then for all projects
558
                if (isCanceled) {
558
            List<TypeDescriptor> items;
559
                    return null;
559
            // Multiple providers: merge results
560
                }
560
            items = new ArrayList<TypeDescriptor>(128);
561
                current = provider;
561
            String[] message = new String[1];
562
                long start = System.currentTimeMillis();
562
            TypeProvider.Context context = TypeProviderAccessor.DEFAULT.createContext(null, text, nameKind);
563
                try {
563
            TypeProvider.Result result = TypeProviderAccessor.DEFAULT.createResult(items, message);
564
                    LOGGER.log(Level.FINE, "Calling TypeProvider: {0}", provider);  //NOI18N
564
            assert rp.isRequestProcessorThread();
565
                    provider.computeTypeNames(context, result);
565
            if (typeProviders == null) {
566
                } finally {
566
                typeProviders = implicitTypeProviders != null ? implicitTypeProviders : Lookup.getDefault().lookupAll(TypeProvider.class);
567
                    current = null;
567
            }
568
                }
568
            for (TypeProvider provider : typeProviders) {
569
                long delta = System.currentTimeMillis() - start;
569
                if (isCanceled) {
570
                LOGGER.log(Level.FINE, "Provider ''{0}'' took {1} ms.",     //NOI18N
570
                    return null;
571
                        new Object[]{
571
                }
572
                            provider.getDisplayName(),
572
                current = provider;
573
                            delta
573
                long start = System.currentTimeMillis();
574
                        });
574
                try {
575
            }
575
                    LOGGER.log(Level.FINE, "Calling TypeProvider: {0}", provider);  //NOI18N
576
            retry[0] = TypeProviderAccessor.DEFAULT.getRetry(result);
576
                    provider.computeTypeNames(context, result);
577
            if ( !isCanceled ) {   
577
                } finally {
578
                //time = System.currentTimeMillis();
578
                    current = null;
579
                Collections.sort(items, new TypeComparator());
579
                }
580
                panel.setWarning(message[0]);
580
                long delta = System.currentTimeMillis() - start;
581
                //sort += System.currentTimeMillis() - time;
581
                LOGGER.log(Level.FINE, "Provider ''{0}'' took {1} ms.",     //NOI18N
582
                //LOGGER.fine("PERF - " + " GSS:  " + gss + " GSB " + gsb + " CP: " + cp + " SFB: " + sfb + " GTN: " + gtn + "  ADD: " + add + "  SORT: " + sort );
582
                        new Object[]{
583
                return items;
583
                            provider.getDisplayName(),
584
            }
584
                            delta
585
            else {
585
                        });
586
                return null;
586
            }
587
            }            
587
            retry[0] = TypeProviderAccessor.DEFAULT.getRetry(result);
588
        }
588
            if ( !isCanceled ) {   
589
    }
589
                //time = System.currentTimeMillis();
590
590
                Collections.sort(items, new TypeComparator());
591
    private static class MyPanel extends JPanel {
591
                panel.setWarning(message[0]);
592
	
592
                //sort += System.currentTimeMillis() - time;
593
	private TypeDescriptor td;
593
                //LOGGER.fine("PERF - " + " GSS:  " + gss + " GSB " + gsb + " CP: " + cp + " SFB: " + sfb + " GTN: " + gtn + "  ADD: " + add + "  SORT: " + sort );
594
	
594
                return items;
595
	void setDescriptor(TypeDescriptor td) {
595
            }
596
	    this.td = td;
596
            else {
597
	    // since the same component is reused for dirrerent list itens, 
597
                return null;
598
	    // null the tool tip
598
            }
599
	    putClientProperty(TOOL_TIP_TEXT_KEY, null);
599
        }
600
	}
600
    }
601
601
602
	@Override
602
    private static class MyPanel extends JPanel {
603
	public String getToolTipText() {
603
604
	    // the tool tip is gotten from the descriptor 
604
        private TypeDescriptor td;
605
	    // and cached in the standard TOOL_TIP_TEXT_KEY property
605
606
	    String text = (String) getClientProperty(TOOL_TIP_TEXT_KEY);
606
        void setDescriptor(TypeDescriptor td) {
607
	    if( text == null ) {
607
            this.td = td;
608
                if( td != null ) {
608
            // since the same component is reused for dirrerent list itens, 
609
                    FileObject fo = td.getFileObject();
609
            // null the tool tip
610
                    if (fo != null) {
610
            putClientProperty(TOOL_TIP_TEXT_KEY, null);
611
                        text = FileUtil.getFileDisplayName(fo);
611
        }
612
                    }
612
613
                }
613
        @Override
614
                putClientProperty(TOOL_TIP_TEXT_KEY, text);
614
        public String getToolTipText() {
615
	    }
615
            // the tool tip is gotten from the descriptor 
616
	    return text;
616
            // and cached in the standard TOOL_TIP_TEXT_KEY property
617
	}
617
            String text = (String) getClientProperty(TOOL_TIP_TEXT_KEY);
618
    }
618
	    if( text == null ) {
619
619
                if( td != null ) {
620
    final void waitSearchFinished() {
620
                    FileObject fo = td.getFileObject();
621
        assert SwingUtilities.isEventDispatchThread();
621
                    if (fo != null) {
622
        task.waitFinished();
622
                        text = FileUtil.getFileDisplayName(fo);
623
    }
623
                    }
624
624
                }
625
    private static final class Renderer extends EntitiesListCellRenderer {
625
                putClientProperty(TOOL_TIP_TEXT_KEY, text);
626
         
626
            }
627
        private MyPanel rendererComponent;
627
            return text;
628
        private JLabel jlName = new JLabel();
628
        }
629
        private JLabel jlPkg = new JLabel();
629
    }
630
        private JLabel jlPrj = new JLabel();
630
631
        private int DARKER_COLOR_COMPONENT = 5;
631
    final void waitSearchFinished() {
632
        private int LIGHTER_COLOR_COMPONENT = 80;        
632
        assert SwingUtilities.isEventDispatchThread();
633
        private Color fgColor;
633
        task.waitFinished();
634
        private Color fgColorLighter;
634
    }
635
        private Color bgColor;
635
636
        private Color bgColorDarker;
636
    private static final class Renderer extends EntitiesListCellRenderer implements DocumentListener {
637
        private Color bgSelectionColor;
637
638
        private Color fgSelectionColor;
638
        private MyPanel rendererComponent;
639
        
639
        private JLabel jlName = new JLabel();
640
        private JList jList;
640
        private JLabel jlPkg = new JLabel();
641
641
        private JLabel jlPrj = new JLabel();
642
        @SuppressWarnings("LeakingThisInConstructor")
642
        private int DARKER_COLOR_COMPONENT = 5;
643
        public Renderer( JList list ) {
643
        private int LIGHTER_COLOR_COMPONENT = 80;
644
            
644
        private Color fgColor;
645
            jList = list;
645
        private Color fgColorLighter;
646
            
646
        private Color bgColor;
647
            Container container = list.getParent();
647
        private Color bgColorDarker;
648
            if ( container instanceof JViewport ) {
648
        private Color bgSelectionColor;
649
                ((JViewport)container).addChangeListener(this);
649
        private Color fgSelectionColor;
650
                stateChanged(new ChangeEvent(container));
650
        
651
            }
651
        private JList jList;
652
            
652
        private String searchText = "";
653
            rendererComponent = new MyPanel();
653
        private final HighlightingTypeNameFormatter typeNameFormatter;
654
            rendererComponent.setLayout(new GridBagLayout());
654
655
            GridBagConstraints c = new GridBagConstraints();
655
        @SuppressWarnings("LeakingThisInConstructor")
656
            c.gridx = 0;
656
        public Renderer( JList list ) {
657
            c.gridy = 0;
657
            
658
            c.gridwidth = 1;
658
            jList = list;
659
            c.gridheight = 1;
659
660
            c.fill = GridBagConstraints.NONE;
660
            Container container = list.getParent();
661
            c.weightx = 0;            
661
            if ( container instanceof JViewport ) {
662
            c.anchor = GridBagConstraints.WEST;
662
                ((JViewport)container).addChangeListener(this);
663
            c.insets = new Insets (0,0,0,7);
663
                stateChanged(new ChangeEvent(container));
664
            rendererComponent.add( jlName, c);
664
            }
665
            
665
666
            c = new GridBagConstraints();
666
            rendererComponent = new MyPanel();
667
            c.gridx = 1;
667
            rendererComponent.setLayout(new GridBagLayout());
668
            c.gridy = 0;
668
            GridBagConstraints c = new GridBagConstraints();
669
            c.gridwidth = 1;
669
            c.gridx = 0;
670
            c.gridheight = 1;
670
            c.gridy = 0;
671
            c.fill = GridBagConstraints.HORIZONTAL;
671
            c.gridwidth = 1;
672
            c.weightx = 0.1;            
672
            c.gridheight = 1;
673
            c.anchor = GridBagConstraints.WEST;
673
            c.fill = GridBagConstraints.NONE;
674
            c.insets = new Insets (0,0,0,7);
674
            c.weightx = 0;
675
            rendererComponent.add( jlPkg, c);
675
            c.anchor = GridBagConstraints.WEST;
676
            
676
            c.insets = new Insets (0,0,0,7);
677
            c = new GridBagConstraints();
677
            rendererComponent.add( jlName, c);
678
            c.gridx = 2;
678
679
            c.gridy = 0;
679
            c = new GridBagConstraints();
680
            c.gridwidth = 1;
680
            c.gridx = 1;
681
            c.gridheight = 1;
681
            c.gridy = 0;
682
            c.fill = GridBagConstraints.NONE;
682
            c.gridwidth = 1;
683
            c.weightx = 0;            
683
            c.gridheight = 1;
684
            c.anchor = GridBagConstraints.EAST;
684
            c.fill = GridBagConstraints.HORIZONTAL;
685
            rendererComponent.add( jlPrj, c);
685
            c.weightx = 0.1;
686
            
686
            c.anchor = GridBagConstraints.WEST;
687
            
687
            c.insets = new Insets (0,0,0,7);
688
            jlName.setOpaque(false);
688
            rendererComponent.add( jlPkg, c);
689
            jlPkg.setOpaque(false);
689
690
            jlPrj.setOpaque(false);
690
            c = new GridBagConstraints();
691
            
691
            c.gridx = 2;
692
            jlName.setFont(list.getFont());
692
            c.gridy = 0;
693
            jlPkg.setFont(list.getFont());
693
            c.gridwidth = 1;
694
            jlPrj.setFont(list.getFont());
694
            c.gridheight = 1;
695
            
695
            c.fill = GridBagConstraints.NONE;
696
            
696
            c.weightx = 0;
697
            jlPrj.setHorizontalAlignment(RIGHT);
697
            c.anchor = GridBagConstraints.EAST;
698
            jlPrj.setHorizontalTextPosition(LEFT);
698
            rendererComponent.add( jlPrj, c);
699
            
699
700
            // setFont( list.getFont() );            
700
701
            fgColor = list.getForeground();
701
            jlName.setOpaque(false);
702
            fgColorLighter = new Color( 
702
            jlPkg.setOpaque(false);
703
                                   Math.min( 255, fgColor.getRed() + LIGHTER_COLOR_COMPONENT),
703
            jlPrj.setOpaque(false);
704
                                   Math.min( 255, fgColor.getGreen() + LIGHTER_COLOR_COMPONENT),
704
705
                                   Math.min( 255, fgColor.getBlue() + LIGHTER_COLOR_COMPONENT)
705
            jlName.setFont(list.getFont());
706
                                  );
706
            jlPkg.setFont(list.getFont());
707
                            
707
            jlPrj.setFont(list.getFont());
708
            bgColor = list.getBackground();
708
709
            bgColorDarker = new Color(
709
710
                                    Math.abs(bgColor.getRed() - DARKER_COLOR_COMPONENT),
710
            jlPrj.setHorizontalAlignment(RIGHT);
711
                                    Math.abs(bgColor.getGreen() - DARKER_COLOR_COMPONENT),
711
            jlPrj.setHorizontalTextPosition(LEFT);
712
                                    Math.abs(bgColor.getBlue() - DARKER_COLOR_COMPONENT)
712
713
                            );
713
            // setFont( list.getFont() );            
714
            bgSelectionColor = list.getSelectionBackground();
714
            fgColor = list.getForeground();
715
            fgSelectionColor = list.getSelectionForeground();        
715
            fgColorLighter = new Color(
716
        }
716
                                   Math.min( 255, fgColor.getRed() + LIGHTER_COLOR_COMPONENT),
717
        
717
                                   Math.min( 255, fgColor.getGreen() + LIGHTER_COLOR_COMPONENT),
718
        public @Override Component getListCellRendererComponent( JList list,
718
                                   Math.min( 255, fgColor.getBlue() + LIGHTER_COLOR_COMPONENT)
719
                                                       Object value,
719
                                  );
720
                                                       int index,
720
721
                                                       boolean isSelected,
721
            bgColor = list.getBackground();
722
                                                       boolean hasFocus) {
722
            bgColorDarker = new Color(
723
            
723
                    Math.abs(bgColor.getRed() - DARKER_COLOR_COMPONENT),
724
            // System.out.println("Renderer for index " + index );
724
                    Math.abs(bgColor.getGreen() - DARKER_COLOR_COMPONENT),
725
            
725
                                    Math.abs(bgColor.getBlue() - DARKER_COLOR_COMPONENT)
726
            int height = list.getFixedCellHeight();
726
                            );
727
            int width = list.getFixedCellWidth() - 1;
727
            bgSelectionColor = list.getSelectionBackground();
728
            
728
            fgSelectionColor = list.getSelectionForeground();
729
            width = width < 200 ? 200 : width;
729
            //TODO: get caseSensitive mode and init the highlighter
730
            
730
            boolean caseSensitive=false;
731
            // System.out.println("w, h " + width + ", " + height );
731
            this.typeNameFormatter = new HighlightingTypeNameFormatter(fgColor, bgColor, caseSensitive);
732
            
732
        }
733
            Dimension size = new Dimension( width, height );
733
734
            rendererComponent.setMaximumSize(size);
734
        public @Override Component getListCellRendererComponent( JList list,
735
            rendererComponent.setPreferredSize(size);
735
                Object value,
736
                        
736
                int index,
737
            if ( isSelected ) {
737
                boolean isSelected,
738
                jlName.setForeground(fgSelectionColor);
738
                boolean hasFocus) {
739
                jlPkg.setForeground(fgSelectionColor);
739
740
                jlPrj.setForeground(fgSelectionColor);
740
            // System.out.println("Renderer for index " + index );
741
                rendererComponent.setBackground(bgSelectionColor);
741
742
            }
742
            int height = list.getFixedCellHeight();
743
            else {
743
            int width = list.getFixedCellWidth() - 1;
744
                jlName.setForeground(fgColor);
744
745
                jlPkg.setForeground(fgColorLighter);
745
            width = width < 200 ? 200 : width;
746
                jlPrj.setForeground(fgColor);                
746
747
                rendererComponent.setBackground( index % 2 == 0 ? bgColor : bgColorDarker );
747
            // System.out.println("w, h " + width + ", " + height );
748
            }
748
749
            
749
            Dimension size = new Dimension( width, height );
750
            if ( value instanceof TypeDescriptor ) {
750
            rendererComponent.setMaximumSize(size);
751
                long time = System.currentTimeMillis();
751
            rendererComponent.setPreferredSize(size);
752
                TypeDescriptor td = (TypeDescriptor)value;                
752
753
                jlName.setIcon(td.getIcon());
753
            if ( isSelected ) {
754
                jlName.setText(td.getTypeName());
754
                jlName.setForeground(fgSelectionColor);
755
                jlPkg.setText(td.getContextName());
755
                jlPkg.setForeground(fgSelectionColor);
756
                setProjectName(jlPrj, td.getProjectName());
756
                jlPrj.setForeground(fgSelectionColor);
757
                jlPrj.setIcon(td.getProjectIcon());
757
                rendererComponent.setBackground(bgSelectionColor);
758
		rendererComponent.setDescriptor(td);
758
            }
759
                LOGGER.log(Level.FINE, "  Time in paint {0} ms.", System.currentTimeMillis() - time);   //NOI18N
759
            else {
760
            }
760
                jlName.setForeground(fgColor);
761
            else {
761
                jlPkg.setForeground(fgColorLighter);
762
                jlName.setText( value.toString() );
762
                jlPrj.setForeground(fgColor);
763
            }
763
                rendererComponent.setBackground( index % 2 == 0 ? bgColor : bgColorDarker );
764
            
764
            }
765
            return rendererComponent;
765
766
        }
766
            if ( value instanceof TypeDescriptor ) {
767
        
767
                long time = System.currentTimeMillis();
768
        @Override
768
                TypeDescriptor td = (TypeDescriptor)value;                
769
        public void stateChanged(ChangeEvent event) {
769
                jlName.setIcon(td.getIcon());
770
            
770
771
            JViewport jv = (JViewport)event.getSource();
771
                //highlight matching search text patterns in type
772
            
772
                String typeName = td.getTypeName();
773
            jlName.setText( "Sample" ); // NOI18N
773
                String formattedTypeName = typeNameFormatter.formatTypeName(typeName, searchText);
774
            //jlName.setIcon(UiUtils.getElementIcon(ElementKind.CLASS, null));
774
                jlName.setText(String.format("<html>%s</html>", formattedTypeName));
775
            jlName.setIcon(ImageUtilities.loadImageIcon("org/netbeans/modules/jumpto/type/sample.png", false)); //NOI18N
775
                jlPkg.setText(td.getContextName());
776
            
776
                setProjectName(jlPrj, td.getProjectName());
777
            jList.setFixedCellHeight(jlName.getPreferredSize().height);
777
                jlPrj.setIcon(td.getProjectIcon());
778
            jList.setFixedCellWidth(jv.getExtentSize().width);
778
                rendererComponent.setDescriptor(td);
779
        }
779
                LOGGER.log(Level.FINE, "  Time in paint {0} ms.", System.currentTimeMillis() - time);   //NOI18N
780
780
            }
781
     } // Renderer
781
            else {
782
    
782
                jlName.setText( value.toString() );
783
    private class DialogButtonListener implements ActionListener {
783
            }
784
        
784
785
        private GoToPanel panel;
785
            return rendererComponent;
786
        
786
        }
787
        public DialogButtonListener( GoToPanel panel ) {
787
788
            this.panel = panel;
788
        @Override
789
        }
789
        public void stateChanged(ChangeEvent event) {
790
        
790
791
        @Override
791
            JViewport jv = (JViewport)event.getSource();
792
        public void actionPerformed(ActionEvent e) {            
792
793
            if ( e.getSource() == okButton) {
793
            jlName.setText( "Sample" ); // NOI18N
794
                panel.setSelectedTypes();
794
            //jlName.setIcon(UiUtils.getElementIcon(ElementKind.CLASS, null));
795
            }
795
            jlName.setIcon(ImageUtilities.loadImageIcon("org/netbeans/modules/jumpto/type/sample.png", false)); //NOI18N
796
        }
796
797
        
797
            jList.setFixedCellHeight(jlName.getPreferredSize().height);
798
    }
798
            jList.setFixedCellWidth(jv.getExtentSize().width);
799
799
        }
800
800
801
    private Profile initializeProfiling() {
801
        @Override
802
        boolean assertsOn = false;
802
        public void insertUpdate(DocumentEvent e) {
803
        assert assertsOn = true;
803
            changedUpdate(e);
804
        if (!assertsOn) {
804
        }
805
            return null;
805
806
        }
806
        @Override
807
807
        public void removeUpdate(DocumentEvent e) {
808
        Sampler profiler = Sampler.createSampler("jumpto"); //NOI18N
808
            changedUpdate(e);
809
        if (profiler == null) {
809
        }
810
            return null;
810
811
        }
811
        @Override
812
        return new Profile(profiler).start();
812
        public void changedUpdate(DocumentEvent e) {
813
    }
813
814
814
            try {
815
    private class Profile implements Runnable {
815
                String text = e.getDocument().getText(0, e.getDocument().getLength());
816
        private final long time;
816
                searchText = text;
817
        private volatile  Sampler profiler;
817
            } catch (BadLocationException ex) {
818
        private volatile boolean profiling;
818
                searchText = "";
819
819
            }
820
        public Profile(Sampler profiler) {
820
        }
821
            time = System.currentTimeMillis();
821
    } // Renderer
822
            this.profiler = profiler;
822
823
        }
823
    private class DialogButtonListener implements ActionListener {
824
        
824
825
        Profile start() {
825
        private GoToPanel panel;
826
            PROFILE_RP.post(this, 3000); // 3s
826
827
            return this;
827
        public DialogButtonListener( GoToPanel panel ) {
828
        }
828
            this.panel = panel;
829
829
        }
830
        @Override
830
831
        public synchronized void run() {
831
        @Override
832
            if (profiler != null) {
832
        public void actionPerformed(ActionEvent e) {
833
                profiling = true;
833
            if ( e.getSource() == okButton) {
834
                profiler.start();
834
                panel.setSelectedTypes();
835
            }
835
            }
836
        }
836
        }
837
837
        
838
        private synchronized void stop() throws Exception {
838
    }
839
            long delta = System.currentTimeMillis() - time;
839
840
840
841
            Sampler ss = profiler;
841
    private Profile initializeProfiling() {
842
            profiler = null;
842
        boolean assertsOn = false;
843
            if (!profiling) {
843
        assert assertsOn = true;
844
                return;
844
        if (!assertsOn) {
845
            }
845
            return null;
846
            try {
846
        }
847
                ByteArrayOutputStream out = new ByteArrayOutputStream();
847
848
                DataOutputStream dos = new DataOutputStream(out);
848
        Sampler profiler = Sampler.createSampler("jumpto"); //NOI18N
849
                ss.stopAndWriteTo(dos);
849
        if (profiler == null) {
850
                dos.close();
850
            return null;
851
                if (dos.size() > 0) {
851
        }
852
                    Object[] params = new Object[]{out.toByteArray(), delta, "GoToType" };      //NOI18N
852
        return new Profile(profiler).start();
853
                    Logger.getLogger("org.netbeans.ui.performance").log(Level.CONFIG, "Slowness detected", params); //NOI18N
853
    }
854
                } else {
854
855
                    LOGGER.log(Level.WARNING, "no snapshot taken"); // NOI18N
855
    private class Profile implements Runnable {
856
                }
856
        private final long time;
857
            } catch (Exception ex) {
857
        private volatile  Sampler profiler;
858
                Exceptions.printStackTrace(ex);
858
        private volatile boolean profiling;
859
            }
859
860
        }
860
        public Profile(Sampler profiler) {
861
861
            time = System.currentTimeMillis();
862
    }
862
            this.profiler = profiler;
863
863
        }
864
}
864
865
        Profile start() {
866
            PROFILE_RP.post(this, 3000); // 3s
867
            return this;
868
        }
869
870
        @Override
871
        public synchronized void run() {
872
            if (profiler != null) {
873
                profiling = true;
874
                profiler.start();
875
            }
876
        }
877
878
        private synchronized void stop() throws Exception {
879
            long delta = System.currentTimeMillis() - time;
880
881
            Sampler ss = profiler;
882
            profiler = null;
883
            if (!profiling) {
884
                return;
885
            }
886
            try {
887
                ByteArrayOutputStream out = new ByteArrayOutputStream();
888
                DataOutputStream dos = new DataOutputStream(out);
889
                ss.stopAndWriteTo(dos);
890
                dos.close();
891
                if (dos.size() > 0) {
892
                    Object[] params = new Object[]{out.toByteArray(), delta, "GoToType" };      //NOI18N
893
                    Logger.getLogger("org.netbeans.ui.performance").log(Level.CONFIG, "Slowness detected", params); //NOI18N
894
                } else {
895
                    LOGGER.log(Level.WARNING, "no snapshot taken"); // NOI18N
896
                }
897
            } catch (Exception ex) {
898
                Exceptions.printStackTrace(ex);
899
            }
900
        }
901
902
    }
903
904
}
(-)a/jumpto/src/org/netbeans/modules/jumpto/type/HighlightingTypeNameFormatter.java (+136 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s): markiewb@netbeans.org
39
 *
40
 * Portions Copyrighted 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.jumpto.type;
43
44
import java.awt.Color;
45
import java.util.Arrays;
46
import java.util.BitSet;
47
import java.util.List;
48
49
/**
50
 * Highlight the match of text patterns. The matching parts will be placed 
51
 * within HTML-tags, so it can be used easily within the Swing UI.
52
 * @author markiewb
53
 */
54
class HighlightingTypeNameFormatter {
55
56
    private static final String FORMATPATTERN = "<span style=\"background-color:%s; font-weight:bold; color:%s\">%s</span>";
57
    private final boolean caseSensitive;
58
    private String formatPattern;
59
60
    HighlightingTypeNameFormatter(Color bgColor, Color fgColor, boolean caseSensitive) {
61
        String bgColorHighlight = Integer.toHexString(bgColor.getRGB()).substring(2);
62
        String fgColorHighlight = Integer.toHexString(fgColor.getRGB()).substring(2);
63
        formatPattern = String.format(FORMATPATTERN, bgColorHighlight, fgColorHighlight, "%s");
64
        this.caseSensitive = caseSensitive;
65
    }
66
67
    List<String> splitByCamelCaseAndWildcards(String searchText) {
68
        //AbcDeFGhiJo -> [Abc, De, F, Ghi, Jo]
69
        StringBuilder sb = new StringBuilder(searchText.length());
70
        for (char c : searchText.toCharArray()) {
71
            if (Character.isUpperCase(c)) {
72
                //add magic split marker into text before the uppercase char
73
                //example: AbcDeFGhiJo -> &Abc&De&F&Ghi&Jo
74
                sb.append("&");
75
                sb.append(c);
76
            } else {
77
                sb.append(c);
78
            }
79
        }
80
        //split by camelcase (using the split marker) or the wildcards *,?
81
        String[] split = sb.toString().split("[&|\\*|\\?]");
82
        return Arrays.asList(split);
83
    }
84
85
    public String formatTypeName(String typeName, String textToFind) {
86
87
        if (null == textToFind || "".equals(textToFind)) {
88
            return typeName;
89
        }
90
        BitSet bitSet = new BitSet(typeName.length());
91
        List<String> parts = splitByCamelCaseAndWildcards(textToFind);
92
93
        String convertedTypeName = caseSensitive ? typeName : typeName.toLowerCase();
94
        //mark the chars to be highlighted
95
        int startIndex = 0;
96
        for (String camelCasePart : parts) {
97
98
            int indexOf = convertedTypeName.indexOf(caseSensitive ? camelCasePart : camelCasePart.toLowerCase(), startIndex);
99
            if (indexOf != -1) {
100
101
                //mark the chars 
102
                bitSet.set(indexOf, indexOf + camelCasePart.length(), true);
103
            } else {
104
                break;
105
            }
106
            startIndex = indexOf + camelCasePart.length();
107
        }
108
109
        //highlight the marked chars via  tags
110
        StringBuilder formattedTypeName = new StringBuilder();
111
        int i = 0;
112
        while (i < typeName.toCharArray().length) {
113
114
            boolean isMarked = bitSet.get(i);
115
116
            if (isMarked) {
117
                int numberOfContinuousHighlights = bitSet.nextClearBit(i) - i;
118
                String part = typeName.substring(i, i + numberOfContinuousHighlights);
119
                formattedTypeName.append(String.format(formatPattern, part));
120
                i += numberOfContinuousHighlights;
121
            } else {
122
                formattedTypeName.append(typeName.charAt(i));
123
                i++;
124
            }
125
        }
126
        return formattedTypeName.toString();
127
    }
128
129
    /**
130
     * Allow to inject a pattern, so it can be tested easier.
131
     * @param pattern 
132
     */
133
    void setFormatPattern(String pattern) {
134
        this.formatPattern = pattern;
135
    }
136
}
(-)a/jumpto/test/unit/src/org/netbeans/modules/jumpto/type/HighlightingTypeNameFormatterTest.java (+115 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *   markiewb@netbeans.org
40
 *
41
 * Portions Copyrighted 2012 Sun Microsystems, Inc.
42
 */
43
package org.netbeans.modules.jumpto.type;
44
45
import java.awt.Color;
46
import java.util.List;
47
import org.junit.Test;
48
import static org.junit.Assert.*;
49
import org.junit.Before;
50
51
/**
52
 * Tests if the pattern will be highlighted the correct way.
53
 * @author markiewb
54
 */
55
public class HighlightingTypeNameFormatterTest {
56
57
    private Color fg = Color.WHITE;
58
    private Color bg = Color.BLACK;
59
    private HighlightingTypeNameFormatter cut;
60
61
    @Before
62
    public void before() {
63
        cut = new HighlightingTypeNameFormatter(fg, bg, true);
64
        cut.setFormatPattern("[%s]");
65
    }
66
67
    @Test
68
    public void testFormatTypeName_CamelCase() {
69
        String typeName = "AbstractDummyBarTest";
70
71
        assertEquals("[AbstractDummyBarTest]", cut.formatTypeName(typeName, "AbstractDummyBarTest"));
72
        assertEquals("[Abstra]ct[D]ummy[B]arTest", cut.formatTypeName(typeName, "AbstraDB"));
73
        assertEquals("[A]bstract[Dum]my[B]arTest", cut.formatTypeName(typeName, "ADumB"));
74
        assertEquals("[A]bstract[D]ummy[Ba]rTest", cut.formatTypeName(typeName, "ADBa"));
75
        assertEquals("[A]bstract[D]ummy[B]ar[Test]", cut.formatTypeName(typeName, "ADBTest"));
76
        assertEquals("[Ab]stract[Du]mmy[B]ar[Test]", cut.formatTypeName(typeName, "AbDuBTest"));
77
    }
78
79
    @Test
80
    public void testFormatTypeName_NullOrEmpty() {
81
        String typeName = "AbstractDummyBarTest";
82
        assertEquals("AbstractDummyBarTest", cut.formatTypeName(typeName, null));
83
        assertEquals("AbstractDummyBarTest", cut.formatTypeName(typeName, ""));
84
    }
85
86
    @Test
87
    public void testFormatTypeName_Wildcard_CaseSensitive() {
88
        cut = new HighlightingTypeNameFormatter(fg, bg, true);
89
        cut.setFormatPattern("[%s]");
90
        String typeName = "AbstractDummyBarTest";
91
92
        assertEquals("[A]bstractDummyBar[Test]", cut.formatTypeName(typeName, "A*Test"));
93
        assertEquals("[A]bstractDummy[B]ar[Test]", cut.formatTypeName(typeName, "A*B*Test"));
94
        assertEquals("[A]bstractDummy[BarTest]", cut.formatTypeName(typeName, "A*Bar*Test"));
95
    }
96
97
    @Test
98
    public void testFormatTypeName_Wildcard_CaseInSensitive() {
99
        cut = new HighlightingTypeNameFormatter(fg, bg, false);
100
        cut.setFormatPattern("[%s]");
101
        String typeName = "AbstractDummyBarTest";
102
103
        assertEquals("[A]bstractDummyBar[Test]", cut.formatTypeName(typeName, "A*Test"));
104
        assertEquals("[Ab]stractDummyBar[Test]", cut.formatTypeName(typeName, "A*B*Test"));
105
        assertEquals("[A]bstractDummy[BarTest]", cut.formatTypeName(typeName, "A*Bar*Test"));
106
    }
107
108
    @Test
109
    public void testFormatTypeName_FullFormat() {
110
        cut = new HighlightingTypeNameFormatter(fg, bg, false);
111
        String typeName = "AbstractDummyBarTest";
112
113
        assertEquals("<span style=\"background-color:ffffff; font-weight:bold; color:000000\">A</span>bstract<span style=\"background-color:ffffff; font-weight:bold; color:000000\">D</span>ummy<span style=\"background-color:ffffff; font-weight:bold; color:000000\">B</span>ar<span style=\"background-color:ffffff; font-weight:bold; color:000000\">Test</span>", cut.formatTypeName(typeName, "ADBTest"));
114
    }
115
}

Return to bug 216833