diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFieldFromUsageFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFieldFromUsageFix.java
index 18c2e0b1c6b4..139a605ae60d 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFieldFromUsageFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFieldFromUsageFix.java
@@ -66,8 +66,6 @@ public class CreateFieldFromUsageFix extends CreateVarFromUsageFix {
}
while (parentClass instanceof PsiAnonymousClass);
- final PsiFile targetFile = targetClass.getContainingFile();
-
ExpectedTypeInfo[] expectedTypes = CreateFromUsageUtils.guessExpectedTypes(myReferenceExpression, false);
String fieldName = myReferenceExpression.getReferenceName();
@@ -94,10 +92,20 @@ public class CreateFieldFromUsageFix extends CreateVarFromUsageFix {
setupVisibility(parentClass, targetClass, field.getModifierList());
+ createFieldFromUsageTemplate(targetClass, project, expectedTypes, field, createConstantField(), myReferenceExpression);
+ }
+
+ public static void createFieldFromUsageTemplate(final PsiClass targetClass,
+ final Project project,
+ final ExpectedTypeInfo[] expectedTypes,
+ final PsiField field,
+ final boolean createConstantField,
+ final PsiElement context) {
+ final PsiFile targetFile = targetClass.getContainingFile();
final Editor newEditor = positionCursor(project, targetFile, field);
if (newEditor == null) return;
Template template =
- CreateFieldFromUsageHelper.setupTemplate(field, expectedTypes, targetClass, newEditor, myReferenceExpression, createConstantField());
+ CreateFieldFromUsageHelper.setupTemplate(field, expectedTypes, targetClass, newEditor, context, createConstantField);
startTemplate(newEditor, template, project, new TemplateEditingAdapter() {
@Override
diff --git a/plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFXQuickfixTest.java b/plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFXQuickfixTest.java
index e7b7135d929b..7ac6b6972242 100644
--- a/plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFXQuickfixTest.java
+++ b/plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFXQuickfixTest.java
@@ -40,6 +40,10 @@ public class JavaFXQuickfixTest extends DaemonAnalyzerTestCase {
doTest("Create Method 'void bar(ActionEvent)'", true);
}
+ public void testCreateField() throws Exception {
+ doTest("Create Field 'btn'", true);
+ }
+
private void doTest(final String actionName) throws Exception {
doTest(actionName, false);
}
diff --git a/plugins/javaFX/src/META-INF/common-javaFX-plugin.xml b/plugins/javaFX/src/META-INF/common-javaFX-plugin.xml
index 76cd8a641f07..fc913b0d5deb 100644
--- a/plugins/javaFX/src/META-INF/common-javaFX-plugin.xml
+++ b/plugins/javaFX/src/META-INF/common-javaFX-plugin.xml
@@ -9,6 +9,7 @@
+
diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxFieldIdReferenceProvider.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxFieldIdReferenceProvider.java
index c649a37f8639..b4f8e47152af 100644
--- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxFieldIdReferenceProvider.java
+++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxFieldIdReferenceProvider.java
@@ -15,28 +15,48 @@
*/
package org.jetbrains.plugins.javaFX.fxml.refs;
+import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.ExpectedTypeInfo;
+import com.intellij.codeInsight.ExpectedTypeInfoImpl;
+import com.intellij.codeInsight.TailType;
+import com.intellij.codeInsight.daemon.QuickFixActionRegistrar;
+import com.intellij.codeInsight.daemon.QuickFixBundle;
+import com.intellij.codeInsight.daemon.impl.quickfix.CreateFieldFromUsageFix;
+import com.intellij.codeInsight.daemon.impl.quickfix.CreateFieldFromUsageHelper;
+import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction;
+import com.intellij.codeInsight.quickfix.UnresolvedReferenceQuickFixProvider;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
+import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlAttributeValue;
+import com.intellij.psi.xml.XmlFile;
+import com.intellij.psi.xml.XmlTag;
import com.intellij.util.ArrayUtil;
+import com.intellij.util.IncorrectOperationException;
import com.intellij.util.ProcessingContext;
+import com.intellij.util.VisibilityUtil;
+import com.intellij.xml.XmlElementDescriptor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.javaFX.fxml.FxmlConstants;
import org.jetbrains.plugins.javaFX.fxml.JavaFxPsiUtil;
+import org.jetbrains.plugins.javaFX.fxml.descriptors.JavaFxClassBackedElementDescriptor;
import java.util.ArrayList;
import java.util.List;
/**
-* User: anna
-* Date: 1/17/13
-*/
+ * User: anna
+ * Date: 1/17/13
+ */
class JavaFxFieldIdReferenceProvider extends JavaFxControllerBasedReferenceProvider {
@Override
protected PsiReference[] getReferencesByElement(@NotNull final PsiClass aClass,
final XmlAttributeValue xmlAttributeValue,
ProcessingContext context) {
final PsiField field = aClass.findFieldByName(xmlAttributeValue.getValue(), false);
- return new PsiReference[] {new JavaFxControllerFieldRef(xmlAttributeValue, field, aClass)};
+ return new PsiReference[]{new JavaFxControllerFieldRef(xmlAttributeValue, field, aClass)};
}
public static class JavaFxControllerFieldRef extends PsiReferenceBase {
@@ -54,7 +74,19 @@ class JavaFxFieldIdReferenceProvider extends JavaFxControllerBasedReferenceProvi
@Nullable
@Override
public PsiElement resolve() {
- return myField != null ? myField : myXmlAttributeValue;
+ if (myField != null) {
+ return myField;
+ }
+ else {
+ if (myAClass != null) {
+ final XmlFile xmlFile = (XmlFile)myXmlAttributeValue.getContainingFile();
+ final XmlTag rootTag = xmlFile.getRootTag();
+ if (rootTag != null && !FxmlConstants.FX_ROOT.equals(rootTag.getName())) {
+ return null;
+ }
+ }
+ return myXmlAttributeValue;
+ }
}
@NotNull
@@ -72,4 +104,81 @@ class JavaFxFieldIdReferenceProvider extends JavaFxControllerBasedReferenceProvi
return ArrayUtil.toObjectArray(fieldsToSuggest);
}
}
+
+ public static class JavaFxUnresolvedReferenceHandlerQuickfixProvider extends UnresolvedReferenceQuickFixProvider {
+ @Override
+ public void registerFixes(final JavaFxControllerFieldRef ref, final QuickFixActionRegistrar registrar) {
+ if (ref.myAClass != null && ref.myField == null) {
+ final PsiClass fieldClass = CreateFieldFix.checkContext(ref.myXmlAttributeValue);
+ if (fieldClass != null) {
+ registrar.register(new CreateFieldFix(ref, fieldClass));
+ }
+ }
+ }
+
+ @NotNull
+ @Override
+ public Class getReferenceClass() {
+ return JavaFxControllerFieldRef.class;
+ }
+
+ private static class CreateFieldFix extends PsiElementBaseIntentionAction {
+ private final PsiClass myFieldClass;
+ private final PsiClass myClass;
+ private final String myCanonicalText;
+
+ public CreateFieldFix(JavaFxControllerFieldRef ref, PsiClass fieldClass) {
+ myFieldClass = fieldClass;
+ myClass = ref.myAClass;
+ myCanonicalText = ref.getCanonicalText();
+ }
+
+ @Override
+ public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException {
+
+ if (!CodeInsightUtilBase.prepareFileForWrite(myClass.getContainingFile())) {
+ return;
+ }
+ final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
+ PsiField field = factory.createField(myCanonicalText, PsiType.INT);
+ VisibilityUtil.setVisibility(field.getModifierList(), PsiModifier.PUBLIC);
+
+ field = CreateFieldFromUsageHelper.insertField(myClass, field, element);
+
+ final PsiClassType fieldType = factory.createType(myFieldClass);
+ final ExpectedTypeInfo[] types = {new ExpectedTypeInfoImpl(fieldType, ExpectedTypeInfo.TYPE_OR_SUBTYPE, 0, fieldType, TailType.NONE)};
+ CreateFieldFromUsageFix.createFieldFromUsageTemplate(myClass, project, types, field, false, element);
+ }
+
+ protected static PsiClass checkContext(final XmlAttributeValue attributeValue) {
+ if (attributeValue == null) return null;
+ final PsiElement parent = attributeValue.getParent();
+ if (parent instanceof XmlAttribute){
+ final XmlTag tag = ((XmlAttribute)parent).getParent();
+ if (tag != null) {
+ final XmlElementDescriptor descriptor = tag.getDescriptor();
+ if (descriptor instanceof JavaFxClassBackedElementDescriptor) {
+ final PsiElement declaration = descriptor.getDeclaration();
+ if (declaration instanceof PsiClass) {
+ return (PsiClass)declaration;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) {
+ setText(QuickFixBundle.message("create.field.from.usage.text", myCanonicalText));
+ return element.isValid();
+ }
+
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return QuickFixBundle.message("create.field.from.usage.family");
+ }
+ }
+ }
}
diff --git a/plugins/javaFX/testData/quickfix/CreateField.java b/plugins/javaFX/testData/quickfix/CreateField.java
new file mode 100644
index 000000000000..e72dc651892b
--- /dev/null
+++ b/plugins/javaFX/testData/quickfix/CreateField.java
@@ -0,0 +1 @@
+public class CreateControllerMethod {}
\ No newline at end of file
diff --git a/plugins/javaFX/testData/quickfix/CreateField_after.java b/plugins/javaFX/testData/quickfix/CreateField_after.java
new file mode 100644
index 000000000000..a247a27be877
--- /dev/null
+++ b/plugins/javaFX/testData/quickfix/CreateField_after.java
@@ -0,0 +1,5 @@
+import javafx.scene.control.Button;
+
+public class CreateControllerMethod {
+ public Button btn;
+}
\ No newline at end of file
diff --git a/plugins/javaFX/testData/quickfix/createField.fxml b/plugins/javaFX/testData/quickfix/createField.fxml
new file mode 100644
index 000000000000..a4f21c4d63a5
--- /dev/null
+++ b/plugins/javaFX/testData/quickfix/createField.fxml
@@ -0,0 +1,5 @@
+
+
+
+
+