diff --git a/plugins/javaFX/FxBuilderEmbedder/lib/embedder.jar b/plugins/javaFX/FxBuilderEmbedder/lib/embedder.jar index ec19b110af58..1ddf9204cf68 100644 Binary files a/plugins/javaFX/FxBuilderEmbedder/lib/embedder.jar and b/plugins/javaFX/FxBuilderEmbedder/lib/embedder.jar differ diff --git a/plugins/javaFX/FxBuilderEmbedder/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderImpl.java b/plugins/javaFX/FxBuilderEmbedder/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderImpl.java index a99d55d3e163..025da2f708f0 100644 --- a/plugins/javaFX/FxBuilderEmbedder/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderImpl.java +++ b/plugins/javaFX/FxBuilderEmbedder/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderImpl.java @@ -7,6 +7,8 @@ import com.oracle.javafx.scenebuilder.kit.editor.panel.inspector.InspectorPanelC import com.oracle.javafx.scenebuilder.kit.editor.panel.library.LibraryPanelController; import com.oracle.javafx.scenebuilder.kit.fxom.FXOMDocument; import javafx.application.Platform; +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; import javafx.embed.swing.JFXPanel; import javafx.geometry.Orientation; import javafx.scene.Scene; @@ -21,13 +23,14 @@ import java.net.URL; */ public class SceneBuilderImpl implements SceneBuilder { private final URL myFileURL; - private final ErrorHandler myErrorHandler; + private final EditorCallback myEditorCallback; private final JFXPanel myPanel = new JFXPanel(); private EditorController myEditorController; + private ChangeListener myListener; - public SceneBuilderImpl(URL url, ErrorHandler errorHandler) { + public SceneBuilderImpl(URL url, EditorCallback editorCallback) { myFileURL = url; - myErrorHandler = errorHandler; + myEditorCallback = editorCallback; Platform.runLater(new Runnable() { @Override @@ -45,6 +48,7 @@ public class SceneBuilderImpl implements SceneBuilder { LibraryPanelController palette = new LibraryPanelController(myEditorController); loadFile(); + startChangeListener(); SplitPane leftPane = new SplitPane(); leftPane.setOrientation(Orientation.VERTICAL); @@ -73,19 +77,38 @@ public class SceneBuilderImpl implements SceneBuilder { Platform.runLater(new Runnable() { @Override public void run() { - create(); + // TODO: restore state + loadFile(); } }); } } + private void startChangeListener() { + myListener = new ChangeListener() { + @Override + public void changed(ObservableValue observable, Number oldValue, Number newValue) { + myEditorCallback.saveChanges(myEditorController.getFxmlText()); + } + }; + + myEditorController.getJobManager().revisionProperty().addListener(myListener); + } + + @Override + public void close() { + if (myEditorController != null) { + myEditorController.getJobManager().revisionProperty().removeListener(myListener); + } + } + private void loadFile() { try { String fxmlText = FXOMDocument.readContentFromURL(myFileURL); myEditorController.setFxmlTextAndLocation(fxmlText, myFileURL); } catch (Throwable e) { - myErrorHandler.handle(e); + myEditorCallback.handleError(e); } } } \ No newline at end of file diff --git a/plugins/javaFX/FxBuilderEmbedder/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderKitWrapper.java b/plugins/javaFX/FxBuilderEmbedder/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderKitWrapper.java index 5515be078451..592401c7b96f 100644 --- a/plugins/javaFX/FxBuilderEmbedder/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderKitWrapper.java +++ b/plugins/javaFX/FxBuilderEmbedder/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderKitWrapper.java @@ -14,7 +14,7 @@ import java.util.HashSet; * @author Alexander Lobas */ public class SceneBuilderKitWrapper { - public static SceneBuilder create(URL url, ErrorHandler errorHandler) throws Exception { + public static SceneBuilder create(URL url, EditorCallback editorCallback) throws Exception { // JavaFX -> Swing drag&drop fix Field identifier = DataFormat.class.getDeclaredField("identifier"); identifier.setAccessible(true); @@ -24,6 +24,6 @@ public class SceneBuilderKitWrapper { // JavaFX class loading fix FXMLLoader.setDefaultClassLoader(SceneBuilderKitWrapper.class.getClassLoader()); - return new SceneBuilderImpl(url, errorHandler); + return new SceneBuilderImpl(url, editorCallback); } } \ No newline at end of file diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/sceneBuilder/EditorCallback.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/sceneBuilder/EditorCallback.java new file mode 100644 index 000000000000..8d019dcf29ee --- /dev/null +++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/sceneBuilder/EditorCallback.java @@ -0,0 +1,10 @@ +package org.jetbrains.plugins.javaFX.sceneBuilder; + +/** + * @author Alexander Lobas + */ +public interface EditorCallback { + void saveChanges(String content); + + void handleError(Throwable e); +} \ No newline at end of file diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/sceneBuilder/ErrorHandler.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/sceneBuilder/ErrorHandler.java deleted file mode 100644 index 09858623aec8..000000000000 --- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/sceneBuilder/ErrorHandler.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.jetbrains.plugins.javaFX.sceneBuilder; - -/** - * @author Alexander Lobas - */ -public interface ErrorHandler { - void handle(Throwable e); -} \ No newline at end of file diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/sceneBuilder/ErrorSceneBuilderCreator.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/sceneBuilder/ErrorSceneBuilderCreator.java index ea5e7a1ccc13..e1f989df9c7e 100644 --- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/sceneBuilder/ErrorSceneBuilderCreator.java +++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/sceneBuilder/ErrorSceneBuilderCreator.java @@ -18,7 +18,7 @@ public class ErrorSceneBuilderCreator implements SceneBuilderCreator { } @Override - public SceneBuilder create(URL url, ErrorHandler errorHandler) throws Exception { + public SceneBuilder create(URL url, EditorCallback editorCallback) throws Exception { throw new UnsupportedOperationException(); } } \ No newline at end of file diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilder.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilder.java index 23406c4f3e5c..4891d6bd4ac7 100644 --- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilder.java +++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilder.java @@ -9,4 +9,6 @@ public interface SceneBuilder { JComponent getPanel(); void reloadFile(); + + void close(); } \ No newline at end of file diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderCreator.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderCreator.java index 7ab9cf3ab513..4a81bac001aa 100644 --- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderCreator.java +++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderCreator.java @@ -8,5 +8,5 @@ import java.net.URL; public interface SceneBuilderCreator { State getState(); - SceneBuilder create(URL url, ErrorHandler errorHandler) throws Exception; + SceneBuilder create(URL url, EditorCallback editorCallback) throws Exception; } \ No newline at end of file diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderCreatorImpl.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderCreatorImpl.java index 326f770279fc..97832c4888f7 100644 --- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderCreatorImpl.java +++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderCreatorImpl.java @@ -30,9 +30,9 @@ public class SceneBuilderCreatorImpl implements SceneBuilderCreator { } @Override - public SceneBuilder create(URL url, ErrorHandler errorHandler) throws Exception { + public SceneBuilder create(URL url, EditorCallback editorCallback) throws Exception { Class wrapperClass = Class.forName("org.jetbrains.plugins.javaFX.sceneBuilder.SceneBuilderKitWrapper", false, myClassLoader); - return (SceneBuilder)wrapperClass.getMethod("create", URL.class, ErrorHandler.class).invoke(null, url, errorHandler); + return (SceneBuilder)wrapperClass.getMethod("create", URL.class, EditorCallback.class).invoke(null, url, editorCallback); } @Override diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderEditor.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderEditor.java index fd8271ba20e8..d102654d5a6d 100644 --- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderEditor.java +++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderEditor.java @@ -2,6 +2,8 @@ package org.jetbrains.plugins.javaFX.sceneBuilder; import com.intellij.codeHighlighting.BackgroundEditorHighlighter; import com.intellij.ide.structureView.StructureViewBuilder; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.event.DocumentAdapter; @@ -27,7 +29,7 @@ import java.net.URL; /** * @author Alexander Lobas */ -public class SceneBuilderEditor extends UserDataHolderBase implements FileEditor, ErrorHandler { +public class SceneBuilderEditor extends UserDataHolderBase implements FileEditor, EditorCallback { private static final Logger LOG = Logger.getInstance("#org.jetbrains.plugins.javaFX.sceneBuilder.SceneBuilderEditor"); private final static String SCENE_CARD = "scene_builder"; @@ -43,6 +45,7 @@ public class SceneBuilderEditor extends UserDataHolderBase implements FileEditor private final JPanel myErrorPanel = new JPanel(new VerticalFlowLayout(VerticalFlowLayout.TOP, 10, 5, true, false)); private final HyperlinkLabel myErrorLabel = new HyperlinkLabel(); + private final Document myDocument; private final ExternalChangeListener myChangeListener; private SceneBuilderCreator myBuilderCreator; @@ -54,6 +57,7 @@ public class SceneBuilderEditor extends UserDataHolderBase implements FileEditor myFile = file; myCreatorProvider = creatorProvider; + myDocument = FileDocumentManager.getInstance().getDocument(file); myChangeListener = new ExternalChangeListener(); createErrorPage(); @@ -101,7 +105,37 @@ public class SceneBuilderEditor extends UserDataHolderBase implements FileEditor } @Override - public void handle(Throwable e) { + public void saveChanges(final String content) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + if (mySceneBuilder != null) { + try { + myChangeListener.setRunState(false); + + // XXX: strange behavior with undo/redo + + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { + @Override + public void run() { + myDocument.setText(content); + } + }, "JavaFX Scene Builder edit operation", null); + } + }); + } + finally { + myChangeListener.setRunState(true); + } + } + } + }); + } + + @Override + public void handleError(Throwable e) { showErrorPage(null, e); } @@ -163,6 +197,7 @@ public class SceneBuilderEditor extends UserDataHolderBase implements FileEditor if (mySceneBuilder != null) { myPanel.remove(mySceneBuilder.getPanel()); + mySceneBuilder.close(); mySceneBuilder = null; } } @@ -248,12 +283,10 @@ public class SceneBuilderEditor extends UserDataHolderBase implements FileEditor } private class ExternalChangeListener extends DocumentAdapter { - private final Document myDocument; private volatile boolean myRunState; private String myContent; public ExternalChangeListener() { - myDocument = FileDocumentManager.getInstance().getDocument(myFile); myDocument.addDocumentListener(this); } @@ -271,6 +304,10 @@ public class SceneBuilderEditor extends UserDataHolderBase implements FileEditor } } + public void setRunState(boolean state) { + myRunState = state; + } + public void dispose() { myDocument.removeDocumentListener(this); }