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 |
} |