diff -r 7a902c74231a editor.completion/src/org/netbeans/api/editor/completion/Completion.java
--- a/editor.completion/src/org/netbeans/api/editor/completion/Completion.java Tue Dec 11 13:22:22 2012 +0100
+++ b/editor.completion/src/org/netbeans/api/editor/completion/Completion.java Tue Dec 11 17:01:43 2012 +0100
@@ -158,5 +158,17 @@
public void hideAll() {
CompletionImpl.get().hideAll();
}
+
+ /**
+ * Workaround for http://netbeans.org/bugzilla/show_bug.cgi?id=223290 .
+ *
+ * Client needs to explicitly repaint its CompletionItem-s when their full
+ * state is computation is finished in a background thread.
+ *
+ * Called by reflection.
+ */
+ private void repaintCompletionView() {
+ CompletionImpl.get().repaintCompletionView();
+ }
}
diff -r 7a902c74231a editor.completion/src/org/netbeans/modules/editor/completion/CompletionImpl.java
--- a/editor.completion/src/org/netbeans/modules/editor/completion/CompletionImpl.java Tue Dec 11 13:22:22 2012 +0100
+++ b/editor.completion/src/org/netbeans/modules/editor/completion/CompletionImpl.java Tue Dec 11 17:01:43 2012 +0100
@@ -1545,6 +1545,16 @@
}
// ..........................................................................
+
+ /**
+ * Workaround for http://netbeans.org/bugzilla/show_bug.cgi?id=223290 .
+ *
+ * Client needs to explicitly repaint its CompletionItem-s when their full
+ * state is computation is finished in a background thread.
+ */
+ public void repaintCompletionView() {
+ layout.repaintCompletionView();
+ }
private final class CompletionShowAction extends AbstractAction {
private int queryType;
diff -r 7a902c74231a editor.completion/src/org/netbeans/modules/editor/completion/CompletionLayout.java
--- a/editor.completion/src/org/netbeans/modules/editor/completion/CompletionLayout.java Tue Dec 11 13:22:22 2012 +0100
+++ b/editor.completion/src/org/netbeans/modules/editor/completion/CompletionLayout.java Tue Dec 11 17:01:43 2012 +0100
@@ -47,6 +47,7 @@
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
+import java.awt.EventQueue;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
@@ -300,6 +301,14 @@
return completionPopup;
}
+ void repaintCompletionView() {
+ assert EventQueue.isDispatchThread();
+ JComponent completionView = completionPopup.completionScrollPane;
+ if(completionView != null && completionView.isVisible()) {
+ completionView.repaint();
+ }
+ }
+
private static final class CompletionPopup extends CompletionLayoutPopup {
private CompletionScrollPane completionScrollPane;
diff -r 7a902c74231a html.editor/src/org/netbeans/modules/html/editor/api/completion/HtmlCompletionItem.java
--- a/html.editor/src/org/netbeans/modules/html/editor/api/completion/HtmlCompletionItem.java Tue Dec 11 13:22:22 2012 +0100
+++ b/html.editor/src/org/netbeans/modules/html/editor/api/completion/HtmlCompletionItem.java Tue Dec 11 17:01:43 2012 +0100
@@ -58,7 +58,12 @@
import org.netbeans.modules.editor.indent.api.Indent;
import org.netbeans.spi.editor.completion.*;
import java.awt.Color;
+import java.awt.EventQueue;
import java.awt.event.KeyEvent;
+import java.beans.FeatureDescriptor;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.lang.reflect.Method;
import javax.swing.text.BadLocationException;
import javax.swing.text.JTextComponent;
import org.netbeans.modules.html.editor.lib.api.model.HtmlTagAttribute;
@@ -66,13 +71,15 @@
import org.netbeans.modules.html.editor.javadoc.HelpManager;
import org.netbeans.spi.editor.completion.support.AsyncCompletionTask;
import org.netbeans.spi.editor.completion.support.CompletionUtilities;
+import org.openide.explorer.propertysheet.PropertySheet;
+import org.openide.util.Exceptions;
import org.openide.util.ImageUtilities;
import org.openide.xml.XMLUtil;
/**
* Code completion result item base class
*
- * @author Dusan Balek, Marek Fukala
+ * @author Dusan Balek, Marek Fukala
*/
public class HtmlCompletionItem implements CompletionItem {
@@ -82,11 +89,11 @@
public static HtmlCompletionItem createTag(HtmlTag tag, String name, int substitutionOffset, String helpId, boolean possible) {
return new Tag(tag, name, substitutionOffset, helpId, possible);
}
-
+
public static HtmlCompletionItem createEndTag(HtmlTag tag, String name, int substitutionOffset, String helpId, int order, EndTag.Type type) {
return new EndTag(tag, name, substitutionOffset, helpId, order, type);
}
-
+
public static HtmlCompletionItem createEndTag(String name, int substitutionOffset, String helpId, int order, EndTag.Type type) {
return new EndTag(name, substitutionOffset, helpId, order, type);
}
@@ -122,8 +129,6 @@
public static HtmlCompletionItem createGoUpFileCompletionItem(int substitutionOffset, Color color, ImageIcon icon) {
return new GoUpFileAttributeValue(substitutionOffset, color, icon);
}
-
-
//------------------------------------------
protected int substitutionOffset;
protected String text, helpId;
@@ -178,7 +183,7 @@
}
int caretOffset = component.getSelectionEnd();
int len = caretOffset - substitutionOffset;
- if(len >= 0) {
+ if (len >= 0) {
substituteText(component, len);
}
}
@@ -189,9 +194,9 @@
return 0; //default
}
- /**
- * Subclasses may override to customize the completed text
- * if they do not want to override the substituteText method.
+ /**
+ * Subclasses may override to customize the completed text if they do not
+ * want to override the substituteText method.
*/
protected String getSubstituteText() {
return getItemText();
@@ -211,7 +216,6 @@
result[0] = true;
doc.runAtomic(new Runnable() {
-
@Override
public void run() {
try {
@@ -223,7 +227,7 @@
doc.insertString(substitutionOffset, substituteText, null);
} else {
c.setCaretPosition(c.getCaret().getDot() + substituteText.length() - len);
- }
+ }
} catch (BadLocationException ex) {
result[0] = false;
}
@@ -251,7 +255,6 @@
indent.lock();
try {
doc.runAtomic(new Runnable() {
-
@Override
public void run() {
try {
@@ -260,7 +263,7 @@
indent.reindent(startOffset, endOffset);
} catch (BadLocationException ex) {
//ignore
- }
+ }
}
});
} finally {
@@ -313,7 +316,8 @@
return this.helpId;
}
- /** Returns a url or null, if the help is not URL or the help is not defined.
+ /**
+ * Returns a url or null, if the help is not URL or the help is not defined.
*/
public URL getHelpURL() {
if (helpId == null || helpId.equals("")) {
@@ -326,8 +330,10 @@
return null;
}
- /** Returns help for the item. It can be only url. If the item doesn't have a help
- * than returns null. The class can overwrite this method and compounds the help realtime.
+ /**
+ * Returns help for the item. It can be only url. If the item doesn't have a
+ * help than returns null. The class can overwrite this method and compounds
+ * the help realtime.
*/
public String getHelp() {
return HelpManager.getDefault().getHelp(helpId);
@@ -384,24 +390,20 @@
hash = 97 * hash + (this.helpId != null ? this.helpId.hashCode() : 0);
return hash;
}
-
-
//------------------------------------------------------------------------------
- /**
- * Completion item representing a JSP tag including its prefix eg.
+ /**
+ * Completion item representing a JSP tag including its prefix eg.
+ *
*/
public static class Tag extends HtmlCompletionItem {
private static final ImageIcon HTML_TAG_ICON =
- ImageUtilities.loadImageIcon("org/netbeans/modules/csl/source/resources/icons/html_element.png", false); // NOI18N
-
+ ImageUtilities.loadImageIcon("org/netbeans/modules/csl/source/resources/icons/html_element.png", false); // NOI18N
private static final ImageIcon SVG_TAG_ICON =
- ImageUtilities.loadImageIcon("org/netbeans/modules/csl/source/resources/icons/class.png", false); // NOI18N
-
+ ImageUtilities.loadImageIcon("org/netbeans/modules/csl/source/resources/icons/class.png", false); // NOI18N
private static final ImageIcon MATHML_TAG_ICON =
- ImageUtilities.loadImageIcon("org/netbeans/modules/html/editor/resources/mathml.png", false); // NOI18N
-
+ ImageUtilities.loadImageIcon("org/netbeans/modules/html/editor/resources/mathml.png", false); // NOI18N
private String GRAY_COLOR_CODE = hexColorCode(Color.GRAY);
private boolean possible;
private HtmlTag tag;
@@ -435,9 +437,9 @@
@Override
protected String getLeftHtmlText() {
- return possible ?
- "<" + getItemText() + ">" : //NOI18N
- "<" + getItemText() + ">"; //NOI18N
+ return possible
+ ? "<" + getItemText() + ">" : //NOI18N
+ "<" + getItemText() + ">"; //NOI18N
}
@Override
@@ -465,24 +467,23 @@
@Override
public boolean hasHelp() {
- return tag != null && tag.getHelp() != null || super.hasHelp();
+ return tag != null && tag.getHelp() != null || super.hasHelp();
}
-
-
}
/**
- * Completion item representing a JSP tag including its prefix eg.
+ * Completion item representing a JSP tag including its prefix eg.
+ *
*/
public static class EndTag extends HtmlCompletionItem {
-
+
public enum Type {
+
DEFAULT(hexColorCode(Color.BLUE), false, DEFAULT_SORT_PRIORITY), //NOI18N
OPTIONAL_EXISTING(hexColorCode(Color.GRAY), false, DEFAULT_SORT_PRIORITY),
OPTIONAL_MISSING(hexColorCode(Color.BLUE), false, DEFAULT_SORT_PRIORITY - 10), //NOI18N
REQUIRED_EXISTING(hexColorCode(Color.GRAY), false, DEFAULT_SORT_PRIORITY),
REQUIRED_MISSING(hexColorCode(Color.BLUE), false, DEFAULT_SORT_PRIORITY - 10); //NOI18N
-
private String colorCode;
private boolean bold;
private int sortPriority;
@@ -492,9 +493,7 @@
this.bold = bold;
this.sortPriority = sortPriority;
}
-
}
-
private int orderIndex;
private Type type;
private HtmlTag tag;
@@ -519,7 +518,7 @@
} else {
char[] result = new char[Integer.toString(Integer.MAX_VALUE).length()];
char[] orderIndexChars = Integer.toString(orderIndex).toCharArray();
- Arrays.fill(result,'0'); //NOI18N
+ Arrays.fill(result, '0'); //NOI18N
System.arraycopy(orderIndexChars, 0, result, result.length - orderIndexChars.length, orderIndexChars.length);
return new String(result);
@@ -547,7 +546,6 @@
public boolean hasHelp() {
return tag != null && tag.getHelp() != null || super.hasHelp();
}
-
}
public static class AutocompleteEndTag extends EndTag {
@@ -565,7 +563,6 @@
public boolean instantSubstitution(JTextComponent component) {
return false;
}
-
}
/**
@@ -604,7 +601,9 @@
}
}
- /** Item representing a JSP attribute value. */
+ /**
+ * Item representing a JSP attribute value.
+ */
public static class AttributeValue extends HtmlCompletionItem {
private boolean addQuotation;
@@ -618,8 +617,6 @@
protected String getSubstituteText() {
return addQuotation ? "\"" + super.getSubstituteText() + "\"" : super.getSubstituteText();
}
-
-
}
public static class Attribute extends HtmlCompletionItem {
@@ -627,7 +624,6 @@
private boolean required;
private boolean autocompleteQuotes;
private HtmlTagAttribute attr;
-
protected static final String ATTR_NAME_COLOR = hexColorCode(Color.green.darker());
public Attribute(HtmlTagAttribute attr, String value, int offset, boolean required, String helpId) {
@@ -664,18 +660,16 @@
"" + getItemText() + "" + //NOI18N
(required ? "" : ""); //NOI18N
}
-
+
@Override
public boolean hasHelp() {
return attr != null && attr.getHelp() != null || super.hasHelp();
}
-
}
public static class BooleanAttribute extends HtmlCompletionItem {
private boolean required;
-
protected static final String ATTR_NAME_COLOR = hexColorCode(Color.green.darker());
public BooleanAttribute(String value, int offset, boolean required, String helpId) {
@@ -691,11 +685,14 @@
}
}
- /** Item representing a File attribute */
- public static class FileAttributeValue extends HtmlCompletionItem {
+ /**
+ * Item representing a File attribute
+ */
+ public static class FileAttributeValue extends HtmlCompletionItem implements PropertyChangeListener, LazyCompletionItem {
private javax.swing.ImageIcon icon;
private Color color;
+ private boolean visible = false;
FileAttributeValue(String text, int substitutionOffset, Color color, javax.swing.ImageIcon icon) {
super(text, substitutionOffset);
@@ -712,6 +709,47 @@
protected String getLeftHtmlText() {
return "" + getItemText() + ""; //NOI18N
}
+
+ private void iconLoaded(ImageIcon icon) {
+ this.icon = icon;
+ if(visible) {
+ repaintCompletionView_EDT();
+ }
+ }
+
+ private void repaintCompletionView_EDT() {
+ EventQueue.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ repaintCompletionView();
+ }
+ });
+ }
+
+ private static void repaintCompletionView() {
+ try {
+ Completion completion = Completion.get();
+ Class extends Completion> clz = completion.getClass();
+ Method method = clz.getDeclaredMethod("repaintCompletionView"); //NOI18N
+ method.setAccessible(true);
+ method.invoke(completion);
+ } catch (Exception e) {
+ //ignore
+ }
+ }
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ if(evt.getPropertyName().equals("iconLoaded")) { //NOI18N
+ iconLoaded((ImageIcon)evt.getNewValue());
+ }
+ }
+
+ @Override
+ public boolean accept() {
+ visible = true;
+ return true;
+ }
}
public static class GoUpFileAttributeValue extends FileAttributeValue {
diff -r 7a902c74231a web.common/src/org/netbeans/modules/web/common/api/FileReferenceCompletion.java
--- a/web.common/src/org/netbeans/modules/web/common/api/FileReferenceCompletion.java Tue Dec 11 13:22:22 2012 +0100
+++ b/web.common/src/org/netbeans/modules/web/common/api/FileReferenceCompletion.java Tue Dec 11 17:01:43 2012 +0100
@@ -42,6 +42,8 @@
package org.netbeans.modules.web.common.api;
import java.awt.Color;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
@@ -57,7 +59,9 @@
import org.openide.filesystems.FileSystem;
import org.openide.loaders.DataObject;
import org.openide.loaders.DataObjectNotFoundException;
+import org.openide.util.Exceptions;
import org.openide.util.ImageUtilities;
+import org.openide.util.RequestProcessor;
/**
*
@@ -65,6 +69,8 @@
*/
public abstract class FileReferenceCompletion implements ValueCompletion {
+ private static RequestProcessor RP = new RequestProcessor();
+
private static final ImageIcon PACKAGE_ICON =
ImageUtilities.loadImageIcon("org/openide/loaders/defaultFolder.gif", false); // NOI18N
@@ -139,19 +145,32 @@
Enumeration extends FileObject> files = folder.getChildren(false);
while (files.hasMoreElements()) {
- FileObject file = files.nextElement();
+ final FileObject file = files.nextElement();
String fname = file.getNameExt();
if (fname.startsWith(prefix) && !"cvs".equalsIgnoreCase(fname)) {
if (file.isFolder()) {
resFolders.put(file.getNameExt(), createFileItem(offset, file.getNameExt() + "/", java.awt.Color.BLUE, PACKAGE_ICON));
} else {
- java.awt.Image icon = getIcon(file);
- if (icon != null) {
- resFiles.put(file.getNameExt(), createFileItem(offset, file.getNameExt(), java.awt.Color.BLACK, new javax.swing.ImageIcon(icon)));
+ T fileItem = createFileItem(offset, file.getNameExt(), java.awt.Color.BLACK, null);
+ if(fileItem instanceof PropertyChangeListener) { //"bit" hacky :-)
+ //lazy load icons
+ final PropertyChangeListener plistener = (PropertyChangeListener)fileItem;
+ RP.post(new Runnable() {
+ @Override
+ public void run() {
+ ImageIcon icon = new ImageIcon(getIcon(file));
+ plistener.propertyChange(
+ new PropertyChangeEvent(this, "iconLoaded", null, icon)); //NOI18N
+ }
+
+ });
} else {
- resFiles.put(file.getNameExt(), createFileItem(offset, file.getNameExt(), java.awt.Color.BLACK, null));
+ //direct icons load
+ ImageIcon icon = new ImageIcon(getIcon(file));
+ fileItem = createFileItem(offset, file.getNameExt(), java.awt.Color.BLACK, icon);
}
+ resFiles.put(file.getNameExt(), fileItem);
}
}
}