mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Javafx: "Wrap field with JavaFx property" intention (IDEA-102430)
This commit is contained in:
@@ -15,5 +15,7 @@
|
||||
<orderEntry type="module" module-name="jetgroovy" scope="TEST" />
|
||||
<orderEntry type="module" module-name="common-javaFX-plugin" scope="TEST" />
|
||||
<orderEntry type="module" module-name="java-tests" scope="TEST" />
|
||||
<orderEntry type="module" module-name="structuralsearch-groovy" scope="TEST" />
|
||||
<orderEntry type="module" module-name="compiler-openapi" scope="TEST" />
|
||||
</component>
|
||||
</module>
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
package org.jetbrains.plugins.javaFX;
|
||||
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.roots.ContentEntry;
|
||||
import com.intellij.openapi.roots.ModifiableRootModel;
|
||||
import com.intellij.testFramework.fixtures.DefaultLightProjectDescriptor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.javaFX.fxml.AbstractJavaFXTestCase;
|
||||
|
||||
/**
|
||||
* Same as the base test, but detects the presence of JavaFX using imports and FXMLs, not artifacts
|
||||
* @author Pavel.Dolgov
|
||||
*/
|
||||
public class JavaFxFieldToPropertyNoArtifactTest extends JavaFxFieldToPropertyTest {
|
||||
public static final DefaultLightProjectDescriptor JAVA_FX_DESCRIPTOR_NO_ARTIFACT = new DefaultLightProjectDescriptor() {
|
||||
@Override
|
||||
public void configureModule(@NotNull Module module, @NotNull ModifiableRootModel model, @NotNull ContentEntry contentEntry) {
|
||||
AbstractJavaFXTestCase.addJavaFxJarAsLibrary(module, model);
|
||||
super.configureModule(module, model, contentEntry);
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void setUpModule() {
|
||||
super.setUpModule();
|
||||
}
|
||||
|
||||
public void testLongFieldToProperty() throws Exception {
|
||||
final IntentionAction intentionAction = getIntentionAction(false);
|
||||
// no artifact, no fxml, no javafx.* imports: the intention shoudn't be available
|
||||
assertNull(intentionAction);
|
||||
}
|
||||
}
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
package org.jetbrains.plugins.javaFX;
|
||||
|
||||
import com.intellij.codeInsight.daemon.DaemonAnalyzerTestCase;
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.codeInsight.intention.impl.ShowIntentionActionsHandler;
|
||||
import com.intellij.openapi.application.PluginPathManager;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.packaging.artifacts.ArtifactManager;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.javaFX.fxml.AbstractJavaFXTestCase;
|
||||
import org.jetbrains.plugins.javaFX.packaging.JavaFxApplicationArtifactType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Pavel.Dolgov
|
||||
* Run this test with 'main_idea_tests' classpath
|
||||
*/
|
||||
public class JavaFxFieldToPropertyTest extends DaemonAnalyzerTestCase {
|
||||
private static final String actionName = "Convert to JavaFX property";
|
||||
|
||||
@Override
|
||||
protected void setUpModule() {
|
||||
super.setUpModule();
|
||||
AbstractJavaFXTestCase.addJavaFxJarAsLibrary(getModule());
|
||||
ArtifactManager.getInstance(getProject()).addArtifact("fake-javafx", JavaFxApplicationArtifactType.getInstance(), null);
|
||||
}
|
||||
|
||||
public void testIntFieldToProperty() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testBoxedFloatFieldToProperty() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testStringFieldToProperty() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testListFieldToProperty() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testBigDecimalFieldToProperty() throws Exception {
|
||||
doTest(true);
|
||||
}
|
||||
|
||||
public void testLongFieldToProperty() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
private void doTest() throws Exception {
|
||||
doTest(false);
|
||||
}
|
||||
|
||||
private void doTest(boolean withFxml) throws Exception {
|
||||
final IntentionAction intentionAction = getIntentionAction(withFxml);
|
||||
assertNotNull(intentionAction);
|
||||
|
||||
Editor editor = getEditor();
|
||||
PsiFile file = getFile();
|
||||
|
||||
assertTrue(ShowIntentionActionsHandler.chooseActionAndInvoke(file, editor, intentionAction,actionName));
|
||||
checkResultByFile(getTestName(false) + "_after.java");
|
||||
}
|
||||
|
||||
protected IntentionAction getIntentionAction(boolean withFxml) throws Exception {
|
||||
if (withFxml) {
|
||||
configureByFiles(null, getTestName(false) + ".java", "sample.fxml");
|
||||
}
|
||||
else {
|
||||
configureByFiles(null, getTestName(false) + ".java");
|
||||
}
|
||||
final List<HighlightInfo> infos = doHighlighting();
|
||||
final Editor editor = getEditor();
|
||||
final PsiFile file = getFile();
|
||||
return findIntentionAction(infos, actionName, editor, file);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected String getTestDataPath() {
|
||||
return PluginPathManager.getPluginHomePath("javaFX") + "/testData/intentions/fieldToProperty/";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -27,5 +27,6 @@
|
||||
<orderEntry type="module" module-name="properties" />
|
||||
<orderEntry type="library" name="SceneBuilderKit" level="project" />
|
||||
<orderEntry type="module" module-name="testFramework-java" scope="TEST" />
|
||||
<orderEntry type="module" module-name="typeMigration" />
|
||||
</component>
|
||||
</module>
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
ObservableIntegerValue number;
|
||||
|
||||
int getNumber() {
|
||||
return number.get();
|
||||
}
|
||||
void setNumber(int newNumber) {
|
||||
number.set(newNumber);
|
||||
}
|
||||
ObservableIntegerValue number() {
|
||||
return number;
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
int number;
|
||||
|
||||
int getNumber() {
|
||||
return number;
|
||||
}
|
||||
void setNumber(int newNumber) {
|
||||
number = newNumber;
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
This intention converts a field into JavaFX property.
|
||||
</body>
|
||||
</html>
|
||||
@@ -44,6 +44,11 @@
|
||||
<className>org.jetbrains.plugins.javaFX.fxml.codeInsight.intentions.JavaFxExpandAttributeIntention</className>
|
||||
<category>JavaFX</category>
|
||||
</intentionAction>
|
||||
<intentionAction>
|
||||
<className>org.jetbrains.plugins.javaFX.codeInsight.JavaFxFieldToPropertyIntention</className>
|
||||
<category>JavaFX</category>
|
||||
</intentionAction>
|
||||
|
||||
<lang.importOptimizer language="XML" implementationClass="org.jetbrains.plugins.javaFX.fxml.codeInsight.JavaFxImportsOptimizer" order="before XML"/>
|
||||
<psi.referenceContributor implementation="org.jetbrains.plugins.javaFX.fxml.refs.JavaFxReferencesContributor"/>
|
||||
<getterSetterProvider implementation="org.jetbrains.plugins.javaFX.codeInsight.JavaFxGetterSetterPrototypeProvider"/>
|
||||
@@ -65,6 +70,7 @@
|
||||
<deadCode implementation="org.jetbrains.plugins.javaFX.JavaFxEntryPoint"/>
|
||||
<projectSdkSetupValidator implementation="org.jetbrains.plugins.javaFX.JavaFxProjectSdkSetupValidator" order="after javaSdk"/>
|
||||
<predefinedMigrationMapProvider implementation="org.jetbrains.plugins.javaFX.refactoring.migration.JavaFx9Migration"/>
|
||||
<postStartupActivity implementation="org.jetbrains.plugins.javaFX.fxml.JavaFxModuleUtil$JavaFxDetectionStartupActivity"/>
|
||||
</extensions>
|
||||
|
||||
<actions>
|
||||
|
||||
+422
@@ -0,0 +1,422 @@
|
||||
package org.jetbrains.plugins.javaFX.codeInsight;
|
||||
|
||||
import com.intellij.codeInsight.FileModificationService;
|
||||
import com.intellij.codeInsight.intention.LowPriorityAction;
|
||||
import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction;
|
||||
import com.intellij.lang.java.JavaLanguage;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.VariableKind;
|
||||
import com.intellij.psi.impl.PsiDiamondTypeUtil;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.*;
|
||||
import com.intellij.refactoring.typeMigration.*;
|
||||
import com.intellij.refactoring.typeMigration.usageInfo.TypeMigrationUsageInfo;
|
||||
import com.intellij.refactoring.util.RefactoringUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.Query;
|
||||
import com.siyeh.ig.psiutils.ParenthesesUtils;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.javaFX.fxml.JavaFxCommonNames;
|
||||
import org.jetbrains.plugins.javaFX.fxml.JavaFxModuleUtil;
|
||||
import org.jetbrains.plugins.javaFX.fxml.JavaFxPsiUtil;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author Pavel.Dolgov
|
||||
*/
|
||||
public class JavaFxFieldToPropertyIntention extends PsiElementBaseIntentionAction implements LowPriorityAction {
|
||||
private static final Logger LOG = Logger.getInstance(JavaFxFieldToPropertyIntention.class);
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return "Convert to JavaFX property";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
//noinspection DialogTitleCapitalization
|
||||
return "Convert to JavaFX property";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) {
|
||||
final PsiField field = getField(element);
|
||||
if (field != null) {
|
||||
final PsiFile file = field.getContainingFile();
|
||||
if (JavaFxModuleUtil.isInJavaFxProject(file) || JavaFxPsiUtil.isJavaFxPackageImported(file)) {
|
||||
return PropertyInfo.createPropertyInfo(field, project) != null;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException {
|
||||
final PsiField field = getField(element);
|
||||
LOG.assertTrue(field != null, "field");
|
||||
final PropertyInfo property = PropertyInfo.createPropertyInfo(field, project);
|
||||
LOG.assertTrue(property != null, "propertyInfo");
|
||||
|
||||
final Query<PsiReference> refs = ReferencesSearch.search(field);
|
||||
|
||||
final Set<PsiElement> elements = new HashSet<>();
|
||||
elements.add(element);
|
||||
for (PsiReference reference : refs) {
|
||||
elements.add(reference.getElement());
|
||||
}
|
||||
if (!FileModificationService.getInstance().preparePsiElementsForWrite(elements)) return;
|
||||
field.normalizeDeclaration();
|
||||
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(project).getElementFactory();
|
||||
final PsiType fromType = field.getType();
|
||||
final PsiType toType = elementFactory.createTypeFromText(property.myObservableType.myText, field);
|
||||
try {
|
||||
final TypeMigrationRules rules = new TypeMigrationRules();
|
||||
rules.setBoundScope(GlobalSearchScope.fileScope(element.getContainingFile()));
|
||||
final TypeMigrationLabeler labeler = new TypeMigrationLabeler(rules, toType);
|
||||
final TypeMigrationUsageInfo[] migratedUsages = labeler.getMigratedUsages(false, field);
|
||||
|
||||
for (PsiReference reference : refs) {
|
||||
final PsiElement refElement = reference.getElement();
|
||||
if (refElement instanceof PsiExpression) {
|
||||
final TypeConversionDescriptor conversion =
|
||||
property.myObservableType.findDirectConversion(refElement, toType, fromType, labeler);
|
||||
if (conversion != null) {
|
||||
TypeMigrationReplacementUtil.replaceExpression((PsiExpression)refElement, project, conversion, new TypeEvaluator(null, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
property.convertField();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiField getField(@NotNull PsiElement element) {
|
||||
if (!(element instanceof PsiIdentifier)) return null;
|
||||
final PsiField field = PsiTreeUtil.getParentOfType(element, PsiField.class);
|
||||
if (field == null) return null;
|
||||
if (field.getLanguage() != JavaLanguage.INSTANCE) return null;
|
||||
if (field.getTypeElement() == null) return null;
|
||||
if (field.hasModifierProperty(PsiModifier.STATIC) || field.hasModifierProperty(PsiModifier.FINAL)) return null;
|
||||
return field;
|
||||
}
|
||||
|
||||
private static class PropertyInfo {
|
||||
final PsiField myField;
|
||||
final PsiClass myContainingClass;
|
||||
final PsiTypeElement myTypeElement;
|
||||
final String myFieldName;
|
||||
final ObservableType myObservableType;
|
||||
|
||||
private PropertyInfo(@NotNull PsiField field,
|
||||
@NotNull PsiClass containingClass,
|
||||
@NotNull PsiTypeElement typeElement,
|
||||
@NotNull String fieldName,
|
||||
@NotNull ObservableType observableType) {
|
||||
myField = field;
|
||||
myContainingClass = containingClass;
|
||||
myTypeElement = typeElement;
|
||||
myFieldName = fieldName;
|
||||
myObservableType = observableType;
|
||||
}
|
||||
|
||||
static PropertyInfo createPropertyInfo(@NotNull PsiField field, @NotNull Project project) {
|
||||
final String fieldName = field.getName();
|
||||
final PsiClass containingClass = field.getContainingClass();
|
||||
final PsiTypeElement typeElement = field.getTypeElement();
|
||||
if (fieldName != null && containingClass != null && typeElement != null) {
|
||||
final ObservableType observableType = ObservableType.createObservableType(field, project);
|
||||
if (observableType != null) {
|
||||
return new PropertyInfo(field, containingClass, typeElement, fieldName, observableType);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void convertField() {
|
||||
final Project project = myContainingClass.getProject();
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(project).getElementFactory();
|
||||
|
||||
final PsiTypeElement newTypeElement = elementFactory.createTypeElementFromText(myObservableType.myText, myField);
|
||||
myTypeElement.replace(newTypeElement);
|
||||
|
||||
final PsiExpression initializer = myField.getInitializer();
|
||||
final String propertyName = JavaCodeStyleManager.getInstance(project).variableNameToPropertyName(myFieldName, VariableKind.FIELD);
|
||||
final String initializerArgs = "this,\"" + propertyName + "\"" + (initializer == null ? "" : "," + initializer.getText());
|
||||
|
||||
String initializerText = "new " + myObservableType.myText + "(" + initializerArgs + ")";
|
||||
final PsiNewExpression newInitializer = (PsiNewExpression)elementFactory.createExpressionFromText(initializerText, myField);
|
||||
myField.setInitializer(newInitializer);
|
||||
|
||||
final PsiType fieldType = myField.getType();
|
||||
if (PsiDiamondTypeUtil.canCollapseToDiamond(newInitializer, newInitializer, fieldType)) {
|
||||
final PsiJavaCodeReferenceElement classReference = newInitializer.getClassOrAnonymousClassReference();
|
||||
if (classReference != null) {
|
||||
PsiDiamondTypeUtil.replaceExplicitWithDiamond(classReference.getParameterList());
|
||||
}
|
||||
}
|
||||
myField.setInitializer(newInitializer);
|
||||
|
||||
final JavaCodeStyleManager javaCodeStyleManager = JavaCodeStyleManager.getInstance(project);
|
||||
final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(project);
|
||||
codeStyleManager.reformat(javaCodeStyleManager.shortenClassReferences(myField));
|
||||
}
|
||||
}
|
||||
|
||||
static class ObservableType {
|
||||
final String myText;
|
||||
|
||||
ObservableType(@NotNull String text) {
|
||||
this.myText = text;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static ObservableType createObservableType(@NotNull PsiField field, @NotNull Project project) {
|
||||
final PsiType type = field.getType();
|
||||
if (type instanceof PsiPrimitiveType) {
|
||||
final String text = JavaFxCommonNames.ourObservablePrimitiveWrappers.get(type);
|
||||
return text != null ? new ObservablePrimitive(text, (PsiPrimitiveType)type) : null;
|
||||
}
|
||||
final PsiPrimitiveType unboxedType = PsiPrimitiveType.getUnboxedType(type);
|
||||
if (unboxedType != null) {
|
||||
final String text = JavaFxCommonNames.ourObservablePrimitiveWrappers.get(unboxedType);
|
||||
return text != null ? new ObservablePrimitive(text, unboxedType) : null;
|
||||
}
|
||||
if (type.equalsToText(CommonClassNames.JAVA_LANG_STRING)) {
|
||||
return new ObservableString(project);
|
||||
}
|
||||
if (type instanceof PsiClassType) {
|
||||
if (InheritanceUtil.isInheritor(type, JavaFxCommonNames.JAVAFX_BEANS_OBSERVABLE)) {
|
||||
return null; // already observable
|
||||
}
|
||||
if (InheritanceUtil.isInheritor(type, CommonClassNames.JAVA_UTIL_LIST)) {
|
||||
return ObservableList.createObservableList(type, project);
|
||||
}
|
||||
else if (InheritanceUtil.isInheritor(type, CommonClassNames.JAVA_UTIL_COLLECTION) ||
|
||||
InheritanceUtil.isInheritor(type, CommonClassNames.JAVA_UTIL_MAP)) {
|
||||
return null; // TODO: support SimpleSetProperty, SimpleMapProperty
|
||||
}
|
||||
else {
|
||||
return new ObservableObject(type, project);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
TypeConversionDescriptor findDirectConversion(@NotNull PsiElement context,
|
||||
@NotNull PsiType to,
|
||||
@NotNull PsiType from,
|
||||
@NotNull TypeMigrationLabeler labeler) {
|
||||
final PsiClass toTypeClass = PsiUtil.resolveClassInType(to);
|
||||
LOG.assertTrue(toTypeClass != null);
|
||||
|
||||
final PsiElement parent = context.getParent();
|
||||
final PsiElement statementOrLambda = RefactoringUtil.getParentStatement(context, false);
|
||||
if (parent instanceof PsiAssignmentExpression) {
|
||||
final PsiAssignmentExpression expression = (PsiAssignmentExpression)parent;
|
||||
final IElementType tokenType = expression.getOperationTokenType();
|
||||
if (tokenType == JavaTokenType.EQ) {
|
||||
return findSimpleAssignmentConversion(expression);
|
||||
}
|
||||
final String sign = expression.getOperationSign().getText();
|
||||
final String binarySign = sign.substring(0, sign.length() - 1);
|
||||
return findCompoundAssignmentConversion(from, expression, sign, binarySign);
|
||||
}
|
||||
else if (parent instanceof PsiPostfixExpression) {
|
||||
final PsiPostfixExpression expression = (PsiPostfixExpression)parent;
|
||||
final TypeConversionDescriptor conversion = getUpdateConversion(expression, expression.getOperationSign(), true);
|
||||
if (conversion != null) return conversion;
|
||||
}
|
||||
else if (parent instanceof PsiPrefixExpression) {
|
||||
final PsiPrefixExpression expression = (PsiPrefixExpression)parent;
|
||||
final TypeConversionDescriptor conversion = getUpdateConversion(expression, expression.getOperationSign(), false);
|
||||
if (conversion != null) return conversion;
|
||||
}
|
||||
else if (context instanceof PsiReferenceExpression) {
|
||||
final PsiExpression qualifierExpression = ((PsiReferenceExpression)context).getQualifierExpression();
|
||||
final PsiExpression expression = context.getParent() instanceof PsiMethodCallExpression && qualifierExpression != null
|
||||
? qualifierExpression
|
||||
: (PsiExpression)context;
|
||||
return getReadConversion(expression);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
TypeConversionDescriptor findSimpleAssignmentConversion(PsiAssignmentExpression expression) {
|
||||
return new TypeConversionDescriptor("$qualifier$ = $val$", "$qualifier$.set($val$)", expression);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
TypeConversionDescriptor findCompoundAssignmentConversion(@NotNull PsiType from,
|
||||
@NotNull PsiExpression expression,
|
||||
@NotNull String sign,
|
||||
@NotNull String binarySign) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
TypeConversionDescriptor getUpdateConversion(@NotNull PsiExpression expression, @NotNull PsiJavaToken operationToken, boolean postfix) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
TypeConversionDescriptor getReadConversion(PsiExpression expression) {
|
||||
return new TypeConversionDescriptor("$qualifier$", "$qualifier$.get()", expression);
|
||||
}
|
||||
}
|
||||
|
||||
static class ObservablePrimitive extends ObservableType {
|
||||
final PsiPrimitiveType myType;
|
||||
|
||||
ObservablePrimitive(@NotNull String text, @NotNull PsiPrimitiveType type) {
|
||||
super(text);
|
||||
myType = type;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
TypeConversionDescriptor findCompoundAssignmentConversion(@NotNull PsiType from,
|
||||
@NotNull PsiExpression expression,
|
||||
@NotNull String sign,
|
||||
@NotNull String binarySign) {
|
||||
final PsiPrimitiveType unboxedType = PsiPrimitiveType.getUnboxedType(from);
|
||||
final String valueType = (unboxedType != null ? unboxedType : from).getCanonicalText();
|
||||
return new TypeConversionDescriptor("$qualifier$ " + sign + " $val$",
|
||||
"$qualifier$.set((" + valueType + ")($qualifier$.get() " + binarySign + " ($val$)))",
|
||||
expression);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
TypeConversionDescriptor getUpdateConversion(@NotNull PsiExpression expression, @NotNull PsiJavaToken operationToken, boolean postfix) {
|
||||
final PsiElement parent = ParenthesesUtils.getParentSkipParentheses(expression);
|
||||
if (parent instanceof PsiExpressionStatement) {
|
||||
final IElementType tokenType = operationToken.getTokenType();
|
||||
if (tokenType == JavaTokenType.PLUSPLUS || tokenType == JavaTokenType.MINUSMINUS) {
|
||||
final String sign = operationToken.getText();
|
||||
return new TypeConversionDescriptor(postfix ? ("$qualifier$" + sign) : (sign + "$qualifier$"),
|
||||
"$qualifier$.set($qualifier$.get()" + sign.charAt(0) + "1)", expression);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static class ObservableString extends ObservableType {
|
||||
ObservableString(@NotNull Project project) {
|
||||
super(JavaFxCommonNames.JAVAFX_BEANS_PROPERTY_SIMPLE_STRING_PROPERTY);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
TypeConversionDescriptor findCompoundAssignmentConversion(@NotNull PsiType from,
|
||||
@NotNull PsiExpression expression,
|
||||
@NotNull String sign,
|
||||
@NotNull String binarySign) {
|
||||
return new TypeConversionDescriptor("$qualifier$ " + sign + " $val$",
|
||||
"$qualifier$.set($qualifier$.get() " + binarySign + " ($val$))",
|
||||
expression);
|
||||
}
|
||||
}
|
||||
|
||||
static class ObservableList extends ObservableType {
|
||||
final PsiType myOriginalType;
|
||||
final PsiType myItemType;
|
||||
|
||||
ObservableList(@NotNull PsiType originalType, @NotNull PsiType itemType) {
|
||||
super(JavaFxCommonNames.JAVAFX_BEANS_PROPERTY_SIMPLE_LIST_PROPERTY + "<" + itemType.getCanonicalText() + ">");
|
||||
myOriginalType = originalType;
|
||||
myItemType = itemType;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static ObservableType createObservableList(@NotNull PsiType type, @NotNull Project project) {
|
||||
final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(type);
|
||||
final PsiClass fieldClass = resolveResult.getElement();
|
||||
if (fieldClass != null) {
|
||||
final PsiClass listClass = JavaPsiFacade.getInstance(project)
|
||||
.findClass(CommonClassNames.JAVA_UTIL_LIST, GlobalSearchScope.allScope(project));
|
||||
if (listClass != null) {
|
||||
final PsiSubstitutor substitutor =
|
||||
TypeConversionUtil.getClassSubstitutor(listClass, fieldClass, resolveResult.getSubstitutor());
|
||||
if (substitutor != null) {
|
||||
final PsiType itemType = substitutor.substitute(listClass.getTypeParameters()[0]);
|
||||
if (itemType != null) {
|
||||
return new ObservableList(type, itemType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
TypeConversionDescriptor findSimpleAssignmentConversion(PsiAssignmentExpression expression) {
|
||||
return new TypeConversionDescriptor("$qualifier$ = $val$", "$qualifier$.setAll($val$)", expression);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
TypeConversionDescriptor getReadConversion(PsiExpression expression) {
|
||||
return new TypeConversionDescriptor("$qualifier$", "$qualifier$.get()", expression) {
|
||||
@Override
|
||||
public PsiExpression replace(PsiExpression expression, TypeEvaluator evaluator) {
|
||||
final PsiExpression replaced = super.replace(expression, evaluator);
|
||||
// Replace the getter's return type: List -> ObservableList
|
||||
final PsiElement parent = replaced.getParent();
|
||||
if (parent instanceof PsiReturnStatement) {
|
||||
final PsiReturnStatement returnStatement = (PsiReturnStatement)parent;
|
||||
final PsiElement statementParent = returnStatement.getParent();
|
||||
if (statementParent instanceof PsiCodeBlock) {
|
||||
final PsiCodeBlock codeBlock = (PsiCodeBlock)statementParent;
|
||||
final PsiElement blockParent = codeBlock.getParent();
|
||||
if (blockParent instanceof PsiMethod) {
|
||||
final PsiMethod method = (PsiMethod)blockParent;
|
||||
final PsiTypeElement returnTypeElement = method.getReturnTypeElement();
|
||||
if (returnTypeElement != null && myOriginalType.equals(method.getReturnType())) {
|
||||
final Project project = expression.getProject();
|
||||
final String text = JavaFxCommonNames.JAVAFX_COLLECTIONS_OBSERVABLE_LIST + "<" + myItemType.getCanonicalText() + ">";
|
||||
final PsiTypeElement newReturnTypeElement = JavaPsiFacade.getInstance(project)
|
||||
.getElementFactory().createTypeElementFromText(text, method);
|
||||
final JavaCodeStyleManager javaCodeStyleManager = JavaCodeStyleManager.getInstance(project);
|
||||
javaCodeStyleManager.shortenClassReferences(returnTypeElement.replace(newReturnTypeElement));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return replaced;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
static class ObservableObject extends ObservableType {
|
||||
final PsiType myType;
|
||||
|
||||
ObservableObject(@NotNull PsiType type, @NotNull Project project) {
|
||||
super(JavaFxCommonNames.JAVAFX_BEANS_PROPERTY_SIMPLE_OBJECT_PROPERTY + "<" + type.getCanonicalText() + ">");
|
||||
myType = type;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.jetbrains.plugins.javaFX.fxml;
|
||||
|
||||
import com.intellij.psi.PsiPrimitiveType;
|
||||
import com.intellij.psi.PsiType;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
@@ -50,6 +51,9 @@ public class JavaFxCommonNames {
|
||||
@NonNls public static final String JAVAFX_BEANS_VALUE_WRITABLE_VALUE = "javafx.beans.value.WritableValue";
|
||||
@NonNls public static final String JAVAFX_SCENE_LAYOUT_PANE = "javafx.scene.layout.Pane";
|
||||
@NonNls public static final String JAVAFX_BEANS_NAMED_ARG = "javafx.beans.NamedArg";
|
||||
@NonNls public static final String JAVAFX_BEANS_PROPERTY_SIMPLE_STRING_PROPERTY = "javafx.beans.property.SimpleStringProperty";
|
||||
@NonNls public static final String JAVAFX_BEANS_PROPERTY_SIMPLE_LIST_PROPERTY = "javafx.beans.property.SimpleListProperty";
|
||||
@NonNls public static final String JAVAFX_BEANS_PROPERTY_SIMPLE_OBJECT_PROPERTY = "javafx.beans.property.SimpleObjectProperty";
|
||||
|
||||
@NonNls public static final String PROPERTY_METHOD_SUFFIX = "Property";
|
||||
|
||||
@@ -74,4 +78,13 @@ public class JavaFxCommonNames {
|
||||
@NonNls public static final String JAVA_FX_PARENT = "javafx.scene.Parent";
|
||||
@NonNls public static final String JAVA_FX_SCENE = "javafx.scene.Scene";
|
||||
@NonNls public static final String JAVAFX_APPLICATION_APPLICATION = "javafx.application.Application";
|
||||
|
||||
public static final Map<PsiPrimitiveType, String> ourObservablePrimitiveWrappers = new HashMap<>();
|
||||
static {
|
||||
ourObservablePrimitiveWrappers.put(PsiPrimitiveType.INT, "javafx.beans.property.SimpleIntegerProperty");
|
||||
ourObservablePrimitiveWrappers.put(PsiPrimitiveType.LONG, "javafx.beans.property.SimpleLongProperty");
|
||||
ourObservablePrimitiveWrappers.put(PsiPrimitiveType.FLOAT, "javafx.beans.property.SimpleFloatProperty");
|
||||
ourObservablePrimitiveWrappers.put(PsiPrimitiveType.DOUBLE, "javafx.beans.property.SimpleDoubleProperty");
|
||||
ourObservablePrimitiveWrappers.put(PsiPrimitiveType.BOOLEAN, "javafx.beans.property.SimpleBooleanProperty");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.intellij.openapi.fileTypes.FileTypeFactory;
|
||||
import com.intellij.openapi.fileTypes.FileTypeManager;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -13,7 +14,8 @@ import org.jetbrains.annotations.NotNull;
|
||||
* Date: 1/8/13
|
||||
*/
|
||||
public class JavaFxFileTypeFactory extends FileTypeFactory {
|
||||
public static final String FXML_EXTENSION = "fxml";
|
||||
@NonNls public static final String FXML_EXTENSION = "fxml";
|
||||
@NonNls private static final String DOT_FXML_EXTENSION = "." + FXML_EXTENSION;
|
||||
|
||||
public static boolean isFxml(@NotNull PsiFile file) {
|
||||
final VirtualFile virtualFile = file.getViewProvider().getVirtualFile();
|
||||
@@ -23,11 +25,18 @@ public class JavaFxFileTypeFactory extends FileTypeFactory {
|
||||
public static boolean isFxml(@NotNull VirtualFile virtualFile) {
|
||||
if (FXML_EXTENSION.equals(virtualFile.getExtension())) {
|
||||
final FileType fileType = virtualFile.getFileType();
|
||||
if (fileType == FileTypeManager.getInstance().getFileTypeByExtension(FXML_EXTENSION) && !fileType.isBinary()) return true;
|
||||
if (fileType == getFileType() && !fileType.isBinary()) {
|
||||
return virtualFile.getName().endsWith(DOT_FXML_EXTENSION);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static FileType getFileType() {
|
||||
return FileTypeManager.getInstance().getFileTypeByExtension(FXML_EXTENSION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createFileTypes(@NotNull FileTypeConsumer consumer) {
|
||||
final FileType fileType = consumer.getStandardFileTypeByName("XML");
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
package org.jetbrains.plugins.javaFX.fxml;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleUtil;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.startup.StartupActivity;
|
||||
import com.intellij.openapi.startup.StartupManager;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.packaging.artifacts.Artifact;
|
||||
import com.intellij.packaging.artifacts.ArtifactManager;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.search.FileTypeIndex;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.CachedValueProvider;
|
||||
import com.intellij.psi.util.CachedValuesManager;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.javaFX.packaging.JavaFxApplicationArtifactType;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author Pavel.Dolgov
|
||||
*/
|
||||
public class JavaFxModuleUtil {
|
||||
public static boolean isInJavaFxProject(@NotNull PsiFile file) {
|
||||
final Project project = file.getProject();
|
||||
if (hasJavaFxArtifacts(project)) {
|
||||
return true;
|
||||
}
|
||||
return isInJavaFxModule(file);
|
||||
}
|
||||
|
||||
private static boolean isInJavaFxModule(@NotNull PsiFile file) {
|
||||
final VirtualFile virtualFile = file.getVirtualFile();
|
||||
if (virtualFile != null) {
|
||||
final Project project = file.getProject();
|
||||
final Module fileModule = ModuleUtil.findModuleForFile(virtualFile, project);
|
||||
if (fileModule != null) {
|
||||
return getCachedJavaFxModules(project).contains(fileModule);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Set<Module> getCachedJavaFxModules(@NotNull Project project) {
|
||||
Set<Module> value = CachedValuesManager.getManager(project).getCachedValue(
|
||||
project, () -> {
|
||||
final Collection<VirtualFile> files =
|
||||
FileTypeIndex.getFiles(JavaFxFileTypeFactory.getFileType(), GlobalSearchScope.projectScope(project));
|
||||
|
||||
final Set<Module> modules = files.stream()
|
||||
.filter(JavaFxFileTypeFactory::isFxml)
|
||||
.map(file -> ModuleUtil.findModuleForFile(file, project))
|
||||
.collect(Collectors.toCollection(THashSet::new));
|
||||
|
||||
return CachedValueProvider.Result.create(modules, ProjectRootManager.getInstance(project));
|
||||
});
|
||||
return value;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static boolean hasJavaFxArtifacts(@NotNull Project project) {
|
||||
return CachedValuesManager.getManager(project).getCachedValue(
|
||||
project, () -> {
|
||||
final Collection<? extends Artifact> artifacts =
|
||||
ArtifactManager.getInstance(project).getArtifactsByType(JavaFxApplicationArtifactType.getInstance());
|
||||
return CachedValueProvider.Result.create(!artifacts.isEmpty(), ProjectRootManager.getInstance(project));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Avoids freeze on first use of Java intentions
|
||||
*/
|
||||
public static class JavaFxDetectionStartupActivity implements StartupActivity {
|
||||
@Override
|
||||
public void runActivity(@NotNull Project project) {
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
return;
|
||||
}
|
||||
StartupManager.getInstance(project).runWhenProjectIsInitialized(
|
||||
() -> ApplicationManager.getApplication().executeOnPooledThread(
|
||||
() -> DumbService.getInstance(project).runReadActionInSmartMode(
|
||||
() -> populateCachedJavaFxModules(project))));
|
||||
}
|
||||
|
||||
private void populateCachedJavaFxModules(@NotNull Project project) {
|
||||
if (!project.isDisposed() && project.isOpen()) {
|
||||
hasJavaFxArtifacts(project);
|
||||
getCachedJavaFxModules(project);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1236,4 +1236,26 @@ public class JavaFxPsiUtil {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean isJavaFxPackageImported(@NotNull PsiFile file) {
|
||||
if (!(file instanceof PsiJavaFile)) return false;
|
||||
final PsiJavaFile javaFile = (PsiJavaFile)file;
|
||||
|
||||
return CachedValuesManager.getCachedValue(
|
||||
javaFile, () -> {
|
||||
final PsiImportList importList = javaFile.getImportList();
|
||||
if (importList != null) {
|
||||
for (PsiImportStatementBase statementBase : importList.getAllImportStatements()) {
|
||||
final PsiJavaCodeReferenceElement importReference = statementBase.getImportReference();
|
||||
if (importReference != null) {
|
||||
final String qualifiedName = importReference.getQualifiedName();
|
||||
if (qualifiedName != null && qualifiedName.startsWith("javafx.")) {
|
||||
return CachedValueProvider.Result.create(true, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return CachedValueProvider.Result.create(false, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import java.math.BigDecimal;
|
||||
|
||||
class BigDecimalDemo {
|
||||
private BigDecimal nu<caret>mber = new BigDecimal(42);
|
||||
|
||||
BigDecimalDemo(BigDecimal number) {
|
||||
this.number = number;
|
||||
}
|
||||
|
||||
public BigDecimal get() {
|
||||
return number;
|
||||
}
|
||||
|
||||
public BigDecimal get(int i) {
|
||||
return number;
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
class BigDecimalDemo {
|
||||
private SimpleObjectProperty<BigDecimal> number = new SimpleObjectProperty<>(this, "number", new BigDecimal(42));
|
||||
|
||||
BigDecimalDemo(BigDecimal number) {
|
||||
this.number.set(number);
|
||||
}
|
||||
|
||||
public BigDecimal get() {
|
||||
return number.get();
|
||||
}
|
||||
|
||||
public BigDecimal get(int i) {
|
||||
return number.get();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
import javafx.scene.Node;
|
||||
|
||||
class BoxedFloatDemo {
|
||||
private Float <caret>f;
|
||||
|
||||
BoxedFloatDemo(Float f) {
|
||||
this.f = f;
|
||||
}
|
||||
|
||||
public Float getF() {
|
||||
return f;
|
||||
}
|
||||
|
||||
public void setF(Float f) {
|
||||
this.f = f;
|
||||
}
|
||||
|
||||
public void preInc() {
|
||||
++f;
|
||||
}
|
||||
|
||||
public void postDec() {
|
||||
f--;
|
||||
}
|
||||
|
||||
public void twice() {
|
||||
f *= 2;
|
||||
}
|
||||
|
||||
public void half() {
|
||||
f /= 1;
|
||||
}
|
||||
|
||||
public Float plusOne() {
|
||||
return f + 1;
|
||||
}
|
||||
|
||||
public F lambda() {
|
||||
return () -> f;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "f=" + f;
|
||||
}
|
||||
|
||||
interface F {
|
||||
Float get();
|
||||
}
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
import javafx.beans.property.SimpleFloatProperty;
|
||||
import javafx.scene.Node;
|
||||
|
||||
class BoxedFloatDemo {
|
||||
private SimpleFloatProperty f = new SimpleFloatProperty(this, "f");
|
||||
|
||||
BoxedFloatDemo(Float f) {
|
||||
this.f.set(f);
|
||||
}
|
||||
|
||||
public Float getF() {
|
||||
return f.get();
|
||||
}
|
||||
|
||||
public void setF(Float f) {
|
||||
this.f.set(f);
|
||||
}
|
||||
|
||||
public void preInc() {
|
||||
f.set(f.get() + 1);
|
||||
}
|
||||
|
||||
public void postDec() {
|
||||
f.set(f.get() - 1);
|
||||
}
|
||||
|
||||
public void twice() {
|
||||
f.set((float) (f.get() * (2)));
|
||||
}
|
||||
|
||||
public void half() {
|
||||
f.set((float) (f.get() / (1)));
|
||||
}
|
||||
|
||||
public Float plusOne() {
|
||||
return f.get() + 1;
|
||||
}
|
||||
|
||||
public F lambda() {
|
||||
return () -> f.get();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "f=" + f.get();
|
||||
}
|
||||
|
||||
interface F {
|
||||
Float get();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
import javafx.scene.Node;
|
||||
|
||||
class IntDemo {
|
||||
int <caret>n;
|
||||
|
||||
IntDemo(int n) {
|
||||
this.n = n;
|
||||
}
|
||||
|
||||
public int getN() {
|
||||
return n;
|
||||
}
|
||||
|
||||
public void setN(int n) {
|
||||
this.n = n;
|
||||
}
|
||||
|
||||
public void preInc() {
|
||||
++n;
|
||||
}
|
||||
|
||||
public void postDec() {
|
||||
n--;
|
||||
}
|
||||
|
||||
public int preIncVal() {
|
||||
return ++n;
|
||||
}
|
||||
|
||||
public void twice() {
|
||||
n *= 2;
|
||||
}
|
||||
|
||||
public void half() {
|
||||
n >>= 1;
|
||||
}
|
||||
|
||||
public int plusOne() {
|
||||
return n + 1;
|
||||
}
|
||||
|
||||
public void forLoop(int a) {
|
||||
for (n = 0; n < a; n++) {
|
||||
System.out.println(n);
|
||||
}
|
||||
}
|
||||
|
||||
public I lambda() {
|
||||
return () -> n;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "n=" + n;
|
||||
}
|
||||
|
||||
interface I {
|
||||
int get();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
import javafx.beans.property.SimpleIntegerProperty;
|
||||
import javafx.scene.Node;
|
||||
|
||||
class IntDemo {
|
||||
SimpleIntegerProperty n = new SimpleIntegerProperty(this, "n");
|
||||
|
||||
IntDemo(int n) {
|
||||
this.n.set(n);
|
||||
}
|
||||
|
||||
public int getN() {
|
||||
return n.get();
|
||||
}
|
||||
|
||||
public void setN(int n) {
|
||||
this.n.set(n);
|
||||
}
|
||||
|
||||
public void preInc() {
|
||||
n.set(n.get() + 1);
|
||||
}
|
||||
|
||||
public void postDec() {
|
||||
n.set(n.get() - 1);
|
||||
}
|
||||
|
||||
public int preIncVal() {
|
||||
return ++n;
|
||||
}
|
||||
|
||||
public void twice() {
|
||||
n.set((int) (n.get() * (2)));
|
||||
}
|
||||
|
||||
public void half() {
|
||||
n.set((int) (n.get() >> (1)));
|
||||
}
|
||||
|
||||
public int plusOne() {
|
||||
return n.get() + 1;
|
||||
}
|
||||
|
||||
public void forLoop(int a) {
|
||||
for (n.set(0); n.get() < a; n.set(n.get() + 1)) {
|
||||
System.out.println(n.get());
|
||||
}
|
||||
}
|
||||
|
||||
public I lambda() {
|
||||
return () -> n.get();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "n=" + n.get();
|
||||
}
|
||||
|
||||
interface I {
|
||||
int get();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
import javafx.scene.Node;
|
||||
|
||||
class ListDemo {
|
||||
private List<URL> <caret>urls;
|
||||
|
||||
ListDemo(List<URL> urls) {
|
||||
this.urls = urls;
|
||||
}
|
||||
|
||||
public List<URL> getUrls() {
|
||||
return urls;
|
||||
}
|
||||
|
||||
public void setUrls(List<URL> urls) {
|
||||
this.urls = urls;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "urls=" + urls;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
|
||||
import javafx.beans.property.SimpleListProperty;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.scene.Node;
|
||||
|
||||
class ListDemo {
|
||||
private SimpleListProperty<URL> urls = new SimpleListProperty<>(this, "urls");
|
||||
|
||||
ListDemo(List<URL> urls) {
|
||||
this.urls.setAll(urls);
|
||||
}
|
||||
|
||||
public ObservableList<URL> getUrls() {
|
||||
return urls.get();
|
||||
}
|
||||
|
||||
public void setUrls(List<URL> urls) {
|
||||
this.urls.setAll(urls);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "urls=" + urls.get();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
class LongDemo {
|
||||
private long <caret>n;
|
||||
|
||||
public long getN() {
|
||||
return n;
|
||||
}
|
||||
|
||||
public void setN(long n) {
|
||||
this.n = n;
|
||||
}
|
||||
|
||||
public void preInc() {
|
||||
++n;
|
||||
}
|
||||
|
||||
public long preIncVal() {
|
||||
return ++n;
|
||||
}
|
||||
|
||||
public void postDec() {
|
||||
n--;
|
||||
}
|
||||
|
||||
public void twice() {
|
||||
n *= 2;
|
||||
}
|
||||
|
||||
public void half() {
|
||||
n >>= 1;
|
||||
}
|
||||
|
||||
public long plusOne() {
|
||||
return n + 1;
|
||||
}
|
||||
|
||||
public L lambda() {
|
||||
return () -> n;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "n=" + n;
|
||||
}
|
||||
|
||||
interface L {
|
||||
long get();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
import javafx.beans.property.SimpleLongProperty;
|
||||
|
||||
class LongDemo {
|
||||
private SimpleLongProperty n = new SimpleLongProperty(this, "n");
|
||||
|
||||
public long getN() {
|
||||
return n.get();
|
||||
}
|
||||
|
||||
public void setN(long n) {
|
||||
this.n.set(n);
|
||||
}
|
||||
|
||||
public void preInc() {
|
||||
n.set(n.get() + 1);
|
||||
}
|
||||
|
||||
public long preIncVal() {
|
||||
return ++n;
|
||||
}
|
||||
|
||||
public void postDec() {
|
||||
n.set(n.get() - 1);
|
||||
}
|
||||
|
||||
public void twice() {
|
||||
n.set((long) (n.get() * (2)));
|
||||
}
|
||||
|
||||
public void half() {
|
||||
n.set((long) (n.get() >> (1)));
|
||||
}
|
||||
|
||||
public long plusOne() {
|
||||
return n.get() + 1;
|
||||
}
|
||||
|
||||
public L lambda() {
|
||||
return () -> n.get();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "n=" + n.get();
|
||||
}
|
||||
|
||||
interface L {
|
||||
long get();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import javafx.scene.Node;
|
||||
|
||||
class StringDemo {
|
||||
String <caret>s = "Something";
|
||||
|
||||
StringDemo(String s) {
|
||||
this.s = s;
|
||||
}
|
||||
|
||||
public void compound(String t) {
|
||||
s += t;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "s=" + s;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.scene.Node;
|
||||
|
||||
class StringDemo {
|
||||
SimpleStringProperty s = new SimpleStringProperty(this, "s", "Something");
|
||||
|
||||
StringDemo(String s) {
|
||||
this.s.set(s);
|
||||
}
|
||||
|
||||
public void compound(String t) {
|
||||
s.set(s.get() + (t));
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "s=" + s.get();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.layout.GridPane?>
|
||||
|
||||
<GridPane xmlns:fx="http://javafx.com/fxml/1">
|
||||
</GridPane>
|
||||
Reference in New Issue
Block a user