OpenJDK / openjfx / 8u-dev / rt
changeset 6031:ffae6092f803
Sync up SceneBuilder changes
line wrap: on
line diff
--- a/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/DocumentWindow.fxml Fri Dec 20 15:48:27 2013 -0800 +++ b/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/DocumentWindow.fxml Mon Dec 23 13:59:52 2013 +0100 @@ -31,13 +31,14 @@ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --> + <?import java.lang.*?> <?import java.net.*?> <?import javafx.scene.control.*?> <?import javafx.scene.layout.*?> <?scenebuilder-preview-i18n-resource i18n/SceneBuilderApp.properties?> -<VBox id="DocumentWindow" alignment="CENTER" prefHeight="800.0" prefWidth="1200.0" spacing="0.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2"> +<VBox id="DocumentWindow" alignment="CENTER" prefHeight="800.0" prefWidth="1200.0" spacing="0.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"> <children> <SplitPane fx:id="mainSplitPane" dividerPositions="0.656641604010025" focusTraversable="true" orientation="VERTICAL" prefHeight="200.0" prefWidth="160.0" VBox.vgrow="ALWAYS"> <items> @@ -49,14 +50,22 @@ <children> <HBox id="HBox" alignment="CENTER" spacing="0.0" styleClass="panelHeader"> <children> - <Label maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" styleClass="panelTitle" text="Library" HBox.hgrow="NEVER" /> + <Label maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" styleClass="panelTitle" text="%library" HBox.hgrow="NEVER" /> <StackPane fx:id="librarySearchPanelHost" maxHeight="-1.0" maxWidth="-1.0" minHeight="-1.0" minWidth="-1.0" prefHeight="-1.0" prefWidth="-1.0" style="" HBox.hgrow="ALWAYS" /> - <MenuButton fx:id="LibraryMenu" mnemonicParsing="false" styleClass="panelMenuButton" text="" HBox.hgrow="NEVER"> + <MenuButton fx:id="libraryMenuButton" mnemonicParsing="false" styleClass="panelMenuButton" text="" HBox.hgrow="NEVER"> <items> - <CheckMenuItem mnemonicParsing="false" onAction="#onLibraryViewAsList" text="%library.panel.menu.view.list" fx:id="libraryViewAsList" /> - <CheckMenuItem mnemonicParsing="false" onAction="#onLibraryViewAsSections" selected="true" text="%library.panel.menu.view.sections" fx:id="libraryViewAsSections" /> + <CheckMenuItem fx:id="libraryViewAsList" mnemonicParsing="false" onAction="#onLibraryViewAsList" text="%library.panel.menu.view.list" /> + <CheckMenuItem fx:id="libraryViewAsSections" mnemonicParsing="false" onAction="#onLibraryViewAsSections" selected="true" text="%library.panel.menu.view.sections" /> <SeparatorMenuItem mnemonicParsing="false" /> <MenuItem mnemonicParsing="false" onAction="#onLibraryImportJarFxml" text="%library.panel.menu.import.jar.fxml" /> + <MenuItem fx:id="libraryImportSelection" mnemonicParsing="false" onAction="#onLibraryImportSelection" text="%library.panel.menu.import.selection" /> + <SeparatorMenuItem mnemonicParsing="false" /> + <Menu mnemonicParsing="false" text="%library.panel.menu.custom"> + <items> + <MenuItem fx:id="libraryReveal" mnemonicParsing="false" onAction="#onLibraryRevealCustomFolder" text="Action 1" /> + <MenuItem fx:id="libraryReport" mnemonicParsing="false" onAction="#onLibraryShowJarAnalysisReport" text="%library.panel.menu.custom.report" /> + </items> + </Menu> </items> </MenuButton> </children> @@ -68,29 +77,33 @@ <children> <HBox id="HBox" alignment="CENTER" spacing="0.0" VBox.vgrow="NEVER"> <children> - <Label maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" styleClass="panelTitle" text="Document" HBox.hgrow="NEVER" /> + <Label maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" styleClass="panelTitle" text="%document" HBox.hgrow="NEVER" /> <Pane maxWidth="1.7976931348623157E308" prefHeight="-1.0" prefWidth="-1.0" HBox.hgrow="ALWAYS" /> - <MenuButton fx:id="HierarchyMenu" contentDisplay="GRAPHIC_ONLY" mnemonicParsing="false" styleClass="panelMenuButton" text=""> + <MenuButton fx:id="" contentDisplay="GRAPHIC_ONLY" mnemonicParsing="false" styleClass="panelMenuButton" text=""> <items> - <RadioMenuItem mnemonicParsing="false" onAction="#onHierarchyShowInfo" selected="true" text="Show Info" fx:id="showInfoMenuItem"> - <toggleGroup> - <ToggleGroup fx:id="hierarchyDisplayOptionTG" /> - </toggleGroup> - </RadioMenuItem> - <RadioMenuItem mnemonicParsing="false" onAction="#onHierarchyShowFxId" text="Show fx:id" toggleGroup="$hierarchyDisplayOptionTG" fx:id="showFxIdMenuItem" /> - <RadioMenuItem mnemonicParsing="false" onAction="#onHierarchyShowNodeId" text="Show Node Id" toggleGroup="$hierarchyDisplayOptionTG" fx:id="showNodeIdMenuItem" /> + <Menu mnemonicParsing="false" text="%hierarchy.displays"> + <items> + <RadioMenuItem fx:id="showInfoMenuItem" mnemonicParsing="false" onAction="#onHierarchyShowInfo" selected="true" text="%hierarchy.show.info"> + <toggleGroup> + <ToggleGroup fx:id="hierarchyDisplayOptionTG" /> + </toggleGroup> + </RadioMenuItem> + <RadioMenuItem fx:id="showFxIdMenuItem" mnemonicParsing="false" onAction="#onHierarchyShowFxId" text="%hierarchy.show.fxid" toggleGroup="$hierarchyDisplayOptionTG" /> + <RadioMenuItem fx:id="showNodeIdMenuItem" mnemonicParsing="false" onAction="#onHierarchyShowNodeId" text="%hierarchy.show.nodeid" toggleGroup="$hierarchyDisplayOptionTG" /> + </items> + </Menu> </items> </MenuButton> </children> </HBox> <Accordion fx:id="documentAccordion" maxHeight="-1.0" VBox.vgrow="ALWAYS"> <panes> - <TitledPane fx:id="Hierarchy" animated="true" text="Hierarchy"> + <TitledPane fx:id="Hierarchy" animated="true" text="%hierarchy"> <content> <StackPane fx:id="hierarchyPanelHost" maxHeight="-1.0" style="-fx-padding: 0;" /> </content> </TitledPane> - <TitledPane fx:id="Info" animated="true" text="Controller"> + <TitledPane fx:id="Info" animated="true" text="%controller"> <content> <StackPane fx:id="infoPanelHost" maxHeight="-1.0" /> </content> @@ -111,24 +124,24 @@ <children> <HBox id="HBox" alignment="CENTER" spacing="0.0" VBox.vgrow="NEVER"> <children> - <Label maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" styleClass="panelTitle" text="Inspector" HBox.hgrow="NEVER" /> + <Label maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" styleClass="panelTitle" text="%inspector" HBox.hgrow="NEVER" /> <StackPane fx:id="inspectorSearchPanelHost" prefHeight="-1.0" prefWidth="-1.0" HBox.hgrow="ALWAYS" /> <MenuButton fx:id="InspectorMenu" contentDisplay="GRAPHIC_ONLY" mnemonicParsing="false" styleClass="panelMenuButton" text="" HBox.hgrow="NEVER"> <items> - <RadioMenuItem mnemonicParsing="false" onAction="#onInspectorShowAllAction" selected="true" text="Show All"> + <RadioMenuItem mnemonicParsing="false" onAction="#onInspectorShowAllAction" selected="true" text="%inspector.show.all"> <toggleGroup> <ToggleGroup fx:id="showTg" /> </toggleGroup> </RadioMenuItem> - <RadioMenuItem disable="false" mnemonicParsing="false" onAction="#onInspectorShowEditedAction" text="Show Edited" toggleGroup="$showTg" /> + <RadioMenuItem disable="false" mnemonicParsing="false" onAction="#onInspectorShowEditedAction" text="%inspector.show.edited" toggleGroup="$showTg" /> <SeparatorMenuItem mnemonicParsing="false" /> - <RadioMenuItem mnemonicParsing="false" onAction="#onInspectorViewSectionsAction" selected="true" text="View Sections"> + <RadioMenuItem mnemonicParsing="false" onAction="#onInspectorViewSectionsAction" selected="true" text="%inspector.view.sections"> <toggleGroup> <ToggleGroup fx:id="viewTg" /> </toggleGroup> </RadioMenuItem> - <RadioMenuItem mnemonicParsing="false" onAction="#onInspectorViewByPropertyNameAction" text="View by property name" toggleGroup="$viewTg" /> - <RadioMenuItem mnemonicParsing="false" onAction="#onInspectorViewByPropertyTypeAction" text="View by property type" toggleGroup="$viewTg" /> + <RadioMenuItem mnemonicParsing="false" onAction="#onInspectorViewByPropertyNameAction" text="%inspector.by.property.name" toggleGroup="$viewTg" /> + <RadioMenuItem mnemonicParsing="false" onAction="#onInspectorViewByPropertyTypeAction" text="%inspector.by.property.type" toggleGroup="$viewTg" /> </items> </MenuButton> </children> @@ -142,7 +155,7 @@ <children> <AnchorPane> <children> - <Label layoutX="0.0" layoutY="6.0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" styleClass="panelTitle" text="CSS Analyzer" /> + <Label layoutX="0.0" layoutY="6.0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" styleClass="panelTitle" text="%csspanel" /> <HBox id="HBox" alignment="CENTER" layoutY="0.0" spacing="5.0" AnchorPane.rightAnchor="0.0"> <children> <StackPane fx:id="cssPanelSearchPanelHost" prefHeight="-1.0" prefWidth="-1.0" /> @@ -161,8 +174,8 @@ </Menu> <SeparatorMenuItem mnemonicParsing="false" /> <MenuItem mnemonicParsing="false" onAction="#onCssPanelCopyStyleablePathAction" text="%csspanel.copy.path" /> - <MenuItem mnemonicParsing="false" onAction="#onCssPanelShowStyledOnlyAction" text="%csspanel.hide.default.values" fx:id="cssPanelShowStyledOnlyMi" /> - <MenuItem mnemonicParsing="false" onAction="#onCssPanelSplitDefaultsAction" text="%csspanel.defaults.split" fx:id="cssPanelSplitDefaultsMi" /> + <MenuItem fx:id="cssPanelShowStyledOnlyMi" mnemonicParsing="false" onAction="#onCssPanelShowStyledOnlyAction" text="%csspanel.hide.default.values" /> + <MenuItem fx:id="cssPanelSplitDefaultsMi" mnemonicParsing="false" onAction="#onCssPanelSplitDefaultsAction" text="%csspanel.defaults.split" /> </items> </MenuButton> </children>
--- a/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/DocumentWindowController.java Fri Dec 20 15:48:27 2013 -0800 +++ b/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/DocumentWindowController.java Mon Dec 23 13:59:52 2013 +0100 @@ -40,10 +40,13 @@ import com.oracle.javafx.scenebuilder.app.preferences.PreferencesRecordGlobal; import com.oracle.javafx.scenebuilder.app.preview.BackgroundColorDialogController; import com.oracle.javafx.scenebuilder.app.preview.PreviewWindowController; +import com.oracle.javafx.scenebuilder.app.report.JarAnalysisReportController; import com.oracle.javafx.scenebuilder.app.selectionbar.SelectionBarController; import com.oracle.javafx.scenebuilder.app.skeleton.SkeletonWindowController; import com.oracle.javafx.scenebuilder.app.template.FxmlTemplates; import com.oracle.javafx.scenebuilder.kit.editor.EditorController; +import com.oracle.javafx.scenebuilder.kit.editor.EditorController.ControlAction; +import com.oracle.javafx.scenebuilder.kit.editor.EditorController.EditAction; import com.oracle.javafx.scenebuilder.kit.editor.EditorPlatform; import com.oracle.javafx.scenebuilder.kit.editor.job.Job; import com.oracle.javafx.scenebuilder.kit.editor.panel.content.ContentPanelController; @@ -59,7 +62,12 @@ import com.oracle.javafx.scenebuilder.kit.editor.panel.util.dialog.AlertDialog; import com.oracle.javafx.scenebuilder.kit.editor.panel.util.dialog.ErrorDialog; import com.oracle.javafx.scenebuilder.kit.editor.search.SearchController; +import com.oracle.javafx.scenebuilder.kit.editor.selection.AbstractSelectionGroup; +import com.oracle.javafx.scenebuilder.kit.editor.selection.ObjectSelectionGroup; import com.oracle.javafx.scenebuilder.kit.fxom.FXOMDocument; +import com.oracle.javafx.scenebuilder.kit.fxom.FXOMObject; +import com.oracle.javafx.scenebuilder.kit.library.user.UserLibrary; +import com.sun.javafx.scene.control.behavior.KeyBinding; import java.io.File; import java.io.IOException; import java.io.UnsupportedEncodingException; @@ -71,19 +79,30 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.attribute.FileTime; +import java.util.ArrayList; import java.util.Comparator; +import java.util.List; import javafx.beans.InvalidationListener; import javafx.beans.Observable; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.event.ActionEvent; +import javafx.event.EventHandler; import javafx.fxml.FXML; import javafx.geometry.Insets; +import javafx.scene.Node; import javafx.scene.control.Accordion; import javafx.scene.control.CheckMenuItem; +import javafx.scene.control.MenuButton; +import javafx.scene.control.ComboBox; import javafx.scene.control.MenuItem; import javafx.scene.control.RadioMenuItem; import javafx.scene.control.SplitPane; +import javafx.scene.control.TextInputControl; +import javafx.scene.input.Clipboard; +import javafx.scene.input.KeyCode; +import javafx.scene.input.KeyCombination; +import javafx.scene.input.KeyEvent; import javafx.scene.layout.StackPane; import javafx.scene.layout.VBox; import javafx.stage.FileChooser; @@ -97,6 +116,9 @@ public enum DocumentControlAction { + COPY, + SELECT_ALL, + SELECT_NONE, SAVE_FILE, SAVE_AS_FILE, REVERT_FILE, @@ -112,6 +134,7 @@ TOGGLE_CSS_PANEL, TOGGLE_LEFT_PANEL, TOGGLE_RIGHT_PANEL, + TOGGLE_OUTLINES_VISIBILITY, TOGGLE_GUIDES_VISIBILITY, SHOW_PREVIEW_WINDOW, CHOOSE_BACKGROUND_COLOR, @@ -125,6 +148,11 @@ SHOW_SAMPLE_CONTROLLER } + public enum DocumentEditAction { + CUT, + PASTE + } + public enum ActionStatus { CANCELLED, DONE @@ -141,18 +169,20 @@ private final LibraryPanelController libraryPanelController = new LibraryPanelController(editorController); private final SelectionBarController selectionBarController = new SelectionBarController(editorController); private final MessageBarController messageBarController = new MessageBarController(editorController); - // The PreviewWindowController is created lazily because it needs an owner - // and computing it here would be too costly (impact on start-up time). - private PreviewWindowController previewWindowController = null; private final SearchController librarySearchController = new SearchController(editorController); private final SearchController inspectorSearchController = new SearchController(editorController); private final SearchController cssPanelSearchController = new SearchController(editorController);; private final SceneStyleSheetMenuController sceneStyleSheetMenuController = new SceneStyleSheetMenuController(this); private final CssPanelMenuController cssPanelMenuController = new CssPanelMenuController(cssPanelController); private final ResourceController resourceController = new ResourceController((this)); - // The SkeletonWindowController is created lazily because it needs an owner - // and computing it here would be too costly (impact on start-up time). + // The controller below are created lazily because they need an owner + // and computing them here would be too costly (impact on start-up time): + // - PreviewWindowController + // - SkeletonWindowController + // - JarAnalysisReportController + private PreviewWindowController previewWindowController = null; private SkeletonWindowController skeletonWindowController = null; + private JarAnalysisReportController jarAnalysisReportController = null; @FXML private StackPane libraryPanelHost; @FXML private StackPane librarySearchPanelHost; @@ -169,8 +199,11 @@ @FXML private SplitPane leftRightSplitPane; @FXML private SplitPane libraryDocumentSplitPane; + @FXML private MenuButton libraryMenuButton; + @FXML private MenuItem libraryImportSelection; @FXML private CheckMenuItem libraryViewAsList; @FXML private CheckMenuItem libraryViewAsSections; + @FXML private MenuItem libraryReveal; @FXML private MenuItem cssPanelShowStyledOnlyMi; @FXML private MenuItem cssPanelSplitDefaultsMi; @@ -188,6 +221,56 @@ private FileTime loadFileTime; private Job saveJob; + private final EventHandler<KeyEvent> mainKeyEventFilter = new EventHandler<KeyEvent>() { + + @Override + public void handle(KeyEvent event) { + //------------------------------------------------------------------ + // TEXT INPUT CONTROL + //------------------------------------------------------------------ + // Common editing actions handled natively and defined as application accelerators + // + // The platform support is not mature/stable enough to rely on. + // Indeed, the behavior may differ : + // - when using system menu bar vs not using it + // - when using accelerators vs using menu items + // - depending on the focused control (TextField vs ComboBox) + // + // On SB side, we decide for now to consume events that may be handled natively + // so ALL actions are defined in our ApplicationMenu class. + // + // This may be revisit when platform implementation will be more reliable. + // + final Node focusOwner = getScene().getFocusOwner(); + final KeyCombination accelerator = getAccelerator(event); + if (isTextInputControlEditing(focusOwner) == true + && accelerator != null) { + for (KeyBinding binding : SBTextInputControlBindings.getBindings()) { + // The event is handled natively + if (binding.getSpecificity(null, event) > 0) { + // + // When using system menu bar, the event is handled natively + // before the application receives it : we just consume the event + // so the editing action is not performed a second time by the app. + if (menuBarController.getMenuBar().isUseSystemMenuBar()) { + event.consume(); + } + break; + } + } + } + + // MenuItems define a single accelerator. + // BACK_SPACE key must be handled same way as DELETE key. + if (isTextInputControlEditing(focusOwner) == false + && KeyCode.BACK_SPACE.equals(event.getCode())) { + if (editorController.canPerformEditAction(EditAction.DELETE)) { + editorController.performEditAction(EditAction.DELETE); + } + } + } + }; + /* * DocumentWindowController */ @@ -336,6 +419,18 @@ final boolean result; switch(controlAction) { + case COPY: + result = canPerformCopy(); + break; + + case SELECT_ALL: + result = canPerformSelectAll(); + break; + + case SELECT_NONE: + result = canPerformSelectNone(); + break; + case PRINT_FILE: result = editorController.getFxomDocument() != null; break; @@ -345,6 +440,7 @@ case TOGGLE_CSS_PANEL: case TOGGLE_LEFT_PANEL: case TOGGLE_RIGHT_PANEL: + case TOGGLE_OUTLINES_VISIBILITY: case TOGGLE_GUIDES_VISIBILITY: case SHOW_PREVIEW_WINDOW: result = true; @@ -421,6 +517,18 @@ final PreferencesRecordDocument recordDocument = pc.getRecordDocument(this); switch(controlAction) { + case COPY: + performCopy(); + break; + + case SELECT_ALL: + performSelectAll(); + break; + + case SELECT_NONE: + performSelectNone(); + break; + case SHOW_PREVIEW_WINDOW: if (previewWindowController == null) { previewWindowController = new PreviewWindowController(editorController, getStage()); @@ -516,6 +624,11 @@ recordDocument.setDocumentVisible(documentSplitController.isTargetVisible()); break; + case TOGGLE_OUTLINES_VISIBILITY: + contentPanelController.setOutlinesVisible( + ! contentPanelController.isOutlinesVisible()); + break; + case TOGGLE_GUIDES_VISIBILITY: contentPanelController.setGuidesVisible( ! contentPanelController.isGuidesVisible()); @@ -559,7 +672,45 @@ } } + public boolean canPerformEditAction(DocumentEditAction editAction) { + final boolean result; + + switch(editAction) { + case CUT: + result = canPerformCut(); + break; + + case PASTE: + result = canPerformPaste(); + break; + + default: + result = false; + assert false; + break; + } + + return result; + } + public void performEditAction(DocumentEditAction editAction) { + assert canPerformEditAction(editAction); + + switch(editAction) { + case CUT: + performCut(); + break; + + case PASTE: + performPaste(); + break; + + default: + assert false; + break; + } + } + public boolean isLeftPanelVisible() { return leftSplitController.isTargetVisible(); } @@ -632,6 +783,13 @@ assert libraryDocumentSplitPane.getItems().size() == 2; assert documentAccordion != null; assert documentAccordion.getPanes().isEmpty() == false; + assert libraryViewAsList != null; + assert libraryViewAsSections != null; + assert libraryReveal != null; + assert libraryMenuButton != null; + assert libraryImportSelection != null; + + mainSplitPane.addEventFilter(KeyEvent.KEY_PRESSED, mainKeyEventFilter); // Insert the menu bar assert getRoot() instanceof VBox; @@ -708,6 +866,37 @@ messageBarController.setDocumentDirty(currentJob != saveJob); } }); + + // Setup title of the Library Reveal menu item according the underlying o/s. + final String revealMenuKey; + if (EditorPlatform.IS_MAC) { + revealMenuKey = "menu.title.reveal.mac"; + } else if (EditorPlatform.IS_WINDOWS) { + revealMenuKey = "menu.title.reveal.win"; + } else { + assert EditorPlatform.IS_LINUX; + revealMenuKey = "menu.title.reveal.linux"; + } + libraryReveal.setText(I18N.getString(revealMenuKey)); + + // We need to tune the content of the library menu according if there's + // or not a selection likely to be dropped onto Library panel. + libraryMenuButton.showingProperty().addListener(new ChangeListener<Boolean>() { + + @Override + public void changed(ObservableValue<? extends Boolean> ov, Boolean t, Boolean t1) { + if (t1) { + AbstractSelectionGroup asg = getEditorController().getSelection().getGroup(); + libraryImportSelection.setDisable(true); + + if (asg != null && asg instanceof ObjectSelectionGroup) { + if (((ObjectSelectionGroup)asg).getItems().size() >= 1) { + libraryImportSelection.setDisable(false); + } + } + } + } + }); } @Override @@ -723,7 +912,8 @@ public boolean isFrontDocumentWindow() { return getStage().isFocused() || (previewWindowController != null && previewWindowController.getStage().isFocused()) - || (skeletonWindowController != null && skeletonWindowController.getStage().isFocused()); + || (skeletonWindowController != null && skeletonWindowController.getStage().isFocused()) + || (jarAnalysisReportController != null && jarAnalysisReportController.getStage().isFocused()); } public void performCloseFrontDocumentWindow() { @@ -735,6 +925,9 @@ } else if (skeletonWindowController != null && skeletonWindowController.getStage().isFocused()) { skeletonWindowController.closeWindow(); + } else if (jarAnalysisReportController != null + && jarAnalysisReportController.getStage().isFocused()) { + jarAnalysisReportController.closeWindow(); } } @@ -807,17 +1000,19 @@ @FXML void onHierarchyShowInfo(ActionEvent event) { hierarchyPanelController.setDisplayOption(AbstractHierarchyPanelController.DisplayOption.INFO); - + documentAccordion.setExpandedPane(documentAccordion.getPanes().get(0)); } @FXML void onHierarchyShowFxId(ActionEvent event) { hierarchyPanelController.setDisplayOption(AbstractHierarchyPanelController.DisplayOption.FXID); + documentAccordion.setExpandedPane(documentAccordion.getPanes().get(0)); } @FXML void onHierarchyShowNodeId(ActionEvent event) { hierarchyPanelController.setDisplayOption(AbstractHierarchyPanelController.DisplayOption.NODEID); + documentAccordion.setExpandedPane(documentAccordion.getPanes().get(0)); } // @@ -842,15 +1037,195 @@ libraryPanelController.setDisplayMode(LibraryPanelController.DISPLAY_MODE.SECTIONS); } + // This method cannot be called if there is not a valid selection, a selection + // eligible for being dropped onto Library panel. @FXML void onLibraryImportSelection(ActionEvent event) { - System.out.println("[DocumentWindowController::onLibraryImportSelection] Not yet available"); //NOI18N + AbstractSelectionGroup asg = getEditorController().getSelection().getGroup(); + + if (asg != null && asg instanceof ObjectSelectionGroup) { + ObjectSelectionGroup osg = (ObjectSelectionGroup)asg; + + if (osg.getItems().size() >= 1) { + List<FXOMObject> selection = new ArrayList<FXOMObject>(osg.getItems()); + libraryPanelController.performImportSelection(selection); + } + } + } + + @FXML + void onLibraryRevealCustomFolder(ActionEvent event) { + String userLibraryPath = ((UserLibrary) getEditorController().getLibrary()).getPath(); + try { + EditorPlatform.revealInFileBrowser(new File(userLibraryPath)); + } catch(IOException x) { + final ErrorDialog errorDialog = new ErrorDialog(null); + errorDialog.setMessage(I18N.getString("alert.reveal.failure.message", getStage().getTitle())); + errorDialog.setDetails(I18N.getString("alert.reveal.failure.details")); + errorDialog.setDebugInfoWithThrowable(x); + errorDialog.showAndWait(); + } + } + + @FXML + void onLibraryShowJarAnalysisReport(ActionEvent event) { + if (jarAnalysisReportController == null) { + jarAnalysisReportController = new JarAnalysisReportController(getEditorController(), getStage()); + } + + jarAnalysisReportController.openWindow(); } /* * Private */ + + private boolean canPerformCopy() { + boolean result; + final Node focusOwner = this.getScene().getFocusOwner(); + if (isTextInputControlEditing(focusOwner)) { + final TextInputControl tic = getTextInputControl(focusOwner); + result = tic.getSelectedText() != null && tic.getSelectedText().isEmpty() == false; + } else { + result = getEditorController().canPerformControlAction(ControlAction.COPY); + } + return result; + } + + private void performCopy() { + final Node focusOwner = this.getScene().getFocusOwner(); + if (isTextInputControlEditing(focusOwner)) { + final TextInputControl tic = getTextInputControl(focusOwner); + tic.copy(); + } else { + this.getEditorController().performControlAction(ControlAction.COPY); + } + } + + private boolean canPerformSelectAll() { + boolean result; + final Node focusOwner = this.getScene().getFocusOwner(); + if (isTextInputControlEditing(focusOwner)) { + final TextInputControl tic = getTextInputControl(focusOwner); + result = tic.getText() != null && tic.getText().isEmpty() == false; + final String selectedText = tic.getSelectedText(); + // Check if the TextInputControl is not already ALL selected + if (selectedText != null && selectedText.length() == tic.getText().length()) { + result = false; + } + } else { + result = getEditorController().canPerformControlAction(ControlAction.SELECT_ALL); + } + return result; + } + + private void performSelectAll() { + final Node focusOwner = this.getScene().getFocusOwner(); + if (isTextInputControlEditing(focusOwner)) { + final TextInputControl tic = getTextInputControl(focusOwner); + tic.selectAll(); + } else { + this.getEditorController().performControlAction(ControlAction.SELECT_ALL); + } + } + + private boolean canPerformSelectNone() { + boolean result; + final Node focusOwner = this.getScene().getFocusOwner(); + if (isTextInputControlEditing(focusOwner)) { + final TextInputControl tic = getTextInputControl(focusOwner); + result = tic.getSelectedText() != null && tic.getSelectedText().isEmpty() == false; + } else { + result = getEditorController().canPerformControlAction(ControlAction.SELECT_NONE); + } + return result; + } + + private void performSelectNone() { + final Node focusOwner = this.getScene().getFocusOwner(); + if (isTextInputControlEditing(focusOwner)) { + final TextInputControl tic = getTextInputControl(focusOwner); + tic.deselect(); + } else { + this.getEditorController().performControlAction(ControlAction.SELECT_NONE); + } + } + private boolean canPerformCut() { + boolean result; + final Node focusOwner = this.getScene().getFocusOwner(); + if (isTextInputControlEditing(focusOwner)) { + final TextInputControl tic = getTextInputControl(focusOwner); + result = tic.getSelectedText() != null && tic.getSelectedText().isEmpty() == false; + } else { + result = getEditorController().canPerformEditAction(EditAction.CUT); + } + return result; + } + + private void performCut() { + final Node focusOwner = this.getScene().getFocusOwner(); + if (isTextInputControlEditing(focusOwner)) { + final TextInputControl tic = getTextInputControl(focusOwner); + tic.cut(); + } else { + this.getEditorController().performEditAction(EditAction.CUT); + } + } + + private boolean canPerformPaste() { + boolean result; + final Node focusOwner = this.getScene().getFocusOwner(); + if (isTextInputControlEditing(focusOwner)) { + result = Clipboard.getSystemClipboard().hasString(); + } else { + result = getEditorController().canPerformEditAction(EditAction.PASTE); + } + return result; + } + + private void performPaste() { + final Node focusOwner = this.getScene().getFocusOwner(); + if (isTextInputControlEditing(focusOwner)) { + final TextInputControl tic = getTextInputControl(focusOwner); + tic.paste(); + } else { + this.getEditorController().performEditAction(EditAction.PASTE); + } + } + + /** + * Returns true if the specified node is either a TextInputControl or a ComboBox. + */ + private boolean isTextInputControlEditing(Node node) { + return (node instanceof TextInputControl + || node instanceof ComboBox); + } + + private TextInputControl getTextInputControl(Node node) { + assert isTextInputControlEditing(node); + final TextInputControl tic; + if (node instanceof TextInputControl) { + tic = (TextInputControl) node; + } else { + assert node instanceof ComboBox; + final ComboBox<?> cb = (ComboBox<?>) node; + tic = cb.getEditor(); + } + return tic; + } + + private KeyCombination getAccelerator(final KeyEvent event) { + KeyCombination result = null; + for (KeyCombination kc : menuBarController.getAccelerators()) { + if (kc.match(event)) { + result = kc; + break; + } + } + return result; + } + private void updateStageTitle() { getStage().setTitle(makeTitle(editorController.getFxomDocument())); } @@ -1207,3 +1582,18 @@ } } } + +/** + * This class setup key bindings for the TextInputControl type classes and + * provide a way to access the key binding list. + */ +class SBTextInputControlBindings extends com.sun.javafx.scene.control.behavior.TextInputControlBindings { + + private SBTextInputControlBindings() { + assert false; + } + + public static List<KeyBinding> getBindings() { + return BINDINGS; + } +}
--- a/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/i18n/SceneBuilderApp.properties Fri Dec 20 15:48:27 2013 -0800 +++ b/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/i18n/SceneBuilderApp.properties Mon Dec 23 13:59:52 2013 +0100 @@ -133,7 +133,11 @@ menu.title.choose.background.color = Choose Background Color\u2026 menu.title.theme = JavaFX Theme menu.title.theme.modena = Modena (JavaFX 8) +menu.title.theme.modena.touch = Modena Touch (JavaFX 8) menu.title.theme.caspian = Caspian (JavaFX 2) +menu.title.theme.caspian.embedded = Caspian Embedded (JavaFX 2) +menu.title.theme.caspian.embedded.qvga = Caspian Embedded QVGA (JavaFX 2) +menu.title.theme.caspian.high.contrast = High Contrast, for Caspian only (JavaFX 2) menu.title.scene.stylesheets = Scene Style Sheets menu.title.add.stylesheet = Add a Style Sheet\u2026 menu.title.remove.stylesheet = Remove a Style Sheet @@ -151,10 +155,34 @@ menu.title.scene.builder.help = Scene Builder Help menu.title.about = About Scene Builder +# ----------------------------------------------------------------------------- +# Document +# ----------------------------------------------------------------------------- +document = Document # ----------------------------------------------------------------------------- -# Document Window +# Hierarchy # ----------------------------------------------------------------------------- +hierarchy = Hierarchy +hierarchy.displays = Hierarchy displays +hierarchy.show.info = Info +hierarchy.show.fxid = fx:id +hierarchy.show.nodeid = Node Id + +# ----------------------------------------------------------------------------- +# Controller +# ----------------------------------------------------------------------------- +controller = Controller + +# ----------------------------------------------------------------------------- +# Inspector +# ----------------------------------------------------------------------------- +inspector = Inspector +inspector.show.all = Show All +inspector.show.edited = Show Edited +inspector.view.sections = View Sections +inspector.by.property.name = View by property name +inspector.by.property.type = View by property type # ----------------------------------------------------------------------------- # Preferences Window @@ -178,7 +206,6 @@ # ----------------------------------------------------------------------------- # Preview Window # ----------------------------------------------------------------------------- -preview.constructing = Constructing Preview content ... preview.background.color = Background Color preview.no.document = No document preview.not.node = Not a Node @@ -203,10 +230,10 @@ # ----------------------------------------------------------------------------- # Library Menu within Library panel # ----------------------------------------------------------------------------- -# Import of FXML file is not yet ready +library = Library library.panel.menu.import.jar.fxml = Import JAR/FXML file +library.panel.menu.import.selection = Import Selection # Messages below are temporarily unused -#library.panel.menu.import.selection = Import Selection #library.panel.menu.category.view = View Library Category #library.panel.menu.category.create = Create Library Category #library.panel.menu.category.remove = Remove Library Category @@ -215,6 +242,8 @@ #library.panel.menu.item.remove = Remove Custom Item library.panel.menu.view.list = View as List library.panel.menu.view.sections = View as Sections +library.panel.menu.custom = Custom Library Folder +library.panel.menu.custom.report = Show JAR Analysis Report # ----------------------------------------------------------------------------- # About Window @@ -323,6 +352,7 @@ # ----------------------------------------------------------------------------- # CSS Panel # ----------------------------------------------------------------------------- +csspanel = CSS Analyzer csspanel.copy.path = Copy Styleable Path csspanel.rules = Rules csspanel.show.default.values = Show Properties with Default Values @@ -339,4 +369,13 @@ skeleton.add.comments = Comments skeleton.format.full = Full # Parameter is a fxml file name -skeleton.window.title = Sample Skeleton for ''{0}'' Controller Class \ No newline at end of file +skeleton.window.title = Sample Skeleton for ''{0}'' Controller Class + +# ----------------------------------------------------------------------------- +# JAR Analysis Report dialog +# ----------------------------------------------------------------------------- +# The parameter is a time stamp +jar.analysis.report.timestamp = Analysis done on {0} +jar.analysis.report.title = JAR Analysis Report +jar.analysis.exception = Exception for: +jar.analysis.not.node = Not a Node:
--- a/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/menubar/MenuBar.fxml Fri Dec 20 15:48:27 2013 -0800 +++ b/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/menubar/MenuBar.fxml Mon Dec 23 13:59:52 2013 +0100 @@ -31,207 +31,209 @@ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --> - <?import java.lang.*?> <?import javafx.scene.control.*?> <?import javafx.scene.layout.*?> <?scenebuilder-preview-i18n-resource ../i18n/SceneBuilderApp.properties?> -<StackPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"> - <children> - <MenuBar fx:id="menuBar"> - <menus> - <Menu fx:id="fileMenu" mnemonicParsing="false" text="%menu.title.file"> - <items> - <MenuItem fx:id="newMenuItem" mnemonicParsing="false" text="%menu.title.new" /> - <Menu fx:id="newTemplateMenuItem" mnemonicParsing="false" text="%menu.title.new.template"> - <items> - <MenuItem fx:id="newAlertDialogMenuItem" mnemonicParsing="false" text="%menu.title.new.alert.dialog" /> - <MenuItem fx:id="newBasicAppMenuItem" mnemonicParsing="false" text="%menu.title.new.basic.app" /> - <MenuItem fx:id="newComplexAppMenuItem" mnemonicParsing="false" text="%menu.title.new.complex.app" /> - <SeparatorMenuItem mnemonicParsing="false" /> - <MenuItem fx:id="newAlertDialogCssMenuItem" mnemonicParsing="false" text="%menu.title.new.alert.dialog.css" /> - <MenuItem fx:id="newAlertDialogI18nMenuItem" mnemonicParsing="false" text="%menu.title.new.alert.dialog.i18n" /> - <MenuItem fx:id="newBasicAppCssMenuItem" mnemonicParsing="false" text="%menu.title.new.basic.app.css" /> - <MenuItem fx:id="newBasicAppI18nMenuItem" mnemonicParsing="false" text="%menu.title.new.basic.app.i18n" /> - <MenuItem fx:id="newComplexAppCssMenuItem" mnemonicParsing="false" text="%menu.title.new.complex.app.css" /> - <MenuItem fx:id="newComplexAppI18nMenuItem" mnemonicParsing="false" text="%menu.title.new.complex.app.i18n" /> - </items> - </Menu> - <SeparatorMenuItem mnemonicParsing="false" /> - <MenuItem fx:id="openMenuItem" mnemonicParsing="false" text="%menu.title.open" /> - <Menu fx:id="openRecentMenu" mnemonicParsing="false" text="%menu.title.open.recent" > - <items> - <MenuItem mnemonicParsing="false" text="Action 1" /> - </items> - </Menu> - <SeparatorMenuItem mnemonicParsing="false" /> - <MenuItem fx:id="saveMenuItem" mnemonicParsing="false" text="%menu.title.save" /> - <MenuItem fx:id="saveAsMenuItem" mnemonicParsing="false" text="%menu.title.save.as" /> - <MenuItem fx:id="revertMenuItem" mnemonicParsing="false" text="%menu.title.revert" /> - <SeparatorMenuItem mnemonicParsing="false" /> - <MenuItem fx:id="revealMenuItem" mnemonicParsing="false" text="Reveal (setup at runtime)" /> - <SeparatorMenuItem mnemonicParsing="false" /> - <MenuItem fx:id="closeMenuItem" mnemonicParsing="false" text="%menu.title.close" /> - <SeparatorMenuItem fx:id="separatorAbovePreferencesMenuItem" mnemonicParsing="false" /> - <MenuItem fx:id="showPreferencesMenuItem" mnemonicParsing="false" text="%menu.title.preferences" /> - <MenuItem fx:id="exitMenuItem" mnemonicParsing="false" text="%menu.title.quit" /> - </items> +<StackPane xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2"> + <children> + <MenuBar fx:id="menuBar"> + <menus> + <Menu mnemonicParsing="false" text="%menu.title.file" fx:id="fileMenu"> + <items> + <MenuItem mnemonicParsing="false" text="%menu.title.new" fx:id="newMenuItem" /> + <Menu mnemonicParsing="false" text="%menu.title.new.template" fx:id="newTemplateMenuItem"> + <items> + <MenuItem mnemonicParsing="false" text="%menu.title.new.alert.dialog" fx:id="newAlertDialogMenuItem" /> + <MenuItem mnemonicParsing="false" text="%menu.title.new.basic.app" fx:id="newBasicAppMenuItem" /> + <MenuItem mnemonicParsing="false" text="%menu.title.new.complex.app" fx:id="newComplexAppMenuItem" /> + <SeparatorMenuItem mnemonicParsing="false" /> + <MenuItem mnemonicParsing="false" text="%menu.title.new.alert.dialog.css" fx:id="newAlertDialogCssMenuItem" /> + <MenuItem mnemonicParsing="false" text="%menu.title.new.alert.dialog.i18n" fx:id="newAlertDialogI18nMenuItem" /> + <MenuItem mnemonicParsing="false" text="%menu.title.new.basic.app.css" fx:id="newBasicAppCssMenuItem" /> + <MenuItem mnemonicParsing="false" text="%menu.title.new.basic.app.i18n" fx:id="newBasicAppI18nMenuItem" /> + <MenuItem mnemonicParsing="false" text="%menu.title.new.complex.app.css" fx:id="newComplexAppCssMenuItem" /> + <MenuItem mnemonicParsing="false" text="%menu.title.new.complex.app.i18n" fx:id="newComplexAppI18nMenuItem" /> + </items> + </Menu> + <SeparatorMenuItem mnemonicParsing="false" /> + <MenuItem mnemonicParsing="false" text="%menu.title.open" fx:id="openMenuItem" /> + <Menu mnemonicParsing="false" text="%menu.title.open.recent" fx:id="openRecentMenu"> + <items> + <MenuItem mnemonicParsing="false" text="Action 1" /> + </items> + </Menu> + <SeparatorMenuItem mnemonicParsing="false" /> + <MenuItem mnemonicParsing="false" text="%menu.title.save" fx:id="saveMenuItem" /> + <MenuItem mnemonicParsing="false" text="%menu.title.save.as" fx:id="saveAsMenuItem" /> + <MenuItem mnemonicParsing="false" text="%menu.title.revert" fx:id="revertMenuItem" /> + <SeparatorMenuItem mnemonicParsing="false" /> + <MenuItem mnemonicParsing="false" text="Reveal (setup at runtime)" fx:id="revealMenuItem" /> + <SeparatorMenuItem mnemonicParsing="false" /> + <MenuItem mnemonicParsing="false" text="%menu.title.close" fx:id="closeMenuItem" /> + <SeparatorMenuItem mnemonicParsing="false" fx:id="separatorAbovePreferencesMenuItem" /> + <MenuItem mnemonicParsing="false" text="%menu.title.preferences" fx:id="showPreferencesMenuItem" /> + <MenuItem mnemonicParsing="false" text="%menu.title.quit" fx:id="exitMenuItem" /> + </items> + </Menu> + <Menu mnemonicParsing="false" text="%menu.title.edit"> + <items> + <MenuItem mnemonicParsing="false" text="%menu.title.undo" fx:id="undoMenuItem" /> + <MenuItem mnemonicParsing="false" text="%menu.title.redo" fx:id="redoMenuItem" /> + <SeparatorMenuItem mnemonicParsing="false" /> + <MenuItem mnemonicParsing="false" text="%menu.title.cut" fx:id="cutMenuItem" /> + <MenuItem mnemonicParsing="false" text="%menu.title.copy" fx:id="copyMenuItem" /> + <MenuItem mnemonicParsing="false" text="%menu.title.paste" fx:id="pasteMenuItem" /> + <MenuItem mnemonicParsing="false" text="%menu.title.paste.into" fx:id="pasteIntoMenuItem" /> + <MenuItem mnemonicParsing="false" text="%menu.title.duplicate" fx:id="duplicateMenuItem" /> + <MenuItem mnemonicParsing="false" text="%menu.title.delete" fx:id="deleteMenuItem" /> + <SeparatorMenuItem mnemonicParsing="false" /> + <MenuItem mnemonicParsing="false" text="%menu.title.select.all" fx:id="selectAllMenuItem" /> + <MenuItem mnemonicParsing="false" text="%menu.title.select.none" fx:id="selectNoneMenuItem" /> + <MenuItem mnemonicParsing="false" text="%menu.title.select.parent" fx:id="selectParentMenuItem" /> + <MenuItem mnemonicParsing="false" text="%menu.title.select.next" fx:id="selectNextMenuItem" /> + <MenuItem mnemonicParsing="false" text="%menu.title.select.previous" fx:id="selectPreviousMenuItem" /> + <SeparatorMenuItem mnemonicParsing="false" /> + <MenuItem mnemonicParsing="false" text="%menu.title.trim" fx:id="trimMenuItem" /> + </items> + </Menu> + <Menu mnemonicParsing="false" text="%menu.title.view"> + <items> + <MenuItem mnemonicParsing="false" text="%menu.title.content" fx:id="gotoContentMenuItem" /> + <MenuItem mnemonicParsing="false" text="%menu.title.properties" fx:id="gotoPropertiesMenuItem" /> + <MenuItem mnemonicParsing="false" text="%menu.title.layout" fx:id="gotoLayoutMenuItem" /> + <MenuItem mnemonicParsing="false" text="%menu.title.code" fx:id="gotoCodeMenuItem" /> + <SeparatorMenuItem mnemonicParsing="false" /> + <MenuItem mnemonicParsing="false" text="%menu.title.hide.library.panel" fx:id="toggleLibraryPanelMenuItem" /> + <MenuItem mnemonicParsing="false" text="%menu.title.hide.document.panel" fx:id="toggleHierarchyPanelMenuItem" /> + <SeparatorMenuItem mnemonicParsing="false" /> + <MenuItem mnemonicParsing="false" text="%menu.title.show.bottom.panel" fx:id="toggleCSSPanelMenuItem" /> + <SeparatorMenuItem mnemonicParsing="false" /> + <MenuItem mnemonicParsing="false" text="%menu.title.hide.left.panel" fx:id="toggleLeftPanelMenuItem" /> + <MenuItem mnemonicParsing="false" text="%menu.title.hide.right.panel" fx:id="toggleRightPanelMenuItem" /> + <SeparatorMenuItem mnemonicParsing="false" /> + <MenuItem mnemonicParsing="false" text="%menu.title.show.outlines" fx:id="toggleOutlinesMenuItem" /> + <MenuItem mnemonicParsing="false" text="%menu.title.show.sample.data" fx:id="toggleSampleDataMenuItem" /> + <MenuItem mnemonicParsing="false" text="%menu.title.disable.guides" fx:id="toggleAlignmentGuidesMenuItem" /> + <SeparatorMenuItem mnemonicParsing="false" /> + <Menu mnemonicParsing="false" text="%menu.title.zoom" fx:id="zoomMenu" /> + <SeparatorMenuItem mnemonicParsing="false" /> + <MenuItem mnemonicParsing="false" text="%menu.title.show.sample.controller.skeleton" fx:id="showSampleControllerMenuItem" /> + </items> + </Menu> + <Menu mnemonicParsing="false" text="%menu.title.insert" fx:id="insertMenu" /> + <Menu mnemonicParsing="false" text="%menu.title.modify"> + <items> + <MenuItem mnemonicParsing="false" text="%menu.title.fit" fx:id="fitToParentMenuItem" /> + <MenuItem mnemonicParsing="false" text="%menu.title.use.computed.sizes" fx:id="useComputedSizesMenuItem" /> + <SeparatorMenuItem mnemonicParsing="false" /> + <Menu mnemonicParsing="false" text="%menu.title.grid"> + <items> + <MenuItem mnemonicParsing="false" text="%menu.title.grid.move.row.above" fx:id="moveRowAboveMenuItem" /> + <MenuItem mnemonicParsing="false" text="%menu.title.grid.move.row.below" fx:id="moveRowBelowMenuItem" /> + <MenuItem mnemonicParsing="false" text="%menu.title.grid.move.column.before" fx:id="moveColumnBeforeMenuItem" /> + <MenuItem mnemonicParsing="false" text="%menu.title.grid.move.column.after" fx:id="moveColumnAfterMenuItem" /> + <SeparatorMenuItem mnemonicParsing="false" /> + <MenuItem mnemonicParsing="false" text="%menu.title.grid.add.row.above" fx:id="addRowAboveMenuItem" /> + <MenuItem mnemonicParsing="false" text="%menu.title.grid.add.row.below" fx:id="addRowBelowMenuItem" /> + <MenuItem mnemonicParsing="false" text="%menu.title.grid.add.column.before" fx:id="addColumnBeforeMenuItem" /> + <MenuItem mnemonicParsing="false" text="%menu.title.grid.add.column.after" fx:id="addColumnAfterMenuItem" /> + <SeparatorMenuItem mnemonicParsing="false" /> + <MenuItem mnemonicParsing="false" text="%menu.title.grid.increase.row.span" fx:id="increaseRowSpanMenuItem" /> + <MenuItem mnemonicParsing="false" text="%menu.title.grid.decrease.row.span" fx:id="decreaseRowSpanMenuItem" /> + <MenuItem mnemonicParsing="false" text="%menu.title.grid.increase.column.span" fx:id="increaseColumnSpanMenuItem" /> + <MenuItem mnemonicParsing="false" text="%menu.title.grid.decrease.column.span" fx:id="decreaseColumnSpanMenuItem" /> + </items> + </Menu> + <SeparatorMenuItem mnemonicParsing="false" /> + <Menu mnemonicParsing="false" text="%menu.title.add.effect" fx:id="addEffectMenu" /> + <Menu mnemonicParsing="false" text="%menu.title.add.popup" fx:id="addPopupControlMenu" /> + <SeparatorMenuItem mnemonicParsing="false" /> + <MenuItem mnemonicParsing="false" text="%menu.title.edit.included.default" fx:id="editIncludedFileMenuItem" /> + <MenuItem mnemonicParsing="false" text="%menu.title.reveal.included.default" fx:id="revealIncludedFileMenuItem" /> + </items> + </Menu> + <Menu mnemonicParsing="false" text="%menu.title.arrange"> + <items> + <MenuItem mnemonicParsing="false" text="%menu.title.front" fx:id="bringToFrontMenuItem" /> + <MenuItem mnemonicParsing="false" text="%menu.title.back" fx:id="sendToBackMenuItem" /> + <MenuItem mnemonicParsing="false" text="%menu.title.forward" fx:id="bringForwardMenuItem" /> + <MenuItem mnemonicParsing="false" text="%menu.title.backward" fx:id="sendBackwardMenuItem" /> + <SeparatorMenuItem mnemonicParsing="false" /> + <Menu mnemonicParsing="false" text="%menu.title.wrap"> + <items> + <MenuItem mnemonicParsing="false" text="AnchorPane" fx:id="wrapInAnchorPaneMenuItem" /> + <MenuItem mnemonicParsing="false" text="GridPane" fx:id="wrapInGridPaneMenuItem" /> + <MenuItem mnemonicParsing="false" text="HBox" fx:id="wrapInHBoxMenuItem" /> + <MenuItem mnemonicParsing="false" text="Pane" fx:id="wrapInPaneMenuItem" /> + <MenuItem mnemonicParsing="false" text="ScrollPane" fx:id="wrapInScrollPaneMenuItem" /> + <MenuItem mnemonicParsing="false" text="SplitPane" fx:id="wrapInSplitPaneMenuItem" /> + <MenuItem mnemonicParsing="false" text="StackPane" fx:id="wrapInStackPaneMenuItem" /> + <MenuItem mnemonicParsing="false" text="TabPane" fx:id="wrapInTabPaneMenuItem" /> + <MenuItem mnemonicParsing="false" text="TitledPane" fx:id="wrapInTitledPaneMenuItem" /> + <MenuItem mnemonicParsing="false" text="ToolBar" fx:id="wrapInToolBarMenuItem" /> + <MenuItem mnemonicParsing="false" text="VBox" fx:id="wrapInVBoxMenuItem" /> + <MenuItem mnemonicParsing="false" text="Group" fx:id="wrapInGroupMenuItem" /> + </items> + </Menu> + <MenuItem mnemonicParsing="false" text="%menu.title.unwrap" fx:id="unwrapMenuItem" /> + </items> + </Menu> + <Menu mnemonicParsing="false" text="%menu.title.preview"> + <items> + <MenuItem mnemonicParsing="false" text="%menu.title.show.preview" fx:id="showPreviewMenuItem" /> + <SeparatorMenuItem mnemonicParsing="false" /> + <MenuItem mnemonicParsing="false" text="%menu.title.choose.background.color" fx:id="chooseBackgroundColorMenuItem" /> + <SeparatorMenuItem mnemonicParsing="false" /> + <Menu mnemonicParsing="false" text="%menu.title.theme"> + <items> + <RadioMenuItem mnemonicParsing="false" text="%menu.title.theme.modena" fx:id="modenaThemeMenuItem" /> + <RadioMenuItem mnemonicParsing="false" text="%menu.title.theme.modena.touch" fx:id="modenaTouchThemeMenuItem" /> + <SeparatorMenuItem mnemonicParsing="false" /> + <RadioMenuItem mnemonicParsing="false" text="%menu.title.theme.caspian" fx:id="caspianThemeMenuItem" /> + <RadioMenuItem mnemonicParsing="false" text="%menu.title.theme.caspian.embedded" fx:id="caspianEmbeddedThemeMenuItem" /> + <RadioMenuItem mnemonicParsing="false" text="%menu.title.theme.caspian.embedded.qvga" fx:id="caspianEmbeddedQVGAThemeMenuItem" /> + <SeparatorMenuItem mnemonicParsing="false" /> + <CheckMenuItem mnemonicParsing="false" text="%menu.title.theme.caspian.high.contrast" fx:id="caspianHighContrastThemeMenuItem"/> + </items> + </Menu> + <Menu mnemonicParsing="false" text="%menu.title.scene.stylesheets"> + <items> + <MenuItem mnemonicParsing="false" text="%menu.title.add.stylesheet" fx:id="addSceneStyleSheetMenuItem" /> + <Menu mnemonicParsing="false" text="%menu.title.remove.stylesheet" fx:id="removeSceneStyleSheetMenu"> + <items> + <MenuItem disable="true" mnemonicParsing="false" text="%scenestylesheet.none" /> + </items> </Menu> - <Menu mnemonicParsing="false" text="%menu.title.edit"> - <items> - <MenuItem fx:id="undoMenuItem" mnemonicParsing="false" text="%menu.title.undo" /> - <MenuItem fx:id="redoMenuItem" mnemonicParsing="false" text="%menu.title.redo" /> - <SeparatorMenuItem mnemonicParsing="false" /> - <MenuItem fx:id="cutMenuItem" mnemonicParsing="false" text="%menu.title.cut" /> - <MenuItem fx:id="copyMenuItem" mnemonicParsing="false" text="%menu.title.copy" /> - <MenuItem fx:id="pasteMenuItem" mnemonicParsing="false" text="%menu.title.paste" /> - <MenuItem fx:id="pasteIntoMenuItem" mnemonicParsing="false" text="%menu.title.paste.into" /> - <MenuItem fx:id="duplicateMenuItem" mnemonicParsing="false" text="%menu.title.duplicate" /> - <MenuItem fx:id="deleteMenuItem" mnemonicParsing="false" text="%menu.title.delete" /> - <SeparatorMenuItem mnemonicParsing="false" /> - <MenuItem fx:id="selectAllMenuItem" mnemonicParsing="false" text="%menu.title.select.all" /> - <MenuItem fx:id="selectNoneMenuItem" mnemonicParsing="false" text="%menu.title.select.none" /> - <MenuItem fx:id="selectParentMenuItem" mnemonicParsing="false" text="%menu.title.select.parent" /> - <MenuItem fx:id="selectNextMenuItem" mnemonicParsing="false" text="%menu.title.select.next" /> - <MenuItem fx:id="selectPreviousMenuItem" mnemonicParsing="false" text="%menu.title.select.previous" /> - <SeparatorMenuItem mnemonicParsing="false" /> - <MenuItem fx:id="trimMenuItem" mnemonicParsing="false" text="%menu.title.trim" /> - </items> + <Menu mnemonicParsing="false" text="%menu.title.open.stylesheet" fx:id="openSceneStyleSheetMenu"> + <items> + <MenuItem disable="true" mnemonicParsing="false" text="%scenestylesheet.none" /> + </items> </Menu> - <Menu mnemonicParsing="false" text="%menu.title.view"> - <items> - <MenuItem fx:id="gotoContentMenuItem" mnemonicParsing="false" text="%menu.title.content" /> - <MenuItem fx:id="gotoPropertiesMenuItem" mnemonicParsing="false" text="%menu.title.properties" /> - <MenuItem fx:id="gotoLayoutMenuItem" mnemonicParsing="false" text="%menu.title.layout" /> - <MenuItem fx:id="gotoCodeMenuItem" mnemonicParsing="false" text="%menu.title.code" /> - <SeparatorMenuItem mnemonicParsing="false" /> - <MenuItem fx:id="toggleLibraryPanelMenuItem" mnemonicParsing="false" text="%menu.title.hide.library.panel" /> - <MenuItem fx:id="toggleHierarchyPanelMenuItem" mnemonicParsing="false" text="%menu.title.hide.document.panel" /> - <SeparatorMenuItem mnemonicParsing="false" /> - <MenuItem fx:id="toggleCSSPanelMenuItem" mnemonicParsing="false" text="%menu.title.show.bottom.panel" /> - <SeparatorMenuItem mnemonicParsing="false" /> - <MenuItem fx:id="toggleLeftPanelMenuItem" mnemonicParsing="false" text="%menu.title.hide.left.panel" /> - <MenuItem fx:id="toggleRightPanelMenuItem" mnemonicParsing="false" text="%menu.title.hide.right.panel" /> - <SeparatorMenuItem mnemonicParsing="false" /> - <MenuItem fx:id="toggleOutlinesMenuItem" mnemonicParsing="false" text="%menu.title.show.outlines" /> - <MenuItem fx:id="toggleSampleDataMenuItem" mnemonicParsing="false" text="%menu.title.show.sample.data" /> - <MenuItem fx:id="toggleAlignmentGuidesMenuItem" mnemonicParsing="false" text="%menu.title.disable.guides" /> - <SeparatorMenuItem mnemonicParsing="false" /> - <Menu fx:id="zoomMenu" mnemonicParsing="false" text="%menu.title.zoom" /> - <SeparatorMenuItem mnemonicParsing="false" /> - <MenuItem fx:id="showSampleControllerMenuItem" mnemonicParsing="false" text="%menu.title.show.sample.controller.skeleton" /> - </items> - </Menu> - <Menu fx:id="insertMenu" mnemonicParsing="false" text="%menu.title.insert" /> - <Menu mnemonicParsing="false" text="%menu.title.modify"> - <items> - <MenuItem fx:id="fitToParentMenuItem" mnemonicParsing="false" text="%menu.title.fit" /> - <MenuItem fx:id="useComputedSizesMenuItem" mnemonicParsing="false" text="%menu.title.use.computed.sizes" /> - <SeparatorMenuItem mnemonicParsing="false" /> - <Menu mnemonicParsing="false" text="%menu.title.grid"> - <items> - <MenuItem fx:id="selectNextRowMenuItem" mnemonicParsing="false" text="%menu.title.grid.select.next.row" /> - <MenuItem fx:id="selectNextColumnMenuItem" mnemonicParsing="false" text="%menu.title.grid.select.next.column" /> - <SeparatorMenuItem mnemonicParsing="false" /> - <MenuItem fx:id="moveRowAboveMenuItem" mnemonicParsing="false" text="%menu.title.grid.move.row.above" /> - <MenuItem fx:id="moveRowBelowMenuItem" mnemonicParsing="false" text="%menu.title.grid.move.row.below" /> - <MenuItem fx:id="moveColumnBeforeMenuItem" mnemonicParsing="false" text="%menu.title.grid.move.column.before" /> - <MenuItem fx:id="moveColumnAfterMenuItem" mnemonicParsing="false" text="%menu.title.grid.move.column.after" /> - <SeparatorMenuItem mnemonicParsing="false" /> - <MenuItem fx:id="addRowAboveMenuItem" mnemonicParsing="false" text="%menu.title.grid.add.row.above" /> - <MenuItem fx:id="addRowBelowMenuItem" mnemonicParsing="false" text="%menu.title.grid.add.row.below" /> - <MenuItem fx:id="addColumnBeforeMenuItem" mnemonicParsing="false" text="%menu.title.grid.add.column.before" /> - <MenuItem fx:id="addColumnAfterMenuItem" mnemonicParsing="false" text="%menu.title.grid.add.column.after" /> - <SeparatorMenuItem mnemonicParsing="false" /> - <MenuItem fx:id="increaseRowSpanMenuItem" mnemonicParsing="false" text="%menu.title.grid.increase.row.span" /> - <MenuItem fx:id="decreaseRowSpanMenuItem" mnemonicParsing="false" text="%menu.title.grid.decrease.row.span" /> - <MenuItem fx:id="increaseColumnSpanMenuItem" mnemonicParsing="false" text="%menu.title.grid.increase.column.span" /> - <MenuItem fx:id="decreaseColumnSpanMenuItem" mnemonicParsing="false" text="%menu.title.grid.decrease.column.span" /> - </items> - </Menu> - <SeparatorMenuItem mnemonicParsing="false" /> - <Menu fx:id="addEffectMenu" mnemonicParsing="false" text="%menu.title.add.effect" /> - <Menu fx:id="addPopupControlMenu" mnemonicParsing="false" text="%menu.title.add.popup" /> - <SeparatorMenuItem mnemonicParsing="false" /> - <MenuItem fx:id="editIncludedFileMenuItem" mnemonicParsing="false" text="%menu.title.edit.included.default" /> - <MenuItem fx:id="revealIncludedFileMenuItem" mnemonicParsing="false" text="%menu.title.reveal.included.default" /> - </items> - </Menu> - <Menu mnemonicParsing="false" text="%menu.title.arrange"> - <items> - <MenuItem fx:id="bringToFrontMenuItem" mnemonicParsing="false" text="%menu.title.front" /> - <MenuItem fx:id="sendToBackMenuItem" mnemonicParsing="false" text="%menu.title.back" /> - <MenuItem fx:id="bringForwardMenuItem" mnemonicParsing="false" text="%menu.title.forward" /> - <MenuItem fx:id="sendBackwardMenuItem" mnemonicParsing="false" text="%menu.title.backward" /> - <SeparatorMenuItem mnemonicParsing="false" /> - <Menu mnemonicParsing="false" text="%menu.title.wrap"> - <items> - <MenuItem fx:id="wrapInAnchorPaneMenuItem" mnemonicParsing="false" text="AnchorPane" /> - <MenuItem fx:id="wrapInGridPaneMenuItem" mnemonicParsing="false" text="GridPane" /> - <MenuItem fx:id="wrapInHBoxMenuItem" mnemonicParsing="false" text="HBox" /> - <MenuItem fx:id="wrapInPaneMenuItem" mnemonicParsing="false" text="Pane" /> - <MenuItem fx:id="wrapInScrollPaneMenuItem" mnemonicParsing="false" text="ScrollPane" /> - <MenuItem fx:id="wrapInSplitPaneMenuItem" mnemonicParsing="false" text="SplitPane" /> - <MenuItem fx:id="wrapInStackPaneMenuItem" mnemonicParsing="false" text="StackPane" /> - <MenuItem fx:id="wrapInTabPaneMenuItem" mnemonicParsing="false" text="TabPane" /> - <MenuItem fx:id="wrapInTitledPaneMenuItem" mnemonicParsing="false" text="TitledPane" /> - <MenuItem fx:id="wrapInToolBarMenuItem" mnemonicParsing="false" text="ToolBar" /> - <MenuItem fx:id="wrapInVBoxMenuItem" mnemonicParsing="false" text="VBox" /> - <MenuItem fx:id="wrapInGroupMenuItem" mnemonicParsing="false" text="Group" /> - </items> - </Menu> - <MenuItem fx:id="unwrapMenuItem" mnemonicParsing="false" text="%menu.title.unwrap" /> - </items> - </Menu> - <Menu mnemonicParsing="false" text="%menu.title.preview"> - <items> - <MenuItem fx:id="showPreviewMenuItem" mnemonicParsing="false" text="%menu.title.show.preview" /> - <SeparatorMenuItem mnemonicParsing="false" /> - <MenuItem fx:id="chooseBackgroundColorMenuItem" mnemonicParsing="false" text="%menu.title.choose.background.color" /> - <SeparatorMenuItem mnemonicParsing="false" /> - <Menu mnemonicParsing="false" text="%menu.title.theme"> - <items> - <RadioMenuItem fx:id="modenaThemeMenuItem" mnemonicParsing="false" text="%menu.title.theme.modena" /> - <RadioMenuItem fx:id="caspianThemeMenuItem" mnemonicParsing="false" text="%menu.title.theme.caspian" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" /> - </items> - </Menu> - <Menu mnemonicParsing="false" text="%menu.title.scene.stylesheets"> - <items> - <MenuItem fx:id="addSceneStyleSheetMenuItem" mnemonicParsing="false" text="%menu.title.add.stylesheet" /> - <Menu fx:id="removeSceneStyleSheetMenu" mnemonicParsing="false" text="%menu.title.remove.stylesheet"> - <items> - <MenuItem disable="true" mnemonicParsing="false" text="%scenestylesheet.none" /> - </items> - </Menu> - <Menu fx:id="openSceneStyleSheetMenu" mnemonicParsing="false" text="%menu.title.open.stylesheet"> - <items> - <MenuItem disable="true" mnemonicParsing="false" text="%scenestylesheet.none" /> - </items> - </Menu> - </items> - </Menu> - <Menu mnemonicParsing="false" text="%menu.title.internationalization"> - <items> - <MenuItem fx:id="setResourceMenuItem" mnemonicParsing="false" text="%menu.title.set.resource" /> - <MenuItem fx:id="removeResourceMenuItem" mnemonicParsing="false" text="%menu.title.remove.resource" /> - <MenuItem fx:id="revealResourceMenuItem" mnemonicParsing="false" text="%menu.title.reveal.resource" /> - </items> - </Menu> - </items> - </Menu> - <Menu fx:id="windowMenu" mnemonicParsing="false" text="%menu.title.window"> - <items> - <SeparatorMenuItem mnemonicParsing="false" /> - </items> - </Menu> - <Menu mnemonicParsing="false" text="%menu.title.help"> - <items> - <MenuItem fx:id="helpMenuItem" mnemonicParsing="false" text="%menu.title.scene.builder.help" /> - <MenuItem fx:id="aboutMenuItem" mnemonicParsing="false" text="%menu.title.about" /> - </items> - </Menu> - </menus> - </MenuBar> - </children> + </items> + </Menu> + <Menu mnemonicParsing="false" text="%menu.title.internationalization"> + <items> + <MenuItem mnemonicParsing="false" text="%menu.title.set.resource" fx:id="setResourceMenuItem" /> + <MenuItem mnemonicParsing="false" text="%menu.title.remove.resource" fx:id="removeResourceMenuItem" /> + <MenuItem mnemonicParsing="false" text="%menu.title.reveal.resource" fx:id="revealResourceMenuItem" /> + </items> + </Menu> + </items> + </Menu> + <Menu mnemonicParsing="false" text="%menu.title.window" fx:id="windowMenu"> + <items> + <SeparatorMenuItem mnemonicParsing="false" /> + </items> + </Menu> + <Menu mnemonicParsing="false" text="%menu.title.help"> + <items> + <MenuItem mnemonicParsing="false" text="%menu.title.scene.builder.help" fx:id="helpMenuItem" /> + <MenuItem mnemonicParsing="false" text="%menu.title.about" fx:id="aboutMenuItem" /> + </items> + </Menu> + </menus> + </MenuBar> + </children> </StackPane>
--- a/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/menubar/MenuBarController.java Fri Dec 20 15:48:27 2013 -0800 +++ b/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/menubar/MenuBarController.java Mon Dec 23 13:59:52 2013 +0100 @@ -33,6 +33,7 @@ import com.oracle.javafx.scenebuilder.app.DocumentWindowController; import com.oracle.javafx.scenebuilder.app.DocumentWindowController.DocumentControlAction; +import com.oracle.javafx.scenebuilder.app.DocumentWindowController.DocumentEditAction; import com.oracle.javafx.scenebuilder.app.SceneBuilderApp; import com.oracle.javafx.scenebuilder.app.SceneBuilderApp.ApplicationControlAction; import com.oracle.javafx.scenebuilder.app.i18n.I18N; @@ -53,6 +54,7 @@ import java.net.URL; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; @@ -66,6 +68,7 @@ import javafx.event.EventHandler; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; +import javafx.scene.control.CheckMenuItem; import javafx.scene.control.Menu; import javafx.scene.control.MenuBar; import javafx.scene.control.MenuItem; @@ -207,10 +210,6 @@ @FXML private MenuItem useComputedSizesMenuItem; @FXML - private MenuItem selectNextRowMenuItem; - @FXML - private MenuItem selectNextColumnMenuItem; - @FXML private MenuItem moveRowAboveMenuItem; @FXML private MenuItem moveRowBelowMenuItem; @@ -279,9 +278,17 @@ @FXML private MenuItem showPreviewMenuItem; @FXML - private MenuItem modenaThemeMenuItem; + private RadioMenuItem modenaThemeMenuItem; @FXML - private MenuItem caspianThemeMenuItem; + private RadioMenuItem modenaTouchThemeMenuItem; + @FXML + private RadioMenuItem caspianThemeMenuItem; + @FXML + private CheckMenuItem caspianHighContrastThemeMenuItem; + @FXML + private RadioMenuItem caspianEmbeddedThemeMenuItem; + @FXML + private RadioMenuItem caspianEmbeddedQVGAThemeMenuItem; @FXML private MenuItem chooseBackgroundColorMenuItem; @FXML @@ -305,6 +312,7 @@ private MenuItem aboutMenuItem; private static final KeyCombination.Modifier modifier; + private final Map<KeyCombination, MenuItem> keyToMenu = new HashMap<>(); static { if (EditorPlatform.IS_MAC) { @@ -422,8 +430,6 @@ assert fitToParentMenuItem != null; assert useComputedSizesMenuItem != null; - assert selectNextRowMenuItem != null; - assert selectNextColumnMenuItem != null; assert moveRowAboveMenuItem != null; assert moveRowBelowMenuItem != null; assert moveColumnBeforeMenuItem != null; @@ -459,7 +465,11 @@ assert showPreviewMenuItem != null; assert modenaThemeMenuItem != null; + assert modenaTouchThemeMenuItem != null; assert caspianThemeMenuItem != null; + assert caspianHighContrastThemeMenuItem != null; + assert caspianEmbeddedThemeMenuItem != null; + assert caspianEmbeddedQVGAThemeMenuItem != null; assert chooseBackgroundColorMenuItem != null; assert addSceneStyleSheetMenuItem != null; assert removeSceneStyleSheetMenu != null; @@ -549,11 +559,11 @@ // http://windows.microsoft.com/en-US/windows7/Keyboard-shortcuts redoMenuItem.setAccelerator(new KeyCodeCombination(KeyCode.Y, modifier)); } - copyMenuItem.setUserData(new ControlActionController(ControlAction.COPY)); + copyMenuItem.setUserData(new DocumentControlActionController(DocumentControlAction.COPY)); copyMenuItem.setAccelerator(new KeyCodeCombination(KeyCode.C, modifier)); - cutMenuItem.setUserData(new EditActionController(EditAction.CUT)); + cutMenuItem.setUserData(new DocumentEditActionController(DocumentEditAction.CUT)); cutMenuItem.setAccelerator(new KeyCodeCombination(KeyCode.X, modifier)); - pasteMenuItem.setUserData(new EditActionController(EditAction.PASTE)); + pasteMenuItem.setUserData(new DocumentEditActionController(DocumentEditAction.PASTE)); pasteMenuItem.setAccelerator(new KeyCodeCombination(KeyCode.V, modifier)); pasteIntoMenuItem.setUserData(new EditActionController(EditAction.PASTE_INTO)); pasteIntoMenuItem.setAccelerator(new KeyCodeCombination(KeyCode.V, KeyCombination.SHIFT_DOWN, modifier)); @@ -561,12 +571,12 @@ duplicateMenuItem.setAccelerator(new KeyCodeCombination(KeyCode.D, modifier)); deleteMenuItem.setUserData(new EditActionController(EditAction.DELETE)); deleteMenuItem.setAccelerator(new KeyCodeCombination(KeyCode.DELETE)); - selectAllMenuItem.setUserData(new ControlActionController(ControlAction.SELECT_ALL)); + selectAllMenuItem.setUserData(new DocumentControlActionController(DocumentControlAction.SELECT_ALL)); selectAllMenuItem.setAccelerator(new KeyCodeCombination(KeyCode.A, modifier)); - selectNoneMenuItem.setUserData(new ControlActionController(ControlAction.SELECT_NONE)); + selectNoneMenuItem.setUserData(new DocumentControlActionController(DocumentControlAction.SELECT_NONE)); selectNoneMenuItem.setAccelerator(new KeyCodeCombination(KeyCode.A, KeyCombination.SHIFT_DOWN, modifier)); selectParentMenuItem.setUserData(new ControlActionController(ControlAction.SELECT_PARENT)); - selectParentMenuItem.setAccelerator(new KeyCodeCombination(KeyCode.L, modifier)); + selectParentMenuItem.setAccelerator(new KeyCodeCombination(KeyCode.UP, modifier)); selectNextMenuItem.setUserData(new ControlActionController(ControlAction.SELECT_NEXT)); selectNextMenuItem.setAccelerator(new KeyCodeCombination(KeyCode.RIGHT, modifier)); selectPreviousMenuItem.setUserData(new ControlActionController(ControlAction.SELECT_PREVIOUS)); @@ -661,7 +671,20 @@ } }); toggleRightPanelMenuItem.setAccelerator(new KeyCodeCombination(KeyCode.DIGIT8, modifier)); -// toggleOutlinesMenuItem.setUserData(new ControlActionController(ControlAction.)); + toggleOutlinesMenuItem.setUserData(new DocumentControlActionController(DocumentControlAction.TOGGLE_OUTLINES_VISIBILITY) { + @Override + public String getTitle() { + final String titleKey; + if (documentWindowController == null) { + titleKey = "menu.title.hide.outlines"; + } else if (documentWindowController.getContentPanelController().isOutlinesVisible()) { + titleKey = "menu.title.hide.outlines"; + } else { + titleKey = "menu.title.show.outlines"; + } + return I18N.getString(titleKey); + } + }); toggleOutlinesMenuItem.setAccelerator(new KeyCodeCombination(KeyCode.E, modifier)); toggleSampleDataMenuItem.setUserData(new ControlActionController(ControlAction.TOGGLE_SAMPLE_DATA) { @Override @@ -719,8 +742,6 @@ fitToParentMenuItem.setAccelerator(new KeyCodeCombination(KeyCode.K, modifier)); useComputedSizesMenuItem.setUserData(new EditActionController(EditAction.USE_COMPUTED_SIZES)); useComputedSizesMenuItem.setAccelerator(new KeyCodeCombination(KeyCode.K, KeyCombination.SHIFT_DOWN, modifier)); - selectNextRowMenuItem.setUserData(new ControlActionController(ControlAction.SELECT_NEXT_ROW)); - selectNextColumnMenuItem.setUserData(new ControlActionController(ControlAction.SELECT_NEXT_COLUMN)); moveRowAboveMenuItem.setUserData(new EditActionController(EditAction.MOVE_ROW_ABOVE)); moveRowBelowMenuItem.setUserData(new EditActionController(EditAction.MOVE_ROW_BELOW)); moveColumnBeforeMenuItem.setUserData(new EditActionController(EditAction.MOVE_COLUMN_BEFORE)); @@ -789,8 +810,12 @@ showPreviewMenuItem.setAccelerator(new KeyCodeCombination(KeyCode.P, modifier)); chooseBackgroundColorMenuItem.setUserData(new DocumentControlActionController(DocumentControlAction.CHOOSE_BACKGROUND_COLOR)); chooseBackgroundColorMenuItem.setDisable(true); + caspianHighContrastThemeMenuItem.setUserData(new SetThemeActionController(EditorPlatform.Theme.CASPIAN_HIGH_CONTRAST)); caspianThemeMenuItem.setUserData(new SetThemeActionController(EditorPlatform.Theme.CASPIAN)); + caspianEmbeddedThemeMenuItem.setUserData(new SetThemeActionController(EditorPlatform.Theme.CASPIAN_EMBEDDED)); + caspianEmbeddedQVGAThemeMenuItem.setUserData(new SetThemeActionController(EditorPlatform.Theme.CASPIAN_EMBEDDED_QVGA)); modenaThemeMenuItem.setUserData(new SetThemeActionController(EditorPlatform.Theme.MODENA)); + modenaTouchThemeMenuItem.setUserData(new SetThemeActionController(EditorPlatform.Theme.MODENA_TOUCH)); addSceneStyleSheetMenuItem.setUserData(new DocumentControlActionController(DocumentControlAction.ADD_SCENE_STYLE_SHEET)); updateOpenAndRemoveSceneStyleSheetMenus(); @@ -888,6 +913,9 @@ } } else { i.setOnAction(onActionEventHandler); + if (i.getAccelerator() != null) { + keyToMenu.put(i.getAccelerator(), i); + } } } @@ -906,7 +934,20 @@ final String title; if (i.getUserData() instanceof MenuItemController) { final MenuItemController c = (MenuItemController) i.getUserData(); - disable = !c.canPerform(); + boolean canPerform; + try { + canPerform = c.canPerform(); + } catch(RuntimeException x) { + // This catch is protection against a bug in canPerform(). + // It avoids to block all the items in the menu in case + // of crash in canPerform() (see DTL-6164). + canPerform = false; + final Exception xx + = new Exception(c.getClass().getSimpleName() + + ".canPerform() did break for menu item " + i, x); //NOI18N + xx.printStackTrace(); + } + disable = !canPerform; title = c.getTitle(); selected = c.isSelected(); } else { @@ -945,7 +986,7 @@ final MenuItemController c = (MenuItemController) i.getUserData(); c.perform(); } - + /* * Private (zoom menu) */ @@ -1329,6 +1370,33 @@ } + class DocumentEditActionController extends MenuItemController { + + private final DocumentEditAction editAction; + + public DocumentEditActionController(DocumentEditAction editAction) { + this.editAction = editAction; + } + + @Override + public boolean canPerform() { + boolean result; + if (documentWindowController == null) { + result = false; + } else { + result = documentWindowController.canPerformEditAction(editAction); + } + return result; + } + + @Override + public void perform() { + assert canPerform() : "editAction=" + editAction; + documentWindowController.performEditAction(editAction); + } + + } + class DocumentControlActionController extends MenuItemController { private final DocumentControlAction controlAction; @@ -1450,28 +1518,126 @@ @Override public boolean canPerform() { - return (documentWindowController != null); + boolean res = documentWindowController != null; + final EditorPlatform.Theme currentTheme + = documentWindowController.getEditorController().getTheme(); + // CASPIAN_HIGH_CONTRAST can be selected only if another CASPIAN + // theme is active. + if (theme == EditorPlatform.Theme.CASPIAN_HIGH_CONTRAST + && (currentTheme == EditorPlatform.Theme.MODENA || currentTheme == EditorPlatform.Theme.MODENA_TOUCH)) { + res = false; + caspianHighContrastThemeMenuItem.setSelected(false); + } + return res; } @Override public void perform() { assert documentWindowController != null; - documentWindowController.getEditorController().setTheme(theme); + + EditorPlatform.Theme overiddingTheme = theme; + + switch (theme) { + case CASPIAN: + if (caspianHighContrastThemeMenuItem.isSelected()) { + overiddingTheme = EditorPlatform.Theme.CASPIAN_HIGH_CONTRAST; + } + break; + case CASPIAN_EMBEDDED: + if (caspianHighContrastThemeMenuItem.isSelected()) { + overiddingTheme = EditorPlatform.Theme.CASPIAN_EMBEDDED_HIGH_CONTRAST; + } + break; + case CASPIAN_EMBEDDED_QVGA: + if (caspianHighContrastThemeMenuItem.isSelected()) { + overiddingTheme = EditorPlatform.Theme.CASPIAN_EMBEDDED_QVGA_HIGH_CONTRAST; + } + break; + case CASPIAN_HIGH_CONTRAST: + final EditorPlatform.Theme currentTheme + = documentWindowController.getEditorController().getTheme(); + switch (currentTheme) { + case CASPIAN: + if (caspianHighContrastThemeMenuItem.isSelected()) { + overiddingTheme = EditorPlatform.Theme.CASPIAN_HIGH_CONTRAST; + } + break; + case CASPIAN_EMBEDDED: + if (caspianHighContrastThemeMenuItem.isSelected()) { + overiddingTheme = EditorPlatform.Theme.CASPIAN_EMBEDDED_HIGH_CONTRAST; + } + break; + case CASPIAN_EMBEDDED_QVGA: + if (caspianHighContrastThemeMenuItem.isSelected()) { + overiddingTheme = EditorPlatform.Theme.CASPIAN_EMBEDDED_QVGA_HIGH_CONTRAST; + } + break; + case CASPIAN_HIGH_CONTRAST: + if (!caspianHighContrastThemeMenuItem.isSelected()) { + overiddingTheme = EditorPlatform.Theme.CASPIAN; + } + break; + case CASPIAN_EMBEDDED_HIGH_CONTRAST: + if (!caspianHighContrastThemeMenuItem.isSelected()) { + overiddingTheme = EditorPlatform.Theme.CASPIAN_EMBEDDED; + } + break; + case CASPIAN_EMBEDDED_QVGA_HIGH_CONTRAST: + if (!caspianHighContrastThemeMenuItem.isSelected()) { + overiddingTheme = EditorPlatform.Theme.CASPIAN_EMBEDDED_QVGA; + } + break; + default: + // All known 6 Caspian cases are already handled above. + assert false; + break; + } + break; + default: + // Modena + break; + } + + documentWindowController.getEditorController().setTheme(overiddingTheme); } @Override public boolean isSelected() { - boolean result; + boolean res; if (documentWindowController == null) { - result = false; + res = false; } else { final EditorPlatform.Theme currentTheme = documentWindowController.getEditorController().getTheme(); - result = currentTheme == theme; + + switch (theme) { + // CASPIAN_HIGH_CONTRAST can be selected only if another CASPIAN + // theme is active. + case CASPIAN_HIGH_CONTRAST: + if (currentTheme == EditorPlatform.Theme.MODENA || currentTheme == EditorPlatform.Theme.MODENA_TOUCH) { + res = false; + } else { + res = true; + } + break; + case CASPIAN: + res = (currentTheme == theme || currentTheme == EditorPlatform.Theme.CASPIAN_HIGH_CONTRAST); + break; + case CASPIAN_EMBEDDED: + res = (currentTheme == theme || currentTheme == EditorPlatform.Theme.CASPIAN_EMBEDDED_HIGH_CONTRAST); + break; + case CASPIAN_EMBEDDED_QVGA: + res = (currentTheme == theme || currentTheme == EditorPlatform.Theme.CASPIAN_EMBEDDED_QVGA_HIGH_CONTRAST); + break; + default: + // Modena + res = currentTheme == theme; + break; + } } - return result; + return res; } } @@ -1525,6 +1691,14 @@ } } + public MenuItem getMenuItem(KeyCombination key) { + return keyToMenu.get(key); + } + + public Set<KeyCombination> getAccelerators() { + return keyToMenu.keySet(); + } + /** * ************************************************************************* * Static inner class
--- a/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/message/MessageBar.fxml Fri Dec 20 15:48:27 2013 -0800 +++ b/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/message/MessageBar.fxml Mon Dec 23 13:59:52 2013 +0100 @@ -44,29 +44,33 @@ <HBox fx:id="messageBox" alignment="CENTER" spacing="5.0" styleClass="message-bar"> <children> <StackPane fx:id="selectionBarHost" prefHeight="-1.0" prefWidth="-1.0" HBox.hgrow="ALWAYS" /> - <Label fx:id="messageLabel" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mouseTransparent="true" style=" " text="Message" HBox.hgrow="ALWAYS" /> - <HBox id="messageBox" alignment="CENTER_RIGHT" fillHeight="true" prefHeight="-1.0" prefWidth="-1.0" spacing="0.0" HBox.hgrow="NEVER"> + <HBox fx:id="messagePart" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"> <children> - <Button fx:id="messageButton" alignment="CENTER" maxHeight="1.7976931348623157E308" minHeight="-1.0" minWidth="20.0" mnemonicParsing="false" onAction="#onOpenCloseAction" text="" HBox.hgrow="ALWAYS"> - <graphic> - <ImageView id="warning" pickOnBounds="true" visible="true"> - <image> - <Image preserveRatio="true" smooth="true" url="@warning.png" /> - </image> - </ImageView> - </graphic> - <tooltip> - <Tooltip text="%message.bar.details" /> - </tooltip> - </Button> - <Label fx:id="statusLabel" contentDisplay="CENTER" focusTraversable="false" graphicTextGap="0.0" maxHeight="1.7976931348623157E308" minWidth="30.0" prefWidth="30.0" text="" HBox.hgrow="ALWAYS"> - <tooltip> - <Tooltip text="%message.bar.file.dirty" /> - </tooltip> - <HBox.margin> - <Insets /> - </HBox.margin> - </Label> + <Label fx:id="messageLabel" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mouseTransparent="true" style=" " text="Message" HBox.hgrow="ALWAYS" /> + <HBox id="messageBox" alignment="CENTER_RIGHT" fillHeight="true" prefHeight="-1.0" prefWidth="-1.0" spacing="0.0" HBox.hgrow="NEVER"> + <children> + <Button fx:id="messageButton" alignment="CENTER" maxHeight="1.7976931348623157E308" minHeight="-1.0" minWidth="20.0" mnemonicParsing="false" onAction="#onOpenCloseAction" text=""> + <graphic> + <ImageView id="warning" pickOnBounds="true" visible="true"> + <image> + <Image preserveRatio="true" smooth="true" url="@warning.png" /> + </image> + </ImageView> + </graphic> + <tooltip> + <Tooltip text="%message.bar.details" /> + </tooltip> + </Button> + <Label fx:id="statusLabel" contentDisplay="CENTER" focusTraversable="false" graphicTextGap="0.0" maxHeight="1.7976931348623157E308" minWidth="30.0" prefWidth="30.0" text=""> + <tooltip> + <Tooltip text="%message.bar.file.dirty" /> + </tooltip> + <HBox.margin> + <Insets /> + </HBox.margin> + </Label> + </children> + </HBox> </children> </HBox> </children>
--- a/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/message/MessageBarController.java Fri Dec 20 15:48:27 2013 -0800 +++ b/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/message/MessageBarController.java Mon Dec 23 13:59:52 2013 +0100 @@ -37,12 +37,11 @@ import com.oracle.javafx.scenebuilder.kit.editor.panel.util.AbstractFxmlPanelController; import com.oracle.javafx.scenebuilder.kit.fxom.FXOMDocument; import java.net.URL; -import java.util.Timer; -import java.util.TimerTask; -import javafx.application.Platform; +import javafx.animation.FadeTransition; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.event.ActionEvent; +import javafx.event.EventHandler; import javafx.fxml.FXML; import javafx.scene.control.Button; import javafx.scene.control.Label; @@ -50,7 +49,9 @@ import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.layout.HBox; +import javafx.scene.layout.Priority; import javafx.scene.layout.StackPane; +import javafx.util.Duration; /** * @@ -70,6 +71,8 @@ private Label statusLabel; @FXML private StackPane selectionBarHost; + @FXML + private HBox messagePart; private final ImageView fileDirtyImage; private Tooltip statusLabelTooltip = null; @@ -194,6 +197,7 @@ // no need to display anything in the message bar. if (entry != null && logSize > previousTotalNumOfMessages) { // We mask the host + HBox.setHgrow(messagePart, Priority.ALWAYS); getSelectionBarHost().getChildren().get(0).setVisible(false); getSelectionBarHost().setManaged(false); messageLabel.setManaged(true); @@ -218,64 +222,31 @@ messageLabel.setText(entry.getText()); messageLabel.setVisible(true); - // We go back to the host after a given time - // The fading based code commented out below do not seem to be - // reliable in the sense that when sending slowly 10 messages in a - // row you get 1 or 2 where the display time isn't correct, fading - // duration abrupt, ... - // For now we use a timer to switch back abruptly. But fact is the - // time the message remains visible do not seem more stable than - // with the fading transition. - final Timer timer = new Timer(true); - final TimerTask timerTask = new TimerTask() { + // We go back to the host after a given time + FadeTransition showHost = new FadeTransition(Duration.seconds(1), messagePart); + showHost.setFromValue(1.0); + showHost.setToValue(0.0); + showHost.setDelay(Duration.seconds(2)); + showHost.setOnFinished(new EventHandler<ActionEvent>() { @Override - public void run() { - Platform.runLater(new Runnable() { - - @Override - public void run() { - messageLabel.setVisible(false); - messageLabel.setGraphic(null); - messageLabel.setManaged(false); - if (getEditorController().getMessageLog().getWarningEntryCount() == 0) { - messageButton.setVisible(false); - messageButton.setManaged(false); - } - resetStyle(); - getSelectionBarHost().setManaged(true); - getSelectionBarHost().getChildren().get(0).setOpacity(1.0); - getSelectionBarHost().getChildren().get(0).setVisible(true); - } - }); - // I don't need to use the timer later on so by cancelling - // it here I free resources that otherwise would prevent - // the JVM from exiting. - timer.cancel(); + public void handle(ActionEvent t) { + messageLabel.setVisible(false); + messageLabel.setGraphic(null); + messageLabel.setManaged(false); + if (getEditorController().getMessageLog().getWarningEntryCount() == 0) { + messageButton.setVisible(false); + messageButton.setManaged(false); + } + resetStyle(); + getSelectionBarHost().setManaged(true); + getSelectionBarHost().getChildren().get(0).setOpacity(1.0); + getSelectionBarHost().getChildren().get(0).setVisible(true); + messagePart.setOpacity(1.0); + HBox.setHgrow(messagePart, Priority.NEVER); } - }; - timer.schedule(timerTask, 2000); // milliseconds - -// FadeTransition showHost = new FadeTransition(Duration.seconds(1), messageLabel); -// showHost.setFromValue(1.0); -// showHost.setToValue(0.0); -// showHost.setDelay(Duration.seconds(3)); -// showHost.setOnFinished(new EventHandler<ActionEvent>() { -// -// @Override -// public void handle(ActionEvent t) { -// messageLabel.setVisible(false); -// messageButton.setVisible(false); -// if (entry.getType() == MessageLogEntry.Type.INFO) { -// messageLabel.getStyleClass().remove("message-label-info"); -// } else { -// messageLabel.getStyleClass().remove("message-label-warning-and-error"); -// } -// getSelectionBarHost().getChildren().get(0).setOpacity(1.0); -// getSelectionBarHost().getChildren().get(0).setVisible(true); -// } -// }); -// showHost.play(); + }); + showHost.play(); } else if (getEditorController().getMessageLog().getEntryCount() == 0) { if (messageWindowController != null && messageWindowController.isWindowOpened()) { messageWindowController.closeWindow();
--- a/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/preview/PreviewWindowController.java Fri Dec 20 15:48:27 2013 -0800 +++ b/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/preview/PreviewWindowController.java Mon Dec 23 13:59:52 2013 +0100 @@ -43,7 +43,10 @@ import java.io.IOException; import java.io.InputStreamReader; import java.net.MalformedURLException; +import java.net.URL; import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; import java.util.PropertyResourceBundle; import java.util.ResourceBundle; import java.util.Timer; @@ -161,7 +164,7 @@ protected void makeRoot() { // Until the timer used in requestUpdate() expires, so that the root of // the scene is updated to the real content, we set a placeholder. - StackPane sp = new StackPane(new Label(I18N.getString("preview.constructing"))); + StackPane sp = new StackPane(); sp.setPrefSize(WIDTH_WHEN_EMPTY, HEIGHT_WHEN_EMPTY); setRoot(sp); @@ -205,7 +208,7 @@ /** * There's a delay before the content of the preview is refreshed. If any - * further modification is brought to the layout before expiration of this + * further modification is brought to the layout before expiration of it * we restart the timer. The idea is to lower the resources used to refresh * the preview window content. */ @@ -246,16 +249,25 @@ } Object sceneGraphRoot = clone.getSceneGraphRoot(); - final String themeStyleSheetString = - EditorPlatform.getThemeStylesheetURL(editorControllerTheme).toString(); + final List<String> themeStyleSheetStrings = new ArrayList<>(); + for (URL themeURL : EditorPlatform.getThemeStylesheetURLs(editorControllerTheme)) { + themeStyleSheetStrings.add(themeURL.toString()); + } if (sceneGraphRoot instanceof Parent) { ((Parent) sceneGraphRoot).setId(NID_PREVIEW_ROOT); setRoot((Parent) updateAutoResizeTransform((Parent) sceneGraphRoot)); assert ((Parent) sceneGraphRoot).getScene() == null; - ((Parent) sceneGraphRoot).getStylesheets().removeAll(themeStyleSheetString); - ((Parent) sceneGraphRoot).getStylesheets().add(themeStyleSheetString); + // At that stage current style sheets are the one defined within the FXML + ObservableList<String> currentStyleSheets = ((Parent) sceneGraphRoot).getStylesheets(); + List<String> newStyleSheets = new ArrayList<>(); + + for (String stylesheet : currentStyleSheets) { + newStyleSheets.add(stylesheet); + } + + // Add style sheet set thanks Preview > Scene Style Sheets > Add a Style Sheet if (sceneStyleSheet != null) { for (File f : sceneStyleSheet) { String urlString = ""; //NOI18N @@ -264,16 +276,21 @@ } catch (MalformedURLException ex) { throw new RuntimeException("Bug in PreviewWindowController", ex); //NOI18N } - ((Parent) sceneGraphRoot).getStylesheets().removeAll(urlString); - ((Parent) sceneGraphRoot).getStylesheets().add(urlString); + newStyleSheets.add(urlString); } } - - // Not proven necessary as per my testing -// ((Parent) sceneGraphRoot).applyCss(); + + // Clean all styling + ((Parent) sceneGraphRoot).getStylesheets().removeAll(); + + // Add theme style sheet; order is significant ==> theme one always first + newStyleSheets.addAll(0, themeStyleSheetStrings); + + // Apply the whole styling + ((Parent) sceneGraphRoot).getStylesheets().addAll(newStyleSheets); } else if (sceneGraphRoot instanceof Node) { StackPane sp = new StackPane(); - sp.getStylesheets().add(themeStyleSheetString); + sp.getStylesheets().addAll(0, themeStyleSheetStrings); if (sceneStyleSheet != null) { for (File f : sceneStyleSheet) { @@ -314,11 +331,12 @@ } }; - // If there is no opened document while Preview window is built we want - // it to come up immediately. long delay = 0; - if (editorController.getFxomDocument() != null) { + // A long delay makes sense only if we have a valid document and + // the preview window is already opened. + // When opening preview window we want it fast. + if (editorController.getFxomDocument() != null && getStage().isShowing()) { delay = 1000; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/report/JarAnalysisReport.css Mon Dec 23 13:59:52 2013 +0100 @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. + * All rights reserved. Use is subject to license terms. + * + * This file is available and licensed under the following license: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * - Neither the name of Oracle Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +.scroll-pane, .scroll-pane:focused, .scroll-pane:selected, .scroll-pane:pressed, .scroll-pane:hover { + -fx-background-color: null; + -fx-padding: 0px; + -fx-border-width: 1px; + -fx-border-color: lightgrey; +} + +.header { +} + +.body { + -fx-font-family: monospace; + -fx-fill: slategray; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/report/JarAnalysisReport.fxml Mon Dec 23 13:59:52 2013 +0100 @@ -0,0 +1,71 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + Copyright (c) 2012, 2013, Oracle and/or its affiliates. + All rights reserved. Use is subject to license terms. + + This file is available and licensed under the following license: + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + - Neither the name of Oracle Corporation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--> + +<?import java.lang.*?> +<?import java.net.*?> +<?import javafx.geometry.*?> +<?import javafx.scene.control.*?> +<?import javafx.scene.layout.*?> +<?import javafx.scene.text.*?> + +<StackPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"> + <children> + <VBox prefHeight="400.0" prefWidth="600.0"> + <children> + <Label fx:id="timestampLabel" text="%jar.analysis.report.timestamp"> + <VBox.margin> + <Insets bottom="7.0" /> + </VBox.margin> + </Label> +<ScrollPane prefViewportHeight="350.0" prefViewportWidth="600.0" VBox.vgrow="ALWAYS" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"> +<content><TextFlow fx:id="textFlow" focusTraversable="true" VBox.vgrow="ALWAYS" /> +</content> +<VBox.margin> +<Insets /> +</VBox.margin> +</ScrollPane> + <Button defaultButton="true" mnemonicParsing="false" onAction="#onCopyAction" text="%label.copy"> + <VBox.margin> + <Insets top="7.0" /> + </VBox.margin></Button> + </children> + <StackPane.margin> + <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" /> + </StackPane.margin> + </VBox> + </children> + <stylesheets> + <URL value="@JarAnalysisReport.css" /> + </stylesheets> +</StackPane>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/report/JarAnalysisReportController.java Mon Dec 23 13:59:52 2013 +0100 @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. + * All rights reserved. Use is subject to license terms. + * + * This file is available and licensed under the following license: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * - Neither the name of Oracle Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.oracle.javafx.scenebuilder.app.report; + +import com.oracle.javafx.scenebuilder.app.i18n.I18N; +import com.oracle.javafx.scenebuilder.kit.editor.EditorController; +import com.oracle.javafx.scenebuilder.kit.editor.panel.util.AbstractFxmlWindowController; +import com.oracle.javafx.scenebuilder.kit.library.user.UserLibrary; +import com.oracle.javafx.scenebuilder.kit.library.util.JarReport; +import com.oracle.javafx.scenebuilder.kit.library.util.JarReportEntry; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import javafx.collections.ListChangeListener; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.scene.control.Label; +import javafx.scene.input.Clipboard; +import javafx.scene.input.DataFormat; +import javafx.stage.Window; +import java.io.PrintWriter; +import java.io.StringWriter; +import javafx.scene.Node; +import javafx.scene.text.Text; +import javafx.scene.text.TextFlow; +import javafx.stage.WindowEvent; + +/** + * + */ +public class JarAnalysisReportController extends AbstractFxmlWindowController { + + @FXML + TextFlow textFlow; + @FXML + Label timestampLabel; + + @FXML + void onCopyAction(ActionEvent event) { + final Map<DataFormat, Object> content = new HashMap<>(); + StringBuilder sb = new StringBuilder(); + + for (Node item : textFlow.getChildrenUnmodifiable()) { + if (item instanceof Text) { + sb.append(((Text)item).getText()); + } + } + + content.put(DataFormat.PLAIN_TEXT, sb.toString()); + Clipboard.getSystemClipboard().setContent(content); + } + + private final EditorController editorController; + private final String TIMESTAMP_PATTERN = "h:mm a EEEEEEEEE d MMM. yyyy"; //NOI18N + private final SimpleDateFormat TIMESTAMP_DATE_FORMAT = new SimpleDateFormat(TIMESTAMP_PATTERN); + private int prefixCounter = 0; + private boolean dirty = false; + + public JarAnalysisReportController(EditorController editorController, Window owner) { + super(JarAnalysisReportController.class.getResource("JarAnalysisReport.fxml"), I18N.getBundle(), owner); //NOI18N + this.editorController = editorController; + } + + @Override + public void onCloseRequest(WindowEvent event) { + getStage().close(); + } + + @Override + public void openWindow() { + super.openWindow(); + + if (dirty) { + update(); + } + } + + @Override + protected void controllerDidCreateStage() { + // Setup window title + getStage().setTitle(I18N.getString("jar.analysis.report.title")); + } + + @Override + protected void controllerDidLoadFxml() { + assert textFlow != null; + assert timestampLabel != null; + + UserLibrary lib = (UserLibrary)editorController.getLibrary(); + lib.getJarReports().addListener(new ListChangeListener<JarReport>() { + + @Override + public void onChanged(ListChangeListener.Change<? extends JarReport> change) { + update(); + } + }); + + update(); + } + + private void update() { + // No need to eat CPU if the skeleton window isn't opened + if (getStage().isShowing()) { + textFlow.getChildren().clear(); + + updateTimeStampLabel(); + + UserLibrary lib = (UserLibrary)editorController.getLibrary(); + + for (JarReport report : lib.getJarReports()) { + for (JarReportEntry entry : report.getEntries()) { + if (entry.getStatus() != JarReportEntry.Status.OK) { + if (entry.getKlass() != null && entry.getException() != null) { + // We use a Text instance for header and another one + // for full stack in order to style them separately + StringBuilder sb = new StringBuilder(); + sb.append(getSectionPrefix()).append(I18N.getString("jar.analysis.exception")); + sb.append(" ").append(entry.getName()); //NOI18N + Text text = new Text(); + text.setText(sb.toString()); + text.getStyleClass().add("header"); //NOI18N + textFlow.getChildren().add(text); + + StringBuilder sb2 = new StringBuilder(); + sb2.append(getFullStack(entry.getException())); + Text text2 = new Text(); + text2.setText(sb2.toString()); + text2.getStyleClass().add("body"); //NOI18N + textFlow.getChildren().add(text2); + } + } else if (! entry.isNode()) { + StringBuilder sb = new StringBuilder(); + sb.append(getSectionPrefix()).append(I18N.getString("jar.analysis.not.node")); + sb.append(" ").append(entry.getName()); //NOI18N + Text text = new Text(); + text.setText(sb.toString()); + text.getStyleClass().add("header"); //NOI18N + textFlow.getChildren().add(text); + } + } + } + + dirty = false; + } else { + dirty = true; + } + } + + // The very first section must start on top, it is only for the next one we + // need a separator. + private String getSectionPrefix() { + if (prefixCounter == 0) { + prefixCounter++; + return ""; //NOI18N + } else { + return "\n\n"; //NOI18N + } + } + + private StringBuilder getFullStack(Throwable t) { + StringBuilder res = new StringBuilder("\n"); //NOI18N + StringWriter writer = new StringWriter(); + t.printStackTrace(new PrintWriter(writer, true)); + res.append(writer.getBuffer().toString()); + return res; + } + + private void updateTimeStampLabel() { + UserLibrary lib = (UserLibrary)editorController.getLibrary(); + Date date = (Date)lib.getExplorationDate(); + String timestampValue = TIMESTAMP_DATE_FORMAT.format(date); + timestampLabel.setText(I18N.getString("jar.analysis.report.timestamp", timestampValue)); + } +}
--- a/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/skeleton/SkeletonBuffer.java Fri Dec 20 15:48:27 2013 -0800 +++ b/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/skeleton/SkeletonBuffer.java Mon Dec 23 13:59:52 2013 +0100 @@ -35,6 +35,7 @@ import com.oracle.javafx.scenebuilder.app.i18n.I18N; import com.oracle.javafx.scenebuilder.kit.fxom.FXOMDocument; import com.oracle.javafx.scenebuilder.kit.fxom.FXOMObject; +import com.oracle.javafx.scenebuilder.kit.fxom.FXOMPropertyT; import java.lang.reflect.TypeVariable; import java.net.URL; import java.util.Map; @@ -59,6 +60,7 @@ private final StringBuilder classLine = new StringBuilder(); private final StringBuilder header = new StringBuilder(); private final StringBuilder initialize = new StringBuilder(); + private final StringBuilder handlers = new StringBuilder(); enum TEXT_TYPE { @@ -155,6 +157,7 @@ constructClassLine(); String documentName = DocumentWindowController.makeTitle(document); + // All that depends on fx:id Map<String, FXOMObject> fxids = document.collectFxIds(); for (FXOMObject value : fxids.values()) { @@ -199,6 +202,14 @@ if (textFormat == FORMAT_TYPE.FULL) { addImportsFor(imports, URL.class, ResourceBundle.class); } + + // Event handlers + for (FXOMPropertyT property : document.getFxomRoot().collectEventHandlers()) { + handlers.append(INDENT).append("@FXML\n").append(INDENT).append("void "); //NOI18N + final String methodName = property.getValue().replace("#", ""); //NOI18N + handlers.append(methodName); + handlers.append("(ActionEvent event) {\n\n").append(INDENT).append("}\n\n"); //NOI18N + } // This method must be called once asserts has been populated. constructInitialize(); @@ -239,6 +250,7 @@ } code.append(variables); + code.append(handlers); code.append(initialize); code.append("}\n"); //NOI18N
--- a/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/skeleton/SkeletonWindow.fxml Fri Dec 20 15:48:27 2013 -0800 +++ b/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/skeleton/SkeletonWindow.fxml Mon Dec 23 13:59:52 2013 +0100 @@ -45,7 +45,7 @@ <TextArea fx:id="textArea" editable="false" focusTraversable="false" prefHeight="500.0" VBox.vgrow="ALWAYS" /> <HBox alignment="BASELINE_RIGHT" prefWidth="600.0" spacing="20.0"> <children> - <Button fx:id="copyButton" mnemonicParsing="false" onAction="#onCopyAction" text="%label.copy" HBox.hgrow="ALWAYS" /> + <Button mnemonicParsing="false" onAction="#onCopyAction" text="%label.copy" HBox.hgrow="ALWAYS" /> <HBox alignment="BASELINE_RIGHT" spacing="5.0" HBox.hgrow="ALWAYS"> <children> <CheckBox fx:id="commentCheckBox" mnemonicParsing="false" text="%skeleton.add.comments">
--- a/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/skeleton/SkeletonWindowController.java Fri Dec 20 15:48:27 2013 -0800 +++ b/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/skeleton/SkeletonWindowController.java Mon Dec 23 13:59:52 2013 +0100 @@ -58,8 +58,6 @@ public class SkeletonWindowController extends AbstractFxmlWindowController { @FXML - Button copyButton; - @FXML CheckBox commentCheckBox; @FXML CheckBox formatCheckBox; @@ -80,6 +78,7 @@ } private final EditorController editorController; + private boolean dirty = false; public SkeletonWindowController(EditorController editorController, Window owner) { super(SkeletonWindowController.class.getResource("SkeletonWindow.fxml"), I18N.getBundle(), owner); //NOI18N @@ -110,6 +109,15 @@ public void onCloseRequest(WindowEvent event) { getStage().close(); } + + @Override + public void openWindow() { + super.openWindow(); + + if (dirty) { + update(); + } + } /* * AbstractFxmlWindowController @@ -117,7 +125,6 @@ @Override protected void controllerDidLoadFxml() { super.controllerDidLoadFxml(); - assert copyButton != null; assert commentCheckBox != null; assert formatCheckBox != null; assert textArea != null; @@ -159,192 +166,27 @@ } private void update() { - updateTitle(); - final SkeletonBuffer buf = new SkeletonBuffer(editorController.getFxomDocument()); + // No need to eat CPU if the skeleton window isn't opened + if (getStage().isShowing()) { + updateTitle(); + final SkeletonBuffer buf = new SkeletonBuffer(editorController.getFxomDocument()); - if (commentCheckBox.isSelected()) { - buf.setTextType(TEXT_TYPE.WITH_COMMENTS); + if (commentCheckBox.isSelected()) { + buf.setTextType(TEXT_TYPE.WITH_COMMENTS); + } else { + buf.setTextType(TEXT_TYPE.WITHOUT_COMMENTS); + } + + if (formatCheckBox.isSelected()) { + buf.setFormat(FORMAT_TYPE.FULL); + } else { + buf.setFormat(FORMAT_TYPE.COMPACT); + } + + textArea.setText(buf.toString()); + dirty = false; } else { - buf.setTextType(TEXT_TYPE.WITHOUT_COMMENTS); + dirty = true; } - - if (formatCheckBox.isSelected()) { - buf.setFormat(FORMAT_TYPE.FULL); - } else { - buf.setFormat(FORMAT_TYPE.COMPACT); - } - - textArea.setText(buf.toString()); } - -// private String generateSkeleton(TEXT_TYPE textType) { -// final String INDENT = " "; //NOI18N -// Map<String, FXOMObject> fxids = editorController.getFxomDocument().collectFxIds(); -// Set<String> imports = new TreeSet<>(); -// StringBuilder variables = new StringBuilder(); -// StringBuilder asserts = new StringBuilder(); -// -// for (String key : fxids.keySet()) { -// final FXOMObject value = fxids.get(key); -//// if (value.isEmpty()) { -//// continue; -//// } -//// if (value.size() > 1) { -//// variables.append(INDENT).append("// WARNING: fx:id=\"").append(key) //NOI18N -//// .append("\" cannot be injected: several objects share the same fx:id;\n\n"); //NOI18N -//// } else if (Utils.isValidFxmlId(key)) { -// final Object obj = value.getSceneGraphObject(); -// final Class<?> type = obj.getClass(); -// -//// if (ComponentDictionary.lookupDefinition(type, false) == null && !type.equals(ToggleGroup.class)) { -//// Utils.println("Class '" + type.getSimpleName() + "' has no definition: skipping fx:id=\"" + key + "\""); -//// continue; -//// } -// -// addImportsFor(imports, FXML.class, type); -// variables.append(INDENT).append("@FXML"); //NOI18N -// -// if (textType == TEXT_TYPE.WITH_COMMENTS) { -// variables.append(" // fx:id=\"").append(key).append("\""); //NOI18N -// } -// -// variables.append("\n"); //NOI18N -// variables.append(INDENT).append("private ").append(type.getSimpleName()); //NOI18N -// final TypeVariable<? extends Class<?>>[] parameters = type.getTypeParameters(); -// -// if (parameters.length > 0) { -// variables.append("<"); //NOI18N -// String sep = ""; //NOI18N -// for (TypeVariable<?> t : parameters) { -// variables.append(sep).append("?"); //NOI18N -// sep = ", "; //NOI18N -// } -// variables.append(">"); //NOI18N -// } -// -// if (textType == TEXT_TYPE.WITH_COMMENTS) { -// variables.append(" ").append(key).append("; // Value injected by FXMLLoader\n\n"); //NOI18N -// } else { -// variables.append(" ").append(key).append(";\n\n"); //NOI18N -// } -// -// asserts.append(INDENT).append(INDENT).append("assert ").append(key).append(" != null : ") //NOI18N -// .append("\"fx:id=\\\"").append(key).append("\\\" was not injected: check your FXML file ") //NOI18N -//// .append("'").append(project.isUntitledProject() ? project.getProjectName() : project.getProjectFxmlFile().getName()) //NOI18N -// .append("'.\";\n"); //NOI18N -//// } else { -//// variables.append(INDENT).append("// WARNING: fx:id=\"").append(key) //NOI18N -//// .append("\" cannot be injected: it is not a valid Java Identifier;\n\n"); //NOI18N -//// } -// } -// -// addImportsFor(imports, URL.class, ResourceBundle.class); -// -// // GLOP -// StringBuilder glop = new StringBuilder(); -// for (String ouaf : imports) { -// glop.append(ouaf); -// } -// return glop.toString(); -// -//// final StringBuilder handlerCode = new StringBuilder(); -//// final Map<String, Set<TargetPropertyValue>> handlers = Collections.unmodifiableMap(context.handlers); -//// final TreeSet<String> handlerNames = new TreeSet<>(handlers.keySet()); -//// for (String name : handlerNames) { -//// if (!name.startsWith("#") || name.startsWith("##")) { -//// continue; //NOI18N -//// } -//// final String methodName = name.substring(1); -//// if (!Utils.isValidFxmlId(methodName)) { -//// handlerCode.append(INDENT) -//// .append("// WARNING: cannot create handler for '") //NOI18N -//// .append(name).append("': not a valid method name\n\n"); //NOI18N -//// } else { -//// TreeSet<String> comments = new TreeSet<>(); -//// Class<?> eventClass = null; -//// for (TargetPropertyValue tpv : handlers.get(name)) { -//// comments.add(describeHandler(tpv)); -//// if (!tpv.getProperty().isProp()) { -//// eventClass = Event.class; -//// } else { -//// eventClass = commonEventClass(eventClass, tpv.getProperty().getProp().getType()); -//// } -//// } -//// if (textType == TEXT_TYPE.WITH_COMMENTS) { -//// for (String s : comments) { -//// handlerCode.append(INDENT).append(s); -//// } -//// } -//// handlerCode.append(INDENT).append("@FXML\n"); //NOI18N -//// handlerCode.append(INDENT).append("void ").append(methodName).append("(") //NOI18N -//// .append(eventClass.getSimpleName()).append(" event) {\n"); //NOI18N -//// if (textType == TEXT_TYPE.WITH_COMMENTS) { -//// handlerCode.append(INDENT).append(INDENT).append("// handle the event here\n"); //NOI18N -//// } -//// handlerCode.append(INDENT).append("}\n\n"); //NOI18N -//// addImportsFor(imports, eventClass); -//// } -//// } -//// -//// final StringBuilder controller = new StringBuilder(); -//// String controllerName = project.getScreenData().getControllerClass(); -//// if (controllerName == null || controllerName.isEmpty()) { -//// controllerName = "PleaseProvideControllerClassName"; //NOI18N -//// } -//// String simpleName = controllerName.replace("$", "."); //NOI18N -//// int dot = simpleName.lastIndexOf('.'); -//// if (dot > -1) { -//// simpleName = simpleName.substring(dot + 1); -//// } -//// if (textType == TEXT_TYPE.WITH_COMMENTS) { -//// controller.append("/**\n").append(" * ") //NOI18N -//// .append(format("menu.view.sample.controller.skeleton.header.line1", project.getProjectName())) -//// .append("\n").append(" * ") //NOI18N -//// .append(format("menu.view.sample.controller.skeleton.header.line2")) -//// .append("\n").append(" **/\n\n"); //NOI18N -//// } -//// if (!controllerName.contains("$")) { //NOI18N -//// int lastdot = controllerName.lastIndexOf('.'); -//// if (lastdot > 0) { -//// controller.append("package ").append(controllerName.substring(0, lastdot)).append(";\n\n"); //NOI18N -//// } -//// } -//// for (String imp : imports) { -//// controller.append(imp); -//// } -//// controller.append("\n\n"); //NOI18N -//// controller.append("public "); //NOI18N -//// if (controllerName.contains("$")) { //NOI18N -//// controller.append("static "); //NOI18N -//// } -//// controller.append("class ").append(simpleName).append(" {\n\n"); //NOI18N -//// if (textType == TEXT_TYPE.WITH_COMMENTS) { -//// controller.append(INDENT).append("@FXML // ResourceBundle that was given to the FXMLLoader\n") //NOI18N -//// .append(INDENT).append("private ResourceBundle resources;\n\n") //NOI18N -//// .append(INDENT).append("@FXML // URL location of the FXML file that was given to the FXMLLoader\n") //NOI18N -//// .append(INDENT).append("private URL location;\n\n"); //NOI18N -//// } else { -//// controller.append(INDENT).append("@FXML\n") //NOI18N -//// .append(INDENT).append("private ResourceBundle resources;\n\n") //NOI18N -//// .append(INDENT).append("@FXML\n") //NOI18N -//// .append(INDENT).append("private URL location;\n\n"); //NOI18N -//// } -//// controller.append(variables); -//// controller.append("\n"); //NOI18N -//// controller.append(handlerCode.toString()); -//// if (textType == TEXT_TYPE.WITH_COMMENTS) { -//// controller.append(INDENT).append("@FXML // This method is called by the FXMLLoader when initialization is complete\n"); //NOI18N -//// } else { -//// controller.append(INDENT).append("@FXML\n"); //NOI18N -//// } -//// controller.append(INDENT).append("void initialize() {\n") //NOI18N -//// .append(asserts.toString()).append("\n"); //NOI18N -//// if (textType == TEXT_TYPE.WITH_COMMENTS) { -//// controller.append(INDENT).append(INDENT).append("// Initialize your logic here: all @FXML variables will have been injected\n"); //NOI18N -//// } -//// controller.append("\n") //NOI18N -//// .append(INDENT).append("}\n\n"); //NOI18N -//// controller.append("}\n"); //NOI18N -//// return controller.toString(); -// } }
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/EditorController.java Fri Dec 20 15:48:27 2013 -0800 +++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/EditorController.java Mon Dec 23 13:59:52 2013 +0100 @@ -51,6 +51,7 @@ import com.oracle.javafx.scenebuilder.kit.editor.job.gridpane.GridPaneJobUtils.Position; import com.oracle.javafx.scenebuilder.kit.editor.job.gridpane.MoveColumnJob; import com.oracle.javafx.scenebuilder.kit.editor.job.gridpane.MoveRowJob; +import com.oracle.javafx.scenebuilder.kit.editor.job.wrap.AbstractWrapInJob; import com.oracle.javafx.scenebuilder.kit.editor.job.wrap.UnwrapJob; import com.oracle.javafx.scenebuilder.kit.editor.job.wrap.WrapInAnchorPaneJob; import com.oracle.javafx.scenebuilder.kit.editor.job.wrap.WrapInGridPaneJob; @@ -102,6 +103,7 @@ import javafx.beans.value.ObservableListValue; import javafx.beans.value.ObservableValue; import javafx.collections.ObservableList; +import javafx.scene.Parent; import javafx.scene.effect.Effect; import javafx.scene.input.Clipboard; import javafx.util.Callback; @@ -183,10 +185,7 @@ SELECT_NEXT, SELECT_PREVIOUS, TOGGLE_CSS_SELECTION, - TOGGLE_SAMPLE_DATA, - // Candidates for Modify - GridPane - SELECT_NEXT_ROW, - SELECT_NEXT_COLUMN, + TOGGLE_SAMPLE_DATA } private final Selection selection = new Selection(); @@ -858,63 +857,51 @@ break; } case WRAP_IN_ANCHOR_PANE: { - final WrapInAnchorPaneJob job = new WrapInAnchorPaneJob(this); - jobManager.push(job); + performWrap(javafx.scene.layout.AnchorPane.class); break; } case WRAP_IN_GRID_PANE: { - final WrapInGridPaneJob job = new WrapInGridPaneJob(this); - jobManager.push(job); + performWrap(javafx.scene.layout.GridPane.class); break; } case WRAP_IN_GROUP: { - final WrapInGroupJob job = new WrapInGroupJob(this); - jobManager.push(job); + performWrap(javafx.scene.Group.class); break; } case WRAP_IN_HBOX: { - final WrapInHBoxJob job = new WrapInHBoxJob(this); - jobManager.push(job); + performWrap(javafx.scene.layout.HBox.class); break; } case WRAP_IN_PANE: { - final WrapInPaneJob job = new WrapInPaneJob(this); - jobManager.push(job); + performWrap(javafx.scene.layout.Pane.class); break; } case WRAP_IN_SCROLL_PANE: { - final WrapInScrollPaneJob job = new WrapInScrollPaneJob(this); - jobManager.push(job); + performWrap(javafx.scene.control.ScrollPane.class); break; } case WRAP_IN_SPLIT_PANE: { - final WrapInSplitPaneJob job = new WrapInSplitPaneJob(this); - jobManager.push(job); + performWrap(javafx.scene.control.SplitPane.class); break; } case WRAP_IN_STACK_PANE: { - final WrapInStackPaneJob job = new WrapInStackPaneJob(this); - jobManager.push(job); + performWrap(javafx.scene.layout.StackPane.class); break; } case WRAP_IN_TAB_PANE: { - final WrapInTabPaneJob job = new WrapInTabPaneJob(this); - jobManager.push(job); + performWrap(javafx.scene.control.TabPane.class); break; } case WRAP_IN_TITLED_PANE: { - final WrapInTitledPaneJob job = new WrapInTitledPaneJob(this); - jobManager.push(job); + performWrap(javafx.scene.control.TitledPane.class); break; } case WRAP_IN_TOOL_BAR: { - final WrapInToolBarJob job = new WrapInToolBarJob(this); - jobManager.push(job); + performWrap(javafx.scene.control.ToolBar.class); break; } case WRAP_IN_VBOX: { - final WrapInVBoxJob job = new WrapInVBoxJob(this); - jobManager.push(job); + performWrap(javafx.scene.layout.VBox.class); break; } default: @@ -1040,63 +1027,51 @@ break; } case WRAP_IN_ANCHOR_PANE: { - final WrapInAnchorPaneJob job = new WrapInAnchorPaneJob(this); - result = job.isExecutable(); + result = canPerformWrap(javafx.scene.layout.AnchorPane.class); break; } case WRAP_IN_GRID_PANE: { - final WrapInGridPaneJob job = new WrapInGridPaneJob(this); - result = job.isExecutable(); + result = canPerformWrap(javafx.scene.layout.GridPane.class); break; } case WRAP_IN_GROUP: { - final WrapInGroupJob job = new WrapInGroupJob(this); - result = job.isExecutable(); + result = canPerformWrap(javafx.scene.Group.class); break; } case WRAP_IN_HBOX: { - final WrapInHBoxJob job = new WrapInHBoxJob(this); - result = job.isExecutable(); + result = canPerformWrap(javafx.scene.layout.HBox.class); break; } case WRAP_IN_PANE: { - final WrapInPaneJob job = new WrapInPaneJob(this); - result = job.isExecutable(); + result = canPerformWrap(javafx.scene.layout.Pane.class); break; } case WRAP_IN_SCROLL_PANE: { - final WrapInScrollPaneJob job = new WrapInScrollPaneJob(this); - result = job.isExecutable(); + result = canPerformWrap(javafx.scene.control.ScrollPane.class); break; } case WRAP_IN_SPLIT_PANE: { - final WrapInSplitPaneJob job = new WrapInSplitPaneJob(this); - result = job.isExecutable(); + result = canPerformWrap(javafx.scene.control.SplitPane.class); break; } case WRAP_IN_STACK_PANE: { - final WrapInStackPaneJob job = new WrapInStackPaneJob(this); - result = job.isExecutable(); + result = canPerformWrap(javafx.scene.layout.StackPane.class); break; } case WRAP_IN_TAB_PANE: { - final WrapInTabPaneJob job = new WrapInTabPaneJob(this); - result = job.isExecutable(); + result = canPerformWrap(javafx.scene.control.TabPane.class); break; } case WRAP_IN_TITLED_PANE: { - final WrapInTitledPaneJob job = new WrapInTitledPaneJob(this); - result = job.isExecutable(); + result = canPerformWrap(javafx.scene.control.TitledPane.class); break; } case WRAP_IN_TOOL_BAR: { - final WrapInToolBarJob job = new WrapInToolBarJob(this); - result = job.isExecutable(); + result = canPerformWrap(javafx.scene.control.ToolBar.class); break; } case WRAP_IN_VBOX: { - final WrapInVBoxJob job = new WrapInVBoxJob(this); - result = job.isExecutable(); + result = canPerformWrap(javafx.scene.layout.VBox.class); break; } default: @@ -1287,26 +1262,60 @@ /** * Performs the 'wrap' edit action. This action creates an object - * matching the specified library item and reparent all the selected objects + * matching the specified class and reparent all the selected objects * below this new object. * - * @param wrappingLibraryItem the library item describing the wrapping object + * @param wrappingClass the wrapping class */ - public void performWrap(Object wrappingLibraryItem) { - throw new UnsupportedOperationException("Not yet implemented"); //NOI18N + public void performWrap(Class<? extends Parent> wrappingClass) { + assert canPerformWrap(wrappingClass); + final AbstractWrapInJob job = AbstractWrapInJob.getWrapInJob(this, wrappingClass); + jobManager.push(job); } /** - * Returns true if the 'wrap' action is permitted with the specified - * library item. - * - * @param wrappingLibraryItem the item describing the wrapping object. + * Returns true if the 'wrap' action is permitted with the specified class. + * + * @param wrappingClass the wrapping class. * @return true if the 'wrap' action is permitted. */ - public boolean canPerformWrap(Object wrappingLibraryItem) { - throw new UnsupportedOperationException("Not yet implemented"); //NOI18N + public boolean canPerformWrap(Class<? extends Parent> wrappingClass) { + if (getClassesSupportingWrapping().contains(wrappingClass) == false) { + return false; + } + final AbstractWrapInJob job = AbstractWrapInJob.getWrapInJob(this, wrappingClass); + return job.isExecutable(); } - + + private static List<Class<? extends Parent>> classesSupportingWrapping; + + /** + * Return the list of classes that can be passed to + * {@link EditorController#performWrap(java.lang.Class)}. + * + * @return the list of classes. + */ + public synchronized static Collection<Class<? extends Parent>> getClassesSupportingWrapping() { + if (classesSupportingWrapping == null) { + classesSupportingWrapping = new ArrayList<>(); + classesSupportingWrapping.add(javafx.scene.layout.AnchorPane.class); + classesSupportingWrapping.add(javafx.scene.layout.GridPane.class); + classesSupportingWrapping.add(javafx.scene.Group.class); + classesSupportingWrapping.add(javafx.scene.layout.HBox.class); + classesSupportingWrapping.add(javafx.scene.layout.Pane.class); + classesSupportingWrapping.add(javafx.scene.control.ScrollPane.class); + classesSupportingWrapping.add(javafx.scene.control.SplitPane.class); + classesSupportingWrapping.add(javafx.scene.layout.StackPane.class); + classesSupportingWrapping.add(javafx.scene.control.TabPane.class); + classesSupportingWrapping.add(javafx.scene.control.TitledPane.class); + classesSupportingWrapping.add(javafx.scene.control.ToolBar.class); + classesSupportingWrapping.add(javafx.scene.layout.VBox.class); + classesSupportingWrapping = Collections.unmodifiableList(classesSupportingWrapping); + } + + return classesSupportingWrapping; + } + /** * Performs the copy control action. */ @@ -1461,7 +1470,28 @@ selection.select(nextSibling); } else { assert asg instanceof GridSelectionGroup; // Because of (1) - // Map to the SELECT_NEXT_ROW/SELECT_NEXT_COLUMN control action + final GridSelectionGroup gsg = (GridSelectionGroup) asg; + final FXOMObject gridPane = gsg.getParentObject(); + final DesignHierarchyMask mask = new DesignHierarchyMask(gridPane); + assert gridPane instanceof FXOMInstance; + final Set<Integer> indexes = gsg.getIndexes(); + assert indexes.size() == 1; // Because of (1) + int selectedIndex = indexes.iterator().next(); + int nextIndex = selectedIndex + 1; + int size = 0; + switch (gsg.getType()) { + case ROW: + size = mask.getRowsSize(); + break; + case COLUMN: + size = mask.getColumnsSize(); + break; + default: + assert false; + break; + } + assert nextIndex < size; // Because of (1) + selection.select((FXOMInstance) gridPane, gsg.getType(), nextIndex); } } @@ -1487,7 +1517,27 @@ final FXOMObject selectedObject = items.iterator().next(); return selectedObject.getNextSlibing() != null; } else if (asg instanceof GridSelectionGroup) { - // Map to the SELECT_NEXT_ROW/SELECT_NEXT_COLUMN control action + final GridSelectionGroup gsg = (GridSelectionGroup) asg; + final Set<Integer> indexes = gsg.getIndexes(); + if (indexes.size() != 1) { + return false; + } + final FXOMObject gridPane = gsg.getParentObject(); + final DesignHierarchyMask mask = new DesignHierarchyMask(gridPane); + int size = 0; + switch (gsg.getType()) { + case ROW: + size = mask.getRowsSize(); + break; + case COLUMN: + size = mask.getColumnsSize(); + break; + default: + assert false; + break; + } + final int index = indexes.iterator().next(); + return index < size - 1; } else { assert selection.getGroup() == null : "Add implementation for " + selection.getGroup(); //NOI18N @@ -1512,7 +1562,15 @@ selection.select(previousSibling); } else { assert asg instanceof GridSelectionGroup; // Because of (1) - // Map to the SELECT_PREVIOUS_ROW/SELECT_PREVIOUS_COLUMN control action + final GridSelectionGroup gsg = (GridSelectionGroup) asg; + final FXOMObject gridPane = gsg.getParentObject(); + assert gridPane instanceof FXOMInstance; + final Set<Integer> indexes = gsg.getIndexes(); + assert indexes.size() == 1; // Because of (1) + int selectedIndex = indexes.iterator().next(); + int previousIndex = selectedIndex - 1; + assert previousIndex >= 0; // Because of (1) + selection.select((FXOMInstance) gridPane, gsg.getType(), previousIndex); } } @@ -1538,7 +1596,13 @@ final FXOMObject selectedObject = items.iterator().next(); return selectedObject.getPreviousSlibing() != null; } else if (asg instanceof GridSelectionGroup) { - // Map to the SELECT_PREVIOUS_ROW/SELECT_PREVIOUS_COLUMN control action + final GridSelectionGroup gsg = (GridSelectionGroup) asg; + final Set<Integer> indexes = gsg.getIndexes(); + if (indexes.size() != 1) { + return false; + } + final int index = indexes.iterator().next(); + return index > 0; } else { assert selection.getGroup() == null : "Add implementation for " + selection.getGroup(); //NOI18N
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/EditorPlatform.java Fri Dec 20 15:48:27 2013 -0800 +++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/EditorPlatform.java Mon Dec 23 13:59:52 2013 +0100 @@ -75,33 +75,71 @@ public enum Theme { MODENA, - CASPIAN + MODENA_TOUCH, + CASPIAN, + CASPIAN_HIGH_CONTRAST, + CASPIAN_EMBEDDED, + CASPIAN_EMBEDDED_HIGH_CONTRAST, + CASPIAN_EMBEDDED_QVGA, + CASPIAN_EMBEDDED_QVGA_HIGH_CONTRAST } private final static URL caspianThemeUrl = Deprecation.getCaspianStylesheetURL(); + private final static URL caspianHighContrastThemeUrl = Deprecation.getCaspianHighContrastStylesheetURL(); + private final static URL caspianEmbeddedThemeUrl = Deprecation.getCaspianEmbeddedStylesheetURL(); + private final static URL caspianEmbeddedQVGAThemeUrl = Deprecation.getCaspianEmbeddedQVGAStylesheetURL(); + private final static URL caspianVirtualKeyboardThemeUrl = Deprecation.getCaspianVirtualKeyboardStylesheetURL(); private final static URL modenaThemeUrl = Deprecation.getModenaStylesheetURL(); + private final static URL modenaTouchThemeUrl = Deprecation.getModenaTouchStylesheetURL(); /** - * Returns url for locating the specified stylesheet in jfxrt.jar. + * Returns the list of url for locating the specified set of stylesheet in jfxrt.jar. * - * @param theme theme for which url should be computed - * @return url for locating the specified stylesheet. + * @param theme theme for which list of url should be computed + * @return list of url for locating the specified stylesheet. */ - public static URL getThemeStylesheetURL(Theme theme) { - final URL result; + public static List<URL> getThemeStylesheetURLs(Theme theme) { + final List<URL> result = new ArrayList<>(); switch (theme) { default: - result = null; break; case MODENA: - result = modenaThemeUrl; + result.add(modenaThemeUrl); + break; + case MODENA_TOUCH: + result.add(modenaThemeUrl); + result.add(modenaTouchThemeUrl); break; case CASPIAN: - result = caspianThemeUrl; + result.add(caspianThemeUrl); + break; + case CASPIAN_HIGH_CONTRAST: + result.add(caspianThemeUrl); + result.add(caspianHighContrastThemeUrl); + break; + case CASPIAN_EMBEDDED: + result.add(caspianThemeUrl); + result.add(caspianEmbeddedThemeUrl); + break; + case CASPIAN_EMBEDDED_HIGH_CONTRAST: + result.add(caspianThemeUrl); + result.add(caspianEmbeddedThemeUrl); + result.add(caspianHighContrastThemeUrl); + break; + case CASPIAN_EMBEDDED_QVGA: + result.add(caspianThemeUrl); + result.add(caspianEmbeddedThemeUrl); + result.add(caspianEmbeddedQVGAThemeUrl); + break; + case CASPIAN_EMBEDDED_QVGA_HIGH_CONTRAST: + result.add(caspianThemeUrl); + result.add(caspianEmbeddedThemeUrl); + result.add(caspianEmbeddedQVGAThemeUrl); + result.add(caspianHighContrastThemeUrl); break; } - assert result != null : "Missing logic for " + theme; + assert !result.isEmpty() : "Missing logic for " + theme; return result; }
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/i18n/SceneBuilderKit.properties Fri Dec 20 15:48:27 2013 -0800 +++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/i18n/SceneBuilderKit.properties Mon Dec 23 13:59:52 2013 +0100 @@ -72,6 +72,11 @@ inspector.error.title = Property error inspector.error.message = Invalid value inspector.error.details = {0} is invalid for {1} +inspector.keycombination.modifier = Modifier +inspector.keycombination.mainkey = Main Key +inspector.keycombination.none = none +inspector.keycombination.clear = Clear All +inspector.keycombination.null = none inspector.list.remove = Remove inspector.list.moveup = Move up inspector.list.movedown = Move down
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/job/PasteJob.java Fri Dec 20 15:48:27 2013 -0800 +++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/job/PasteJob.java Mon Dec 23 13:59:52 2013 +0100 @@ -73,49 +73,52 @@ = clipboardDecoder.decode(fxomDocument); assert newObjects != null; // But possible empty - // Retrieve the target FXOMObject : - // If the document is empty (root object is null), then the target - // object is null. - // If the selection is root or is empty, the target object is - // the root object. - // Otherwise, the target object is the selection common ancestor. - final FXOMObject targetObject; - if (fxomDocument.getFxomRoot() == null) { - targetObject = null; - } else { - final Selection selection = getEditorController().getSelection(); - final FXOMObject rootObject = fxomDocument.getFxomRoot(); - if (selection.isEmpty() || selection.isSelected(rootObject)) { - targetObject = rootObject; + if (newObjects.isEmpty() == false) { + + // Retrieve the target FXOMObject : + // If the document is empty (root object is null), then the target + // object is null. + // If the selection is root or is empty, the target object is + // the root object. + // Otherwise, the target object is the selection common ancestor. + final FXOMObject targetObject; + if (fxomDocument.getFxomRoot() == null) { + targetObject = null; } else { - targetObject = selection.getAncestor(); + final Selection selection = getEditorController().getSelection(); + final FXOMObject rootObject = fxomDocument.getFxomRoot(); + if (selection.isEmpty() || selection.isSelected(rootObject)) { + targetObject = rootObject; + } else { + targetObject = selection.getAncestor(); + } } - } - assert (targetObject != null) || (fxomDocument.getFxomRoot() == null); + assert (targetObject != null) || (fxomDocument.getFxomRoot() == null); - if (targetObject == null) { - // Document is empty : only one object can be inserted - if (newObjects.size() == 1) { - final FXOMObject newObject0 = newObjects.get(0); - final SetDocumentRootJob subJob = new SetDocumentRootJob( - newObject0, - getEditorController()); - result.add(subJob); - result.add(new UpdateSelectionJob(newObject0, getEditorController())); - } - } else { - // Build InsertAsSubComponent jobs - final DesignHierarchyMask targetMask = new DesignHierarchyMask(targetObject); - if (targetMask.isAcceptingSubComponent(newObjects)) { - for (FXOMObject newObject : newObjects) { - final InsertAsSubComponentJob subJob = new InsertAsSubComponentJob( - newObject, - targetObject, - targetMask.getSubComponentCount(), + if (targetObject == null) { + // Document is empty : only one object can be inserted + if (newObjects.size() == 1) { + final FXOMObject newObject0 = newObjects.get(0); + final SetDocumentRootJob subJob = new SetDocumentRootJob( + newObject0, getEditorController()); result.add(subJob); + result.add(new UpdateSelectionJob(newObject0, getEditorController())); } - result.add(new UpdateSelectionJob(newObjects, getEditorController())); + } else { + // Build InsertAsSubComponent jobs + final DesignHierarchyMask targetMask = new DesignHierarchyMask(targetObject); + if (targetMask.isAcceptingSubComponent(newObjects)) { + for (FXOMObject newObject : newObjects) { + final InsertAsSubComponentJob subJob = new InsertAsSubComponentJob( + newObject, + targetObject, + targetMask.getSubComponentCount(), + getEditorController()); + result.add(subJob); + } + result.add(new UpdateSelectionJob(newObjects, getEditorController())); + } } } }
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/job/wrap/AbstractWrapInJob.java Fri Dec 20 15:48:27 2013 -0800 +++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/job/wrap/AbstractWrapInJob.java Mon Dec 23 13:59:52 2013 +0100 @@ -55,6 +55,7 @@ import javafx.geometry.Bounds; import javafx.geometry.Point2D; import javafx.scene.Node; +import javafx.scene.Parent; import javafx.scene.layout.Region; /** @@ -70,6 +71,41 @@ public AbstractWrapInJob(EditorController editorController) { super(editorController); } + + public static AbstractWrapInJob getWrapInJob( + EditorController editorController, + Class<? extends Parent> wrappingClass) { + + assert EditorController.getClassesSupportingWrapping().contains(wrappingClass); + final AbstractWrapInJob job; + if (wrappingClass == javafx.scene.layout.AnchorPane.class) { + job = new WrapInAnchorPaneJob(editorController); + } else if (wrappingClass == javafx.scene.layout.GridPane.class) { + job = new WrapInGridPaneJob(editorController); + } else if (wrappingClass == javafx.scene.Group.class) { + job = new WrapInGroupJob(editorController); + } else if (wrappingClass == javafx.scene.layout.HBox.class) { + job = new WrapInHBoxJob(editorController); + } else if (wrappingClass == javafx.scene.layout.Pane.class) { + job = new WrapInPaneJob(editorController); + } else if (wrappingClass == javafx.scene.control.ScrollPane.class) { + job = new WrapInScrollPaneJob(editorController); + } else if (wrappingClass == javafx.scene.control.SplitPane.class) { + job = new WrapInSplitPaneJob(editorController); + } else if (wrappingClass == javafx.scene.layout.StackPane.class) { + job = new WrapInStackPaneJob(editorController); + } else if (wrappingClass == javafx.scene.control.TabPane.class) { + job = new WrapInTabPaneJob(editorController); + } else if (wrappingClass == javafx.scene.control.TitledPane.class) { + job = new WrapInTitledPaneJob(editorController); + } else if (wrappingClass == javafx.scene.control.ToolBar.class) { + job = new WrapInToolBarJob(editorController); + } else { + assert wrappingClass == javafx.scene.layout.VBox.class; // Because of (1) + job = new WrapInVBoxJob(editorController); + } + return job; + } @Override public boolean isExecutable() {
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/content/ContentPanel.css Fri Dec 20 15:48:27 2013 -0800 +++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/content/ContentPanel.css Mon Dec 23 13:59:52 2013 +0100 @@ -230,3 +230,16 @@ -fx-border-style: dotted; -fx-border-color: black; } + + +/******************************************************************************* + * * + * Resize Shadow * + * * + ******************************************************************************/ + +.outline-ring { + -fx-stroke: rgba(0,0,0,0.2); + -fx-stroke-type: inside; + -fx-fill: rgba(0,0,0,0.01); +}
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/content/ContentPanel.fxml Fri Dec 20 15:48:27 2013 -0800 +++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/content/ContentPanel.fxml Mon Dec 23 13:59:52 2013 +0100 @@ -31,18 +31,17 @@ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --> + <?import java.lang.*?> <?import java.net.*?> -<?import java.util.*?> <?import javafx.geometry.*?> <?import javafx.scene.*?> <?import javafx.scene.control.*?> <?import javafx.scene.layout.*?> -<?import javafx.scene.paint.*?> <?import javafx.scene.shape.*?> <?import javafx.scene.text.*?> -<ScrollPane fx:id="scrollPane" fitToHeight="true" fitToWidth="true" hvalue="0.5" minWidth="300.0" prefHeight="500.0" prefWidth="700.0" vvalue="0.5" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2"> +<ScrollPane fx:id="scrollPane" fitToHeight="true" fitToWidth="true" hvalue="0.5" minWidth="300.0" prefHeight="500.0" prefWidth="700.0" vvalue="0.5" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"> <content> <StackPane fx:id="workspacePane" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" style=""> <children> @@ -67,6 +66,7 @@ </Group> <Pane fx:id="glassLayer" focusTraversable="true"> <children> + <Group fx:id="outlineLayer" mouseTransparent="true" /> <Group fx:id="pringLayer" /> <Group fx:id="handleLayer" /> <Group fx:id="rudderLayer" mouseTransparent="true" />
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/content/ContentPanelController.java Fri Dec 20 15:48:27 2013 -0800 +++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/content/ContentPanelController.java Mon Dec 23 13:59:52 2013 +0100 @@ -57,6 +57,7 @@ import com.oracle.javafx.scenebuilder.kit.editor.panel.content.driver.TreeTableViewDriver; import com.oracle.javafx.scenebuilder.kit.editor.panel.content.driver.VBoxDriver; import com.oracle.javafx.scenebuilder.kit.editor.panel.content.driver.handles.AbstractHandles; +import com.oracle.javafx.scenebuilder.kit.editor.panel.content.driver.outline.NodeOutline; import com.oracle.javafx.scenebuilder.kit.editor.panel.content.util.BoundsUnion; import com.oracle.javafx.scenebuilder.kit.editor.panel.content.util.Picker; import com.oracle.javafx.scenebuilder.kit.editor.panel.content.util.ScrollPaneBooster; @@ -65,6 +66,7 @@ import com.oracle.javafx.scenebuilder.kit.editor.selection.Selection; import com.oracle.javafx.scenebuilder.kit.editor.util.ContextMenuController; import com.oracle.javafx.scenebuilder.kit.fxom.FXOMDocument; +import com.oracle.javafx.scenebuilder.kit.fxom.FXOMInstance; import com.oracle.javafx.scenebuilder.kit.fxom.FXOMObject; import com.oracle.javafx.scenebuilder.kit.metadata.util.DesignHierarchyMask; import com.oracle.javafx.scenebuilder.kit.util.Deprecation; @@ -127,13 +129,12 @@ @FXML private Group scalingGroup; @FXML private Group contentGroup; @FXML private Pane glassLayer; + @FXML private Group outlineLayer; @FXML private Group pringLayer; @FXML private Group handleLayer; @FXML private Group rudderLayer; - private boolean outlinesVisible; private boolean guidesVisible = true; - private boolean sampleDataVisible; private Paint pringColor = Color.rgb(238, 168, 47); private Paint guidesColor = Color.RED; @@ -149,6 +150,7 @@ private boolean tracingEvents; // For debugging purpose private final Picker picker = new Picker(); + private final List<NodeOutline> outlines = new ArrayList<>(); /* * Public @@ -198,7 +200,7 @@ * @return true if this content panel displays outlines. */ public boolean isOutlinesVisible() { - return outlinesVisible; + return (contentGroup != null) && (contentGroup.isVisible() == false); } /** @@ -206,7 +208,13 @@ * @param outlinesVisible true if outlines should be visible. */ public void setOutlinesVisible(boolean outlinesVisible) { - this.outlinesVisible = outlinesVisible; + if (outlinesVisible != isOutlinesVisible()) { + if (outlinesVisible) { + beginShowingOutlines(); + } else { + endShowingOutlines(); + } + } } /** @@ -226,25 +234,6 @@ public void setGuidesVisible(boolean guidesVisible) { this.guidesVisible = guidesVisible; } - - /** - * Returns true if sample data are displayed in this content panel. - * - * @return true if sample data are displayed in this content panel. - */ - public boolean isSampleDataVisible() { - return sampleDataVisible; - } - - /** - * Enables or disables sample data display in this content panel. - * - * @param sampleDataVisible true if sample data should be visible in this content panel. - */ - public void setSampleDataVisible(boolean sampleDataVisible) { - this.sampleDataVisible = sampleDataVisible; - } - /** * Returns the color used by this content panel to draw parent rings. @@ -545,6 +534,15 @@ /** + * @treatAsPrivate Returns the outline layer container. + * @return the outline layer container. + */ + public Group getOutlineLayer() { + return outlineLayer; + } + + + /** * @treatAsPrivate Returns the parent ring layer container. * @return the parent ring layer container. */ @@ -671,6 +669,9 @@ } workspaceController.setFxomDocument(fxomDocument); + if (isOutlinesVisible()) { + updateOutlines(); + } if (currentModeController != null) { currentModeController.fxomDocumentDidChange(oldDocument); } @@ -742,6 +743,9 @@ assert glassLayer != null; assert glassLayer.isMouseTransparent() == false; assert glassLayer.isFocusTraversable(); + assert outlineLayer != null; + assert outlineLayer.isMouseTransparent(); + assert outlineLayer.isFocusTraversable() == false; assert pringLayer != null; assert pringLayer.isMouseTransparent() == false; assert pringLayer.isFocusTraversable() == false; @@ -752,6 +756,7 @@ assert rudderLayer.isMouseTransparent() == true; assert rudderLayer.isFocusTraversable() == false; + outlineLayer.setManaged(false); pringLayer.setManaged(false); handleLayer.setManaged(false); rudderLayer.setManaged(false); @@ -806,6 +811,9 @@ // - new scene graph must replace the old one below contentHook // - mode controller must be informed so that it can updates handles workspaceController.sceneGraphDidChange(); + if (isOutlinesVisible()) { + updateOutlines(); + } if (currentModeController != null) { currentModeController.fxomDocumentDidRefreshSceneGraph(); } @@ -929,8 +937,8 @@ private void themeDidChange() { if (contentGroup != null) { final EditorPlatform.Theme theme = getEditorController().getTheme(); - final URL themeStyleSheet = EditorPlatform.getThemeStylesheetURL(theme); - workspaceController.setThemeStyleSheet(themeStyleSheet.toString()); + final List<URL> themeStyleSheets = EditorPlatform.getThemeStylesheetURLs(theme); + workspaceController.setThemeStyleSheets(themeStyleSheets); } } @@ -958,4 +966,129 @@ isolationGroup.getChildren().add(contentGroup); } + + /* + * Private (outline layer) + */ + + private void beginShowingOutlines() { + assert contentGroup.isVisible(); + + contentGroup.setVisible(false); + updateOutlines(); + } + + private void endShowingOutlines() { + assert contentGroup.isVisible() == false; + + final List<Node> outlineNodes = outlineLayer.getChildren(); + for (NodeOutline o : outlines) { + assert outlineNodes.contains(o.getRootNode()); + outlineNodes.remove(o.getRootNode()); + } + outlines.clear(); + contentGroup.setVisible(true); + } + + private void updateOutlines() { + assert isOutlinesVisible(); + + // Collects fxom objects associated to a node in the fxom document + final List<FXOMObject> allNodes = collectNodes(); + + for (int i = 0, count = allNodes.size(); i < count; i++) { + assert allNodes.get(i) instanceof FXOMInstance; + final FXOMInstance nodeInstance = (FXOMInstance) allNodes.get(i); + if (i < outlines.size()) { + final NodeOutline currentOutline = outlines.get(i); + if (currentOutline.getFxomObject() != nodeInstance) { + replaceOutline(i, nodeInstance); + } else { + switch(currentOutline.getState()) { + case CLEAN: + break; + case NEEDS_RECONCILE: + // scene graph associated to currentOutline has changed but h is still compatible + currentOutline.reconcile(); + break; + case NEEDS_REPLACE: + // currentOutline is no longer compatible with the new scene graph object + replaceOutline(i, nodeInstance); + break; + } + } + } else { + addOutline(outlines.size(), nodeInstance); + } + } + for (int i = allNodes.size(), count = outlines.size(); i < count; i++) { + removeOutline(allNodes.size()); + } + assert outlines.size() == allNodes.size(); + } + + private void addOutline(int i, FXOMInstance nodeInstance) { + assert outlines.size() == outlineLayer.getChildren().size(); + + final NodeOutline newOutline = new NodeOutline(this, nodeInstance); + outlines.add(i, newOutline); + outlineLayer.getChildren().add(i, newOutline.getRootNode()); + + assert outlines.size() == outlineLayer.getChildren().size(); + assert outlines.get(i).getRootNode() == outlineLayer.getChildren().get(i); + } + + private void replaceOutline(int i, FXOMInstance nodeInstance) { + removeOutline(i); + addOutline(i, nodeInstance); + } + + + private void removeOutline(int i) { + assert outlines.size() == outlineLayer.getChildren().size(); + assert outlines.get(i).getRootNode() == outlineLayer.getChildren().get(i); + + outlines.remove(i); + outlineLayer.getChildren().remove(i); + + assert outlines.size() == outlineLayer.getChildren().size(); + } + + private List<FXOMObject> collectNodes() { + final List<FXOMObject> result = new ArrayList<>(); + + final List<FXOMObject> candidates = new ArrayList<>(); + final FXOMDocument fxomDocument = getEditorController().getFxomDocument(); + if ((fxomDocument != null) && (fxomDocument.getFxomRoot() != null)) { + candidates.add(fxomDocument.getFxomRoot()); + } + + while (candidates.isEmpty() == false) { + final FXOMObject candidate = candidates.get(0); + candidates.remove(0); + if (candidate.isNode()) { + final Node sgo = (Node) candidate.getSceneGraphObject(); + if (sgo.getScene() == getPanelRoot().getScene()) { + result.add(candidate); + } + } + final DesignHierarchyMask m = new DesignHierarchyMask(candidate); + if (m.isAcceptingSubComponent()) { + for (int i = 0, c = m.getSubComponentCount(); i < c; i++) { + final FXOMObject subComponent = m.getSubComponentAtIndex(i); + candidates.add(subComponent); + } + } + for (DesignHierarchyMask.Accessory a : DesignHierarchyMask.Accessory.values()) { + if (m.isAcceptingAccessory(a)) { + final FXOMObject accessoryObject = m.getAccessory(a); + if ((accessoryObject != null) && accessoryObject.isNode()) { + candidates.add(accessoryObject); + } + } + } + } + + return result; + } }
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/content/WorkspaceController.java Fri Dec 20 15:48:27 2013 -0800 +++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/content/WorkspaceController.java Mon Dec 23 13:59:52 2013 +0100 @@ -33,6 +33,7 @@ import com.oracle.javafx.scenebuilder.kit.editor.i18n.I18N; import com.oracle.javafx.scenebuilder.kit.fxom.FXOMDocument; +import java.net.URL; import java.util.List; import javafx.animation.FadeTransition; import javafx.application.Platform; @@ -140,24 +141,24 @@ updateScalingGroup(); } - public String getThemeStyleSheet() { - final String result; + public List<String> getThemeStyleSheets() { + final List<String> result; if (contentGroup.getStylesheets().isEmpty()) { result = null; } else { - result = contentGroup.getStylesheets().get(0); + result = contentGroup.getStylesheets(); } return result; } - public void setThemeStyleSheet(String themeStyleSheet) { + public void setThemeStyleSheets(List<URL> themeStyleSheets) { assert contentGroup.getParent() instanceof Group; final Group isolationGroup = (Group) contentGroup.getParent(); assert isolationGroup.getStyleClass().contains("root"); isolationGroup.getStylesheets().clear(); - if (themeStyleSheet != null) { - isolationGroup.getStylesheets().add(themeStyleSheet); + for (URL url : themeStyleSheets) { + isolationGroup.getStylesheets().add(url.toString()); } isolationGroup.applyCss(); }
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/content/driver/gridpane/GridPaneMosaic.java Fri Dec 20 15:48:27 2013 -0800 +++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/content/driver/gridpane/GridPaneMosaic.java Mon Dec 23 13:59:52 2013 +0100 @@ -103,16 +103,16 @@ this.shouldCreateSensors = shouldCreateSensors; final List<Node> topChildren = topGroup.getChildren(); - topChildren.add(gridPath); - topChildren.add(hgapLinesGroup); - topChildren.add(vgapLinesGroup); + topChildren.add(gridPath); // Mouse transparent + topChildren.add(hgapLinesGroup); // Mouse transparent + topChildren.add(vgapLinesGroup); // Mouse transparent topChildren.add(northTrayGroup); topChildren.add(southTrayGroup); topChildren.add(westTrayGroup); topChildren.add(eastTrayGroup); - topChildren.add(targetCellShadow); - topChildren.add(targetGapShadowV); - topChildren.add(targetGapShadowH); + topChildren.add(targetCellShadow); // Mouse transparent + topChildren.add(targetGapShadowV); // Mouse transparent + topChildren.add(targetGapShadowH); // Mouse transparent topChildren.add(hgapSensorsGroup); topChildren.add(vgapSensorsGroup); gridAreaQuad.addToPath(gridPath); @@ -121,6 +121,9 @@ gridPath.getStyleClass().add("gap"); gridPath.getStyleClass().add(baseStyleClass); + hgapLinesGroup.setMouseTransparent(true); + vgapLinesGroup.setMouseTransparent(true); + targetCellShadow.setMouseTransparent(true); targetCellShadow.getStyleClass().add("gap"); targetCellShadow.getStyleClass().add("selected");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/content/driver/outline/AbstractOutline.java Mon Dec 23 13:59:52 2013 +0100 @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. + * All rights reserved. Use is subject to license terms. + * + * This file is available and licensed under the following license: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * - Neither the name of Oracle Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.oracle.javafx.scenebuilder.kit.editor.panel.content.driver.outline; + +import com.oracle.javafx.scenebuilder.kit.editor.panel.content.AbstractDecoration; +import com.oracle.javafx.scenebuilder.kit.editor.panel.content.ContentPanelController; +import com.oracle.javafx.scenebuilder.kit.fxom.FXOMObject; +import java.util.List; +import javafx.geometry.Bounds; +import javafx.geometry.Point2D; +import javafx.scene.shape.ClosePath; +import javafx.scene.shape.LineTo; +import javafx.scene.shape.MoveTo; +import javafx.scene.shape.Path; +import javafx.scene.shape.PathElement; + +/** + * + */ +public abstract class AbstractOutline<T> extends AbstractDecoration<T> { + + public static final String OUTLINE_RING_CLASS = "outline-ring"; //NOI18N + + + protected final Path ringPath = new Path(); + private final MoveTo moveTo0 = new MoveTo(); + private final LineTo lineTo1 = new LineTo(); + private final LineTo lineTo2 = new LineTo(); + private final LineTo lineTo3 = new LineTo(); + + public AbstractOutline(ContentPanelController contentPanelController, + FXOMObject fxomObject, Class<T> sceneGraphClass) { + super(contentPanelController, fxomObject, sceneGraphClass); + + final List<PathElement> ringElements = ringPath.getElements(); + ringElements.add(moveTo0); + ringElements.add(lineTo1); + ringElements.add(lineTo2); + ringElements.add(lineTo3); + ringElements.add(new ClosePath()); + ringPath.getStyleClass().add(OUTLINE_RING_CLASS); + ringPath.setMouseTransparent(true); + getRootNode().getChildren().add(ringPath); + } + + /* + * AbstractDecoration + */ + + @Override + protected void layoutDecoration() { + final Bounds b = getSceneGraphObjectBounds(); + + final boolean snapToPixel = true; + final Point2D p0 = sceneGraphObjectToDecoration(b.getMinX(), b.getMinY(), snapToPixel); + final Point2D p1 = sceneGraphObjectToDecoration(b.getMaxX(), b.getMinY(), snapToPixel); + final Point2D p2 = sceneGraphObjectToDecoration(b.getMaxX(), b.getMaxY(), snapToPixel); + final Point2D p3 = sceneGraphObjectToDecoration(b.getMinX(), b.getMaxY(), snapToPixel); + + moveTo0.setX(p0.getX()); + moveTo0.setY(p0.getY()); + lineTo1.setX(p1.getX()); + lineTo1.setY(p1.getY()); + lineTo2.setX(p2.getX()); + lineTo2.setY(p2.getY()); + lineTo3.setX(p3.getX()); + lineTo3.setY(p3.getY()); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/content/driver/outline/NodeOutline.java Mon Dec 23 13:59:52 2013 +0100 @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. + * All rights reserved. Use is subject to license terms. + * + * This file is available and licensed under the following license: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * - Neither the name of Oracle Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.oracle.javafx.scenebuilder.kit.editor.panel.content.driver.outline; + +import com.oracle.javafx.scenebuilder.kit.editor.panel.content.ContentPanelController; +import com.oracle.javafx.scenebuilder.kit.fxom.FXOMInstance; +import javafx.geometry.Bounds; +import javafx.geometry.Point2D; +import javafx.scene.Node; +import javafx.scene.transform.Transform; + +/** + * + */ +public class NodeOutline extends AbstractOutline<Node> { + + public NodeOutline(ContentPanelController contentPanelController, + FXOMInstance fxomInstance) { + super(contentPanelController, fxomInstance, Node.class); + } + + + /* + * AbstractOutline + */ + + @Override + public Bounds getSceneGraphObjectBounds() { + return getSceneGraphObject().getLayoutBounds(); + } + + @Override + public Transform getSceneGraphToSceneTransform() { + return getSceneGraphObject().getLocalToSceneTransform(); + } + + @Override + public Point2D sceneGraphObjectToScene(double x, double y) { + return getSceneGraphObject().localToScene(x, y); + } + + @Override + public Point2D sceneToSceneGraphObject(double x, double y) { + return getSceneGraphObject().sceneToLocal(x, y); + } + + @Override + protected void startListeningToSceneGraphObject() { + startListeningToLayoutBounds(getSceneGraphObject()); + startListeningToLocalToSceneTransform(getSceneGraphObject()); + } + + @Override + protected void stopListeningToSceneGraphObject() { + stopListeningToLayoutBounds(getSceneGraphObject()); + stopListeningToLocalToSceneTransform(getSceneGraphObject()); + } + +}
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/content/gesture/mouse/SelectAndMoveGesture.java Fri Dec 20 15:48:27 2013 -0800 +++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/content/gesture/mouse/SelectAndMoveGesture.java Mon Dec 23 13:59:52 2013 +0100 @@ -168,7 +168,8 @@ selectedHitObject = selection.lookupSelectedAncestor(hitObject); // Case B.2 } - if (selectedHitObject != null) { + final FXOMObject fxomRoot = hitObject.getFxomDocument().getFxomRoot(); + if ((selectedHitObject != null) && (selectedHitObject != fxomRoot)) { assert selection.getGroup() instanceof ObjectSelectionGroup;
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/css/CssContentMaker.java Fri Dec 20 15:48:27 2013 -0800 +++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/css/CssContentMaker.java Mon Dec 23 13:59:52 2013 +0100 @@ -357,9 +357,9 @@ // System.out.println("==========================="); // System.out.println("\n\n"); // printStyles(allStyles); + List<Style> matchingStyles = removeUserAgentStyles(allStyles); List<Style> notApplied = new ArrayList<>(); - for (Object obj : allStyles) { - Style style = (Style) obj; + for (Style style : matchingStyles) { if (!appliedStyles.contains(style)) { notApplied.add(style); } @@ -367,13 +367,27 @@ for (Style style : notApplied) { if (style.getDeclaration().getProperty().equals(cssMeta.getProperty())) { // We need to retrieve from allStyles, in case a lookup is shared by appliedStyles and notApplied - CssStyle cssStyle = retrieveStyle(allStyles, style); + CssStyle cssStyle = retrieveStyle(matchingStyles, style); ret.add(cssStyle); } } return ret; } + private static List<Style> removeUserAgentStyles(List<Style> allStyles) { + // With SB 2, we apply explicitly Modena/Caspian theme css on user scene graph. + // The rules that appear with an AUTHOR origin has already been considered as USER_AGENT. + // So when an internal css method (such as impl_getMatchingStyles()) is called, + // we need here to remove all USER_AGENT styles, to avoid doublons. + List<Style> matchingStyles = new ArrayList<>(); + for (Style style : allStyles) { + if (!(style.getDeclaration().getRule().getOrigin() == StyleOrigin.USER_AGENT)) { + matchingStyles.add(style); + } + } + return matchingStyles; + } + // private static void printStyles(List<Style> styles) { // for (Style style : styles) { // printStyle(style); @@ -869,12 +883,13 @@ List<CssStyle> notAppliedStyles = ps == null ? Collections.<CssStyle>emptyList() : ps.getNotAppliedStyles(); boolean hasModel = modelState().get() != null; if (hasModel) { - List<Style> styles = Deprecation.getMatchingStyles(getStyleable(), target); - for (Style style : styles) { + List<Style> allStyles = Deprecation.getMatchingStyles(getStyleable(), target); + List<Style> matchingStyles = removeUserAgentStyles(allStyles); + for (Style style : matchingStyles) { CssStyle cssStyle = new CssStyle(style); if (cssStyle.getOrigin() == StyleOrigin.USER_AGENT && !notAppliedStyles.contains(cssStyle)) { if (getStyleable().getProperty().equals(cssStyle.getCssProperty())) { - cssStyle = retrieveStyle(styles, style); + cssStyle = retrieveStyle(matchingStyles, style); ret.add(cssStyle); } }
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/hierarchy/AbstractHierarchyPanelController.java Fri Dec 20 15:48:27 2013 -0800 +++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/hierarchy/AbstractHierarchyPanelController.java Mon Dec 23 13:59:52 2013 +0100 @@ -186,6 +186,7 @@ public AbstractHierarchyPanelController(URL fxmlURL, EditorController editorController) { super(fxmlURL, I18N.getBundle(), editorController); promptLabel.getStyleClass().add("hierarchy-prompt-label"); + promptLabel.setMouseTransparent(true); } /** @@ -1074,6 +1075,9 @@ // Do not invoke dragController.end here because we always receive a // DRAG_EXITED event which will perform the termination event.setDropCompleted(true); + + // Give the focus to the hierarchy + getPanelControl().requestFocus(); } private void handleOnDragEntered(final DragEvent event) {
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/inspector/InspectorPanelController.java Fri Dec 20 15:48:27 2013 -0800 +++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/inspector/InspectorPanelController.java Mon Dec 23 13:59:52 2013 +0100 @@ -63,6 +63,7 @@ import com.oracle.javafx.scenebuilder.kit.editor.panel.inspector.editors.DividerPositionsEditor; import com.oracle.javafx.scenebuilder.kit.editor.panel.inspector.editors.TextAlignmentEditor; import com.oracle.javafx.scenebuilder.kit.editor.panel.inspector.popupeditors.BoundsPopupEditor; +import com.oracle.javafx.scenebuilder.kit.editor.panel.inspector.popupeditors.KeyCombinationPopupEditor; import com.oracle.javafx.scenebuilder.kit.editor.panel.inspector.popupeditors.PaintPopupEditor; import com.oracle.javafx.scenebuilder.kit.editor.panel.util.AbstractFxmlPanelController; import com.oracle.javafx.scenebuilder.kit.editor.selection.GridSelectionGroup; @@ -87,6 +88,7 @@ import com.oracle.javafx.scenebuilder.kit.metadata.property.value.IntegerPropertyMetadata; import com.oracle.javafx.scenebuilder.kit.metadata.property.value.Point3DPropertyMetadata; import com.oracle.javafx.scenebuilder.kit.metadata.property.value.StringPropertyMetadata; +import com.oracle.javafx.scenebuilder.kit.metadata.property.value.keycombination.KeyCombinationPropertyMetadata; import com.oracle.javafx.scenebuilder.kit.metadata.property.value.list.ListValuePropertyMetadata; import com.oracle.javafx.scenebuilder.kit.metadata.property.value.paint.PaintPropertyMetadata; import com.oracle.javafx.scenebuilder.kit.metadata.util.InspectorPath; @@ -199,6 +201,7 @@ private String searchPattern; private SectionId previousExpandedSection; private PropertyEditor lastPropertyEditorValueChanged = null; + private boolean resetInProgress = false; // // Editor pools private final Stack<Editor> i18nStringEditorPool = new Stack<>(); @@ -223,6 +226,7 @@ private final Stack<Editor> point3DEditorPool = new Stack<>(); private final Stack<Editor> dividerPositionsEditorPool = new Stack<>(); private final Stack<Editor> textAlignmentEditorPool = new Stack<>(); + private final Stack<Editor> keyCombinationPopupEditorPool = new Stack<>(); // ... // // Subsection title pool @@ -282,6 +286,7 @@ editorPools.put(Point3DEditor.class, point3DEditorPool); editorPools.put(DividerPositionsEditor.class, dividerPositionsEditorPool); editorPools.put(TextAlignmentEditor.class, textAlignmentEditorPool); + editorPools.put(KeyCombinationPopupEditor.class, keyCombinationPopupEditorPool); // ... } @@ -582,6 +587,7 @@ // - reset the value // System.out.println("Refresh all the editors in use..."); + resetInProgress = true; for (Editor editor : editorsInUse) { if (editor instanceof PropertyEditor) { @@ -595,6 +601,7 @@ } setEditorValueFromSelection(editor); } + resetInProgress = false; } private void buildExpandedSection() { @@ -1094,6 +1101,9 @@ propertyEditor.addIndeterminateListener(new ChangeListener<Boolean>() { @Override public void changed(ObservableValue<? extends Boolean> ov, Boolean oldValue, Boolean newValue) { + if (resetInProgress) { + return; + } if (!newValue) { // value is not anymore indeterminate: commit the current value updateValueInModel(propertyEditor, null, propertyEditor.getValue()); @@ -1329,6 +1339,9 @@ } else if (propMeta instanceof Point3DPropertyMetadata) { // Point3D editor propertyEditor = makePropertyEditor(Point3DEditor.class, propMeta); + } else if (propMeta instanceof KeyCombinationPropertyMetadata) { + // KeyCombination editor + propertyEditor = makePropertyEditor(KeyCombinationPopupEditor.class, propMeta); } else { // Generic editor propertyEditor = makePropertyEditor(GenericEditor.class, propMeta); @@ -1645,6 +1658,12 @@ } else { propertyEditor = new TextAlignmentEditor(propMeta, selectedClasses); } + } else if (editorClass == KeyCombinationPopupEditor.class) { + if (propertyEditor != null) { + ((KeyCombinationPopupEditor) propertyEditor).reset(propMeta, selectedClasses); + } else { + propertyEditor = new KeyCombinationPopupEditor(propMeta, selectedClasses); + } } else { if (propertyEditor != null) { ((GenericEditor) propertyEditor).reset(propMeta, selectedClasses);
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/inspector/editors/AutoSuggestEditor.java Fri Dec 20 15:48:27 2013 -0800 +++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/inspector/editors/AutoSuggestEditor.java Mon Dec 23 13:59:52 2013 +0100 @@ -360,7 +360,9 @@ @Override public void handle(ActionEvent t) { entryField.setText(suggestItem); - AutoSuggestEditor.this.getCommitListener().handle(null); + if (AutoSuggestEditor.this.getCommitListener() != null) { + AutoSuggestEditor.this.getCommitListener().handle(null); + } } }); menuButton.getItems().add(menuItem);
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/inspector/editors/StylesheetEditor.java Fri Dec 20 15:48:27 2013 -0800 +++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/inspector/editors/StylesheetEditor.java Mon Dec 23 13:59:52 2013 +0100 @@ -34,6 +34,8 @@ import com.oracle.javafx.scenebuilder.kit.editor.EditorPlatform; import com.oracle.javafx.scenebuilder.kit.editor.i18n.I18N; import com.oracle.javafx.scenebuilder.kit.metadata.property.ValuePropertyMetadata; +import com.oracle.javafx.scenebuilder.kit.util.Deprecation; +import com.sun.javafx.css.StyleManager; import java.io.File; import java.io.IOException; import java.net.MalformedURLException; @@ -52,6 +54,7 @@ import javafx.fxml.FXML; import javafx.scene.Node; import javafx.scene.Parent; +import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.MenuItem; import javafx.scene.control.TextField; @@ -197,7 +200,6 @@ void chooseStylesheet(ActionEvent event) { String[] extensions = {"*.css"}; //NOI18N - // !! Do we need a wrapper, as we had in SB 1.1, to allow tests to bypass the dialog ? FileChooser fileChooser = new FileChooser(); fileChooser.setTitle(I18N.getString("inspector.select.css")); fileChooser.getExtensionFilters().add( @@ -223,6 +225,12 @@ // Add editor item addItem(new StylesheetItem(this, url)); + // Workaround for RT-34863: Reload of an updated css file has no effect. + // This reset the whole CSS from top. Would need to be moved on the FXOM side. + Scene scene = root.getScene(); + StyleManager.getInstance().forget(scene); + Deprecation.reapplyCSS(scene.getRoot()); + userUpdateValueProperty(getValue()); }
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/inspector/popupeditors/BoundsPopupEditor.fxml Fri Dec 20 15:48:27 2013 -0800 +++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/inspector/popupeditors/BoundsPopupEditor.fxml Mon Dec 23 13:59:52 2013 +0100 @@ -1,4 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> + <!-- Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. Use is subject to license terms. @@ -30,87 +31,80 @@ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --> + <?import java.lang.*?> <?import javafx.scene.control.*?> <?import javafx.scene.layout.*?> -<GridPane hgap="10.0" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="171.0" prefWidth="181.0" stylesheets="file:/C:/wksfx/sb20/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/inspector/Inspector.css" vgap="5.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"> - <children> - <Label text="min:" /> - <Label text="max:" GridPane.rowIndex="1" /> - <Label text="size:" GridPane.rowIndex="2" /> - <HBox spacing="10.0" GridPane.columnIndex="1" GridPane.halignment="LEFT" GridPane.hgrow="ALWAYS" GridPane.rowIndex="0"> - <children> - <VBox alignment="CENTER" HBox.hgrow="ALWAYS"> - <children> +<GridPane hgap="7.0" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" stylesheets="@../Inspector.css" vgap="5.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"> + <children> + <Label maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" text="min:" /> + <Label maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" text="max:" GridPane.rowIndex="1" /> + <Label maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" text="size:" GridPane.rowIndex="2" /> + <VBox alignment="CENTER" GridPane.columnIndex="1" HBox.hgrow="ALWAYS"> + <children> <Label styleClass="label, small-label" text="X" /> <Label fx:id="minX" text="10" /> - </children> - </VBox> - <VBox alignment="CENTER" HBox.hgrow="ALWAYS"> - <children> + </children> + </VBox> + <VBox alignment="CENTER" GridPane.columnIndex="1" GridPane.rowIndex="1" HBox.hgrow="ALWAYS"> + <children> + <Label styleClass="label, small-label" text="X" /> + <Label fx:id="maxX" text="10" /> + </children> + </VBox> + <VBox alignment="CENTER" GridPane.columnIndex="1" GridPane.rowIndex="2" HBox.hgrow="ALWAYS"> + <children> + <Label styleClass="label, small-label" text="Width" /> + <Label fx:id="width" text="10" /> + </children> + </VBox> + <VBox alignment="CENTER" GridPane.columnIndex="2" HBox.hgrow="ALWAYS"> + <children> <Label styleClass="label, small-label" text="Y" /> <Label fx:id="minY" text="10" /> - </children> - </VBox> - <VBox alignment="CENTER" HBox.hgrow="ALWAYS"> - <children> + </children> + </VBox> + <VBox alignment="CENTER" GridPane.columnIndex="3" HBox.hgrow="ALWAYS"> + <children> <Label styleClass="label, small-label" text="Z" /> <Label fx:id="minZ" text="0" /> - </children> - </VBox> - </children> - </HBox><HBox spacing="10.0" GridPane.columnIndex="1" GridPane.rowIndex="1" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"> -<children> -<VBox alignment="CENTER" HBox.hgrow="ALWAYS"> -<children> -<Label styleClass="label, small-label" text="X" /> -<Label fx:id="maxX" text="10" /> -</children> -</VBox> -<VBox alignment="CENTER" HBox.hgrow="ALWAYS"> -<children> -<Label styleClass="label, small-label" text="Y" /> -<Label fx:id="maxY" text="10" /> -</children> -</VBox> -<VBox alignment="CENTER" HBox.hgrow="ALWAYS"> -<children> -<Label styleClass="label, small-label" text="Z" /> -<Label fx:id="maxZ" text="0" /> -</children> -</VBox> -</children> -</HBox><HBox spacing="10.0" GridPane.columnIndex="1" GridPane.rowIndex="2" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"> -<children> -<VBox alignment="CENTER" HBox.hgrow="ALWAYS"> -<children> -<Label styleClass="label, small-label" text="Width" /> -<Label fx:id="width" text="10" /> -</children> -</VBox> -<VBox alignment="CENTER" HBox.hgrow="ALWAYS"> -<children> -<Label styleClass="label, small-label" text="Height" /> -<Label fx:id="height" text="10" /> -</children> -</VBox> -<VBox alignment="CENTER" HBox.hgrow="ALWAYS"> -<children> -<Label styleClass="label, small-label" text="Depth" /> -<Label fx:id="depth" text="0" /> -</children> -</VBox> -</children> -</HBox> - </children> - <columnConstraints> - <ColumnConstraints halignment="RIGHT" hgrow="SOMETIMES" maxWidth="110.0" minWidth="10.0" prefWidth="67.0" /> - <ColumnConstraints hgrow="ALWAYS" maxWidth="152.0" minWidth="10.0" prefWidth="152.0" /> - </columnConstraints> - <rowConstraints> + </children> + </VBox> + <VBox alignment="CENTER" GridPane.columnIndex="2" GridPane.rowIndex="1" HBox.hgrow="ALWAYS"> + <children> + <Label styleClass="label, small-label" text="Y" /> + <Label fx:id="maxY" text="10" /> + </children> + </VBox> + <VBox alignment="CENTER" GridPane.columnIndex="3" GridPane.rowIndex="1" HBox.hgrow="ALWAYS"> + <children> + <Label styleClass="label, small-label" text="Z" /> + <Label fx:id="maxZ" text="0" /> + </children> + </VBox> + <VBox alignment="CENTER" GridPane.columnIndex="2" GridPane.rowIndex="2" HBox.hgrow="ALWAYS"> + <children> + <Label styleClass="label, small-label" text="Height" /> + <Label fx:id="height" text="10" /> + </children> + </VBox> + <VBox alignment="CENTER" GridPane.columnIndex="3" GridPane.rowIndex="2" HBox.hgrow="ALWAYS"> + <children> + <Label styleClass="label, small-label" text="Depth" /> + <Label fx:id="depth" text="0" /> + </children> + </VBox> + </children> + <columnConstraints> + <ColumnConstraints halignment="RIGHT" hgrow="SOMETIMES" maxWidth="-Infinity" minWidth="-Infinity" /> + <ColumnConstraints hgrow="ALWAYS" maxWidth="-Infinity" minWidth="-Infinity" /> + <ColumnConstraints hgrow="ALWAYS" maxWidth="-Infinity" minWidth="-Infinity" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" /> + <ColumnConstraints hgrow="ALWAYS" maxWidth="-Infinity" minWidth="-Infinity" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" /> + </columnConstraints> + <rowConstraints> <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> - </rowConstraints> - </GridPane> + </rowConstraints> +</GridPane>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/inspector/popupeditors/KeyCombinationPopupEditor.fxml Mon Dec 23 13:59:52 2013 +0100 @@ -0,0 +1,61 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (c) 2012, 2013, Oracle and/or its affiliates. + All rights reserved. Use is subject to license terms. + + This file is available and licensed under the following license: + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + - Neither the name of Oracle Corporation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--> +<?import java.lang.*?> +<?import javafx.collections.*?> +<?import javafx.scene.control.*?> +<?import javafx.scene.layout.*?> + +<GridPane hgap="10.0" vgap="5.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"> + <columnConstraints> + <ColumnConstraints halignment="RIGHT" hgrow="ALWAYS" /> + <ColumnConstraints halignment="LEFT" hgrow="ALWAYS" /> + </columnConstraints> + <rowConstraints> + <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="ALWAYS" /> + <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="ALWAYS" /> + <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="ALWAYS" /> + </rowConstraints> +<children> + <Label text="Main key" GridPane.rowIndex="1" /> + <StackPane fx:id="mainKeySp" maxWidth="1.7976931348623157E308" GridPane.columnIndex="1" GridPane.hgrow="ALWAYS" GridPane.rowIndex="1" /> + <Button fx:id="clearAllBt" mnemonicParsing="false" text="Clear all" GridPane.columnIndex="1" GridPane.halignment="RIGHT" GridPane.rowIndex="2" /><Label text="Modifier 1" /><ChoiceBox prefHeight="25.0" prefWidth="94.0" GridPane.columnIndex="1" xmlns:fx="http://javafx.com/fxml"> + <items> + <FXCollections fx:factory="observableArrayList"> + <String fx:value="Item 1" /> + <String fx:value="Item 2" /> + <String fx:value="Item 3" /> + </FXCollections> + </items> +</ChoiceBox> +</children> +</GridPane>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/inspector/popupeditors/KeyCombinationPopupEditor.java Mon Dec 23 13:59:52 2013 +0100 @@ -0,0 +1,549 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. + * All rights reserved. Use is subject to license terms. + * + * This file is available and licensed under the following license: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * - Neither the name of Oracle Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.oracle.javafx.scenebuilder.kit.editor.panel.inspector.popupeditors; + +import com.oracle.javafx.scenebuilder.kit.editor.i18n.I18N; +import com.oracle.javafx.scenebuilder.kit.editor.panel.inspector.editors.AutoSuggestEditor; +import com.oracle.javafx.scenebuilder.kit.editor.panel.inspector.editors.EditorUtils; +import com.oracle.javafx.scenebuilder.kit.metadata.property.ValuePropertyMetadata; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Locale; +import java.util.Set; +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; +import javafx.event.ActionEvent; +import javafx.event.EventHandler; +import javafx.fxml.FXML; +import javafx.scene.Node; +import javafx.scene.Parent; +import javafx.scene.control.Button; +import javafx.scene.control.ChoiceBox; +import javafx.scene.control.Label; +import javafx.scene.input.KeyCharacterCombination; +import javafx.scene.input.KeyCode; +import javafx.scene.input.KeyCodeCombination; +import javafx.scene.input.KeyCombination; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.StackPane; +import javafx.util.StringConverter; + +/** + * KeyCombination popup editor (for keyboard shortcuts). + * + */ +public class KeyCombinationPopupEditor extends PopupEditor { + + @FXML + StackPane mainKeySp; + @FXML + Button clearAllBt; + + private final GridPane gridPane; + private static final int NB_MODIFIERS_MAX = 5; + private final ArrayList<ModifierRow> modifierRows = new ArrayList<>(); + private KeyCombination.ModifierValue alt; + private KeyCombination.ModifierValue control; + private KeyCombination.ModifierValue meta; + private KeyCombination.ModifierValue shift; + private KeyCombination.ModifierValue shortcut; + private MainKey mainKey; + private final KeyCombination.Modifier[] keyCombinationModifiers = { + KeyCombination.ALT_ANY, KeyCombination.ALT_DOWN, + KeyCombination.CONTROL_ANY, KeyCombination.CONTROL_DOWN, + KeyCombination.META_ANY, KeyCombination.META_DOWN, + KeyCombination.SHIFT_ANY, KeyCombination.SHIFT_DOWN, + KeyCombination.SHORTCUT_ANY, KeyCombination.SHORTCUT_DOWN}; + + @SuppressWarnings("LeakingThisInConstructor") + public KeyCombinationPopupEditor(ValuePropertyMetadata propMeta, Set<Class<?>> selectedClasses) { + super(propMeta, selectedClasses); + Parent root = EditorUtils.loadPopupFxml("KeyCombinationPopupEditor.fxml", this); //NOI18N + assert root instanceof GridPane; + gridPane = (GridPane) root; + + initialize(); + } + + // Method to please FindBugs + private void initialize() { + // Build suggested key code list + List<Field> keyCodes = Arrays.asList(KeyCode.class.getFields()); + List<String> keyCodesStr = new ArrayList<>(); + for (Field keyCode : keyCodes) { + keyCodesStr.add(keyCode.getName()); + } + + mainKey = new MainKey(keyCodesStr); + mainKeySp.getChildren().add(mainKey.getNode()); + + clearAllBt.setText(I18N.getString("inspector.keycombination.clear")); + clearAllBt.setOnAction(new EventHandler<ActionEvent>() { + + @Override + public void handle(ActionEvent t) { + resetPopupContent(); + commit(null); + } + }); + + // Plug to the menu button. + plugEditor(this, gridPane); + + buildUI(); + } + + private String getValueAsString(Object value) { + String valueAsString; + if (isIndeterminate()) { + valueAsString = "-"; //NOI18N + } else { + valueAsString = (value != null) ? value.toString() : I18N.getString("inspector.keycombination.null"); //NOI18N + } + return valueAsString; + } + + // + // Interface PopupEditor.InputValue. + // Methods called by PopupEditor. + // + @Override + public void setPopupContentValue(Object value) { + + if (value != null) { + // Empty the editor + resetState(); + resetUI(); + assert value instanceof KeyCombination; + // Apply the new keyCombination + buildContent((KeyCombination) value); + } else { + resetPopupContent(); + } + + // Update the menu button string + displayValueAsString(getValueAsString(value)); + } + + @Override + public void resetPopupContent() { + // Set the editor to its initial value + resetState(); + buildUI(); + displayValueAsString(getValueAsString(null)); + } + + private void resetState() { + modifierRows.clear(); + mainKey.setKeyCode(null); + } + + private void resetUI() { + gridPane.getChildren().clear(); + gridPane.getRowConstraints().clear(); + } + + private void buildContent(KeyCombination keyCombination) { + assert keyCombination != null; + + // Build the modifiers rows + modifierRows.clear(); + KeyCombination.Modifier modifier1 = null; + alt = keyCombination.getAlt(); + if (alt != KeyCombination.ModifierValue.UP) { + if (alt == KeyCombination.ModifierValue.DOWN) { + modifier1 = KeyCombination.ALT_DOWN; + } else if (alt == KeyCombination.ModifierValue.ANY) { + modifier1 = KeyCombination.ALT_ANY; + } + createModifierRow(modifier1); + } + + KeyCombination.Modifier modifier2 = null; + control = keyCombination.getControl(); + if (control != KeyCombination.ModifierValue.UP) { + if (control == KeyCombination.ModifierValue.DOWN) { + modifier2 = KeyCombination.CONTROL_DOWN; + } else if (control == KeyCombination.ModifierValue.ANY) { + modifier2 = KeyCombination.CONTROL_ANY; + } + createModifierRow(modifier2); + } + + KeyCombination.Modifier modifier3 = null; + meta = keyCombination.getMeta(); + if (meta != KeyCombination.ModifierValue.UP) { + if (meta == KeyCombination.ModifierValue.DOWN) { + modifier3 = KeyCombination.META_DOWN; + } else if (meta == KeyCombination.ModifierValue.ANY) { + modifier3 = KeyCombination.META_ANY; + } + createModifierRow(modifier3); + } + + KeyCombination.Modifier modifier4 = null; + shift = keyCombination.getShift(); + if (shift != KeyCombination.ModifierValue.UP) { + if (shift == KeyCombination.ModifierValue.DOWN) { + modifier4 = KeyCombination.SHIFT_DOWN; + } else if (shift == KeyCombination.ModifierValue.ANY) { + modifier4 = KeyCombination.SHIFT_ANY; + } + createModifierRow(modifier4); + } + + KeyCombination.Modifier modifier5 = null; + shortcut = keyCombination.getShortcut(); + if (shortcut != KeyCombination.ModifierValue.UP) { + if (shortcut == KeyCombination.ModifierValue.DOWN) { + modifier5 = KeyCombination.SHORTCUT_DOWN; + } else if (shortcut == KeyCombination.ModifierValue.ANY) { + modifier5 = KeyCombination.SHORTCUT_ANY; + } + createModifierRow(modifier5); + } + + // Handle the main key + KeyCode keyCode = null; + if (keyCombination instanceof KeyCodeCombination) { + keyCode = ((KeyCodeCombination) keyCombination).getCode(); + } else if (keyCombination instanceof KeyCharacterCombination) { + keyCode = KeyCode.getKeyCode(((KeyCharacterCombination) keyCombination).getCharacter()); + } + mainKey.setKeyCode(keyCode); + + // Build the UI + buildUI(); + + commit(keyCombination); + } + + private void commit(KeyCombination keyCombination) { + commitValue(keyCombination, getValueAsString(keyCombination)); + } + + private KeyCombination createKeyCombination() { + if (mainKey.isEmpty()) { + return null; + } + KeyCodeCombination keyComb = null; + List<KeyCombination.Modifier> modifiers = new ArrayList<>(); + for (ModifierRow modifier : modifierRows) { + if (!modifier.isEmpty()) { + if (modifiers.contains(modifier.getModifier())) { + // doublon: invalid + return null; + } + modifiers.add(modifier.getModifier()); + } + } + if (modifiers.isEmpty()) { + // no modifier: invalid + return null; + } + try { + keyComb = new KeyCodeCombination(mainKey.getKeyCode(), modifiers.toArray(new KeyCombination.Modifier[1])); + } catch (IllegalArgumentException | NullPointerException ex) { + System.out.println("Invalid key combination" + ex); //NOI18N + } catch (RuntimeException ex) { + System.out.println(ex.getMessage() + ex); + } + return keyComb; + } + + private List<KeyCombination.Modifier> getModifierConstants() { + ArrayList<KeyCombination.Modifier> mods = new ArrayList<>(); + for (KeyCombination.Modifier modifier : keyCombinationModifiers) { + boolean alreadyUsed = false; + for (ModifierRow row : modifierRows) { + if (!row.isEmpty()) { + if (row.getModifier().getKey().equals(modifier.getKey())) { + // modifier already used + alreadyUsed = true; + break; + } + } + } + if (!alreadyUsed) { + mods.add(modifier); + } + } + mods.add(null); + Collections.sort(mods, new ModifierComparator()); + return mods; + } + + private static class ModifierComparator implements Comparator<KeyCombination.Modifier> { + + @Override + public int compare(KeyCombination.Modifier o1, KeyCombination.Modifier o2) { + if (o1 == null || o2 == null) { + return -1; + } + String str1 = o1.getKey().toString() + o1.getValue().toString(); + String str2 = o2.getKey().toString() + o2.getValue().toString(); + return str1.compareTo(str2); + } + } + + private ChoiceBox<KeyCombination.Modifier> createModifierChoiceBox(KeyCombination.Modifier modifier) { + final ChoiceBox<KeyCombination.Modifier> modifierChoiceBox = new ChoiceBox<>(); + EditorUtils.makeWidthStretchable(modifierChoiceBox); + modifierChoiceBox.setConverter(new ModifierConverter()); + modifierChoiceBox.getItems().setAll(getModifierConstants()); + if (modifier != null) { + modifierChoiceBox.getSelectionModel().select(modifier); + } + + modifierChoiceBox.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<KeyCombination.Modifier>() { + @Override + public void changed(ObservableValue<? extends KeyCombination.Modifier> observable, + KeyCombination.Modifier oldValue, KeyCombination.Modifier newValue) { + if (!mainKey.isEmpty()) { + KeyCombination kc = createKeyCombination(); + if (kc != null) { + commit(kc); + } + } + buildUI(); + } + }); + return modifierChoiceBox; + } + + private void buildUI() { + resetUI(); + + // Cleanup: remove empty rows + ArrayList<ModifierRow> emptyRows = new ArrayList<>(); + for (ModifierRow row : modifierRows) { + if (row.isEmpty()) { + emptyRows.add(row); + } + } + modifierRows.removeAll(emptyRows); + + int lineIndex = 0; + for (ModifierRow row : modifierRows) { + addModifierRow(row, lineIndex); + lineIndex++; + } + + // add an empty row + boolean added = false; + if (modifierRows.size() < NB_MODIFIERS_MAX) { + added = addEmptyModifierIfNeeded(); + } + if (added) { + lineIndex++; + } + + // add mainKey + Label mainKeyLabel = new Label(I18N.getString("inspector.keycombination.mainkey")); + gridPane.add(mainKeyLabel, 0, lineIndex); + gridPane.add(mainKey.getNode(), 1, lineIndex); + lineIndex++; + + // add reset button + gridPane.add(clearAllBt, 1, lineIndex); + } + + private boolean addEmptyModifierIfNeeded() { + for (ModifierRow row : modifierRows) { + if (row.isEmpty()) { + return false; + } + } + addModifierRow(createModifierRow(null), modifierRows.size() - 1); + return true; + } + + private void addModifierRow(ModifierRow row, int lineIndex) { + row.getLabel().setText(I18N.getString("inspector.keycombination.modifier") + + " " + (lineIndex + 1)); //NOI18N + gridPane.add(row.getLabel(), 0, lineIndex); + gridPane.add(row.getChoiceBox(), 1, lineIndex); + } + + private ModifierRow createModifierRow(KeyCombination.Modifier modifier) { + ChoiceBox<KeyCombination.Modifier> choiceBox = createModifierChoiceBox(modifier); + ModifierRow row = new ModifierRow(choiceBox); + modifierRows.add(row); + return row; + } + + @SuppressWarnings("LeakingThisInConstructor") + private class MainKey extends AutoSuggestEditor { + + public MainKey(List<String> suggestedKeys) { + super("", null, suggestedKeys); //NOI18N + ChangeListener<String> textPropertyChange = new ChangeListener<String>() { + + @Override + public void changed(ObservableValue<? extends String> ov, String prevText, String newText) { + if (!newText.isEmpty()) { + KeyCombination kc = createKeyCombination(); + if (kc != null) { + commit(kc); + } + } + } + }; + getTextField().textProperty().addListener(textPropertyChange); + } + + public Node getNode() { + return getValueEditor(); + } + + public void setKeyCode(KeyCode keyCode) { + setValue((keyCode != null) ? keyCode.toString() : "");//NOI18N + } + + public KeyCode getKeyCode() { + String valStr = getTextField().getText(); + if (valStr.isEmpty()) { + return null; + } + if (valStr.length() == 1) { + // single character : put it in uppercase for convenience (lowercase char are not supported) + valStr = valStr.toUpperCase(Locale.ROOT); + } + + KeyCode keyCode = null; + try { + keyCode = KeyCode.valueOf(valStr); + } catch (Exception ex) { + System.out.println("Cannot find key code for " + valStr + "\n" + ex); //NOI18N + } + return keyCode; + } + + public boolean isEmpty() { + return getKeyCode() == null; + } + } + + private static class ModifierRow { + + private Label label; + private ChoiceBox<KeyCombination.Modifier> choiceBox; + + public ModifierRow(ChoiceBox<KeyCombination.Modifier> choiceBox) { + this.label = new Label(); + this.choiceBox = choiceBox; + } + + public Label getLabel() { + return label; + } + + public void setLabel(Label label) { + this.label = label; + } + + public ChoiceBox<KeyCombination.Modifier> getChoiceBox() { + return choiceBox; + } + + public void setChoiceBox(ChoiceBox<KeyCombination.Modifier> choiceBox) { + this.choiceBox = choiceBox; + } + + public KeyCombination.Modifier getModifier() { + return choiceBox.getSelectionModel().getSelectedItem(); + } + + public boolean isEmpty() { + return getModifier() == null; + } + } + + private static class ModifierConverter extends StringConverter<KeyCombination.Modifier> { + + @Override + public String toString(KeyCombination.Modifier object) { + if (object == null) { + return I18N.getString("inspector.keycombination.none"); + } + return object.getKey() + "_" + object.getValue(); //NOI18N + } + + @Override + public KeyCombination.Modifier fromString(String string) { + if (string.equals(I18N.getString("inspector.keycombination.none"))) { + return null; + } + if (string.startsWith(KeyCode.ALT.getName())) { + if (string.endsWith(KeyCombination.ModifierValue.DOWN.name())) { + return KeyCombination.ALT_DOWN; + } else if (string.endsWith(KeyCombination.ModifierValue.ANY.name())) { + return KeyCombination.ALT_ANY; + } + } + if (string.startsWith(KeyCode.CONTROL.getName())) { + if (string.endsWith(KeyCombination.ModifierValue.DOWN.name())) { + return KeyCombination.CONTROL_DOWN; + } else if (string.endsWith(KeyCombination.ModifierValue.ANY.name())) { + return KeyCombination.CONTROL_ANY; + } + } + if (string.startsWith(KeyCode.META.getName())) { + if (string.endsWith(KeyCombination.ModifierValue.DOWN.name())) { + return KeyCombination.META_DOWN; + } else if (string.endsWith(KeyCombination.ModifierValue.ANY.name())) { + return KeyCombination.META_ANY; + } + } + if (string.startsWith(KeyCode.SHIFT.getName())) { + if (string.endsWith(KeyCombination.ModifierValue.DOWN.name())) { + return KeyCombination.SHIFT_DOWN; + } else if (string.endsWith(KeyCombination.ModifierValue.ANY.name())) { + return KeyCombination.SHIFT_ANY; + } + } + if (string.startsWith(KeyCode.SHORTCUT.getName())) { + if (string.endsWith(KeyCombination.ModifierValue.DOWN.name())) { + return KeyCombination.SHORTCUT_DOWN; + } else if (string.endsWith(KeyCombination.ModifierValue.ANY.name())) { + return KeyCombination.SHORTCUT_ANY; + } + } + return null; + } + } + +}
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/library/LibraryPanelController.java Fri Dec 20 15:48:27 2013 -0800 +++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/library/LibraryPanelController.java Mon Dec 23 13:59:52 2013 +0100 @@ -155,6 +155,13 @@ processImportJarFxml(importedFiles); } + /** + * @treatAsPrivate Perform the import of the selection + */ + public void performImportSelection(List<FXOMObject> objects) { + processInternalImport(objects); + } + /* * AbstractPanelController */ @@ -519,7 +526,7 @@ // System.out.println("libPane onDragDropped"); AbstractDragSource dragSource = getEditorController().getDragController().getDragSource(); if (dragSource != null && dragSource instanceof DocumentDragSource) { - processInternalImport((DocumentDragSource)dragSource); + processInternalImport(((DocumentDragSource)dragSource).getDraggedObjects()); } else { initiateImportDialog = false; jarAndFxmlFiles.clear(); @@ -622,7 +629,7 @@ // SceneBuilder (from Content or Hierarchy). // We stop the watching thread to avoid potential parsing of a file that // would not yet be properly finalized on disk. - private void processInternalImport(DocumentDragSource source) { + private void processInternalImport(List<FXOMObject> objects) { String userLibraryPathString = ((UserLibrary) getEditorController().getLibrary()).getPath(); Path libPath = Paths.get(userLibraryPathString); ((UserLibrary) getEditorController().getLibrary()).stopWatching(); @@ -631,7 +638,7 @@ try { // The selection can be multiple, in which case each asset is processed // separately. The handling of dependencies will be addressed later on. - for (FXOMObject asset : source.getDraggedObjects()) { + for (FXOMObject asset : objects) { // Create an FXML layout as a String ArrayList<FXOMObject> selection = new ArrayList<>(); selection.add(asset);
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/util/ContextMenuController.java Fri Dec 20 15:48:27 2013 -0800 +++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/util/ContextMenuController.java Mon Dec 23 13:59:52 2013 +0100 @@ -88,8 +88,6 @@ private final MenuItem wrapInGroupMenuItem; private final MenuItem unwrapMenuItem; private final Menu gridPaneMenu; - private final MenuItem selectNextRowMenuItem; - private final MenuItem selectNextColumnMenuItem; private final MenuItem moveRowAboveMenuItem; private final MenuItem moveRowBelowMenuItem; private final MenuItem moveColumnBeforeMenuItem; @@ -230,16 +228,10 @@ wrapInVBoxMenuItem, wrapInGroupMenuItem); unwrapMenuItem = new MenuItem("Unwrap"); - wrapInGroupMenuItem.setOnAction(onActionEventHandler); + unwrapMenuItem.setOnAction(onActionEventHandler); unwrapMenuItem.setUserData(new EditActionController(EditAction.UNWRAP)); // GridPane specifics gridPaneMenu = new Menu("GridPane"); - selectNextRowMenuItem = new MenuItem("Select Next Row"); - selectNextRowMenuItem.setOnAction(onActionEventHandler); - selectNextRowMenuItem.setUserData(new ControlActionController(ControlAction.SELECT_NEXT_ROW)); - selectNextColumnMenuItem = new MenuItem("Select Next Column"); - selectNextColumnMenuItem.setOnAction(onActionEventHandler); - selectNextColumnMenuItem.setUserData(new ControlActionController(ControlAction.SELECT_NEXT_COLUMN)); moveRowAboveMenuItem = new MenuItem("Move Row Above"); moveRowAboveMenuItem.setOnAction(onActionEventHandler); moveRowAboveMenuItem.setUserData(new EditActionController(EditAction.MOVE_ROW_ABOVE)); @@ -337,9 +329,6 @@ contextMenu.getItems().addAll( deleteMenuItem, new SeparatorMenuItem(), - selectNextRowMenuItem, - selectNextColumnMenuItem, - new SeparatorMenuItem(), moveRowAboveMenuItem, moveRowBelowMenuItem, moveColumnBeforeMenuItem, @@ -444,9 +433,6 @@ // Add actions on the GridPane rows/columns if (canPerformGridPaneActions()) { gridPaneMenu.getItems().addAll( - selectNextRowMenuItem, - selectNextColumnMenuItem, - new SeparatorMenuItem(), moveRowAboveMenuItem, moveRowBelowMenuItem, moveColumnBeforeMenuItem,
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/fxom/FXOMCollection.java Fri Dec 20 15:48:27 2013 -0800 +++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/fxom/FXOMCollection.java Mon Dec 23 13:59:52 2013 +0100 @@ -119,6 +119,12 @@ */ @Override + public List<FXOMObject> getChildObjects() { + return Collections.unmodifiableList(items); + } + + + @Override public FXOMObject searchWithSceneGraphObject(Object sceneGraphObject) { FXOMObject result; @@ -211,6 +217,15 @@ } } + @Override + protected void collectEventHandlers(List<FXOMPropertyT> result) { + if (getSceneGraphObject() != null) { + for (FXOMObject i : items) { + i.collectEventHandlers(result); + } + } + } + /* * FXOMNode */
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/fxom/FXOMInstance.java Fri Dec 20 15:48:27 2013 -0800 +++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/fxom/FXOMInstance.java Mon Dec 23 13:59:52 2013 +0100 @@ -33,6 +33,7 @@ import com.oracle.javafx.scenebuilder.kit.fxom.glue.GlueElement; import com.oracle.javafx.scenebuilder.kit.metadata.util.PropertyName; +import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; @@ -130,6 +131,20 @@ */ @Override + public List<FXOMObject> getChildObjects() { + final List<FXOMObject> result = new ArrayList<>(); + + for (FXOMProperty p : properties.values()) { + if (p instanceof FXOMPropertyC) { + final FXOMPropertyC pc = (FXOMPropertyC) p; + result.addAll(pc.getValues()); + } + } + return result; + } + + + @Override public FXOMObject searchWithSceneGraphObject(Object sceneGraphObject) { FXOMObject result; @@ -271,6 +286,27 @@ } } + @Override + protected void collectEventHandlers(List<FXOMPropertyT> result) { + if (getSceneGraphObject() != null) { + for (FXOMProperty p : properties.values()) { + if (p instanceof FXOMPropertyT) { + final FXOMPropertyT pt = (FXOMPropertyT) p; + if (pt.getValue().startsWith("#")) { + result.add(pt); + } + } + } + for (FXOMProperty p : properties.values()) { + if (p instanceof FXOMPropertyC) { + for (FXOMObject v : ((FXOMPropertyC)p).getValues()) { + v.collectEventHandlers(result); + } + } + } + } + } + /* * FXOMNode */
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/fxom/FXOMIntrinsic.java Fri Dec 20 15:48:27 2013 -0800 +++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/fxom/FXOMIntrinsic.java Mon Dec 23 13:59:52 2013 +0100 @@ -33,6 +33,7 @@ import com.oracle.javafx.scenebuilder.kit.fxom.glue.GlueElement; import com.oracle.javafx.scenebuilder.kit.metadata.util.PropertyName; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; @@ -114,6 +115,13 @@ */ @Override + public List<FXOMObject> getChildObjects() { + // Intrinsics have not children + return Collections.emptyList(); + } + + + @Override public FXOMObject searchWithSceneGraphObject(Object sceneGraphObject) { FXOMObject result; @@ -177,6 +185,10 @@ // Nothing to collect in this kind of object } + @Override + protected void collectEventHandlers(List<FXOMPropertyT> result) { + // Nothing to collect in this kind of object + } /*
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/fxom/FXOMObject.java Fri Dec 20 15:48:27 2013 -0800 +++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/fxom/FXOMObject.java Mon Dec 23 13:59:52 2013 +0100 @@ -393,6 +393,16 @@ protected abstract void collectObjectWithSceneGraphObjectClass(Class<?> sceneGraphObjectClass, List<FXOMObject> result); + public List<FXOMPropertyT> collectEventHandlers() { + final List<FXOMPropertyT> result = new ArrayList<>(); + + collectEventHandlers(result); + + return result; + } + + protected abstract void collectEventHandlers(List<FXOMPropertyT> result); + /* * Utilities */ @@ -410,6 +420,8 @@ return result; } + public abstract List<FXOMObject> getChildObjects(); + public boolean isDescendantOf(FXOMObject other) { final boolean result;
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/fxom/FXOMRefresher.java Fri Dec 20 15:48:27 2013 -0800 +++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/fxom/FXOMRefresher.java Mon Dec 23 13:59:52 2013 +0100 @@ -56,7 +56,9 @@ document.getLocation(), document.getClassLoader(), document.getResources()); + final TransientStateBackup backup = new TransientStateBackup(document); refreshDocument(document, newDocument); + backup.restore(); } catch(IOException x) { final StringBuilder sb = new StringBuilder(); sb.append("Bug in "); @@ -79,7 +81,9 @@ } } - + /* + * Private (stylesheet) + */ private void refreshDocument(FXOMDocument currentDocument, FXOMDocument newDocument) { // if (currentDocument.getSceneGraphRoot() instanceof Parent) { @@ -167,25 +171,25 @@ refreshFxomObject(currentObject, newObject); } } - - - private void reloadStylesheets(final Parent p) { - assert p != null; - assert p.getScene() != null; - - if (p.getStylesheets().isEmpty() == false) { - final List<String> stylesheets = new ArrayList<>(); - stylesheets.addAll(p.getStylesheets()); -// p.getStylesheets().clear(); -// p.impl_processCSS(true); - p.getStylesheets().setAll(stylesheets); -// p.impl_processCSS(true); - } - for (Node child : p.getChildrenUnmodifiable()) { - if (child instanceof Parent) { - reloadStylesheets((Parent)child); - } - } - - } +// +// +// private void reloadStylesheets(final Parent p) { +// assert p != null; +// assert p.getScene() != null; +// +// if (p.getStylesheets().isEmpty() == false) { +// final List<String> stylesheets = new ArrayList<>(); +// stylesheets.addAll(p.getStylesheets()); +//// p.getStylesheets().clear(); +//// p.impl_processCSS(true); +// p.getStylesheets().setAll(stylesheets); +//// p.impl_processCSS(true); +// } +// for (Node child : p.getChildrenUnmodifiable()) { +// if (child instanceof Parent) { +// reloadStylesheets((Parent)child); +// } +// } +// +// } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/fxom/TransientStateBackup.java Mon Dec 23 13:59:52 2013 +0100 @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. + * All rights reserved. Use is subject to license terms. + * + * This file is available and licensed under the following license: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * - Neither the name of Oracle Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.oracle.javafx.scenebuilder.kit.fxom; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javafx.scene.control.Accordion; +import javafx.scene.control.Tab; +import javafx.scene.control.TabPane; +import javafx.scene.control.TitledPane; + +/** + * + */ +class TransientStateBackup { + + private final FXOMDocument fxomDocument; + private final Map<FXOMObject, FXOMObject> tabPaneMap = new HashMap<>(); + private final Map<FXOMObject, FXOMObject> accordionMap = new HashMap<>(); + + public TransientStateBackup(FXOMDocument fxomDocument) { + assert fxomDocument != null; + + this.fxomDocument = fxomDocument; + + final List<FXOMObject> candidates = new ArrayList<>(); + if (this.fxomDocument.getFxomRoot() != null) { + candidates.add(this.fxomDocument.getFxomRoot()); + } + + while (candidates.isEmpty() == false) { + final FXOMObject candidate = candidates.get(0); + candidates.remove(0); + + final Object sceneGraphObject = candidate.getSceneGraphObject(); + if (sceneGraphObject instanceof TabPane) { + final TabPane tabPane = (TabPane) sceneGraphObject; + final Tab currentTab = tabPane.getSelectionModel().getSelectedItem(); + if (currentTab != null) { + final FXOMObject tabObject + = candidate.searchWithSceneGraphObject(currentTab); + if (tabObject != null) { + tabPaneMap.put(candidate, tabObject); + } + } + } else if (sceneGraphObject instanceof Accordion) { + final Accordion accordion = (Accordion) sceneGraphObject; + final TitledPane currentTitledPane = accordion.getExpandedPane(); + if (currentTitledPane != null) { + final FXOMObject titledPaneObject + = candidate.searchWithSceneGraphObject(currentTitledPane); + if (titledPaneObject != null) { + accordionMap.put(candidate, titledPaneObject); + } + } + } + + candidates.addAll(candidate.getChildObjects()); + } + } + + public void restore() { + final List<FXOMObject> candidates = new ArrayList<>(); + if (this.fxomDocument.getFxomRoot() != null) { + candidates.add(this.fxomDocument.getFxomRoot()); + } + + while (candidates.isEmpty() == false) { + final FXOMObject candidate = candidates.get(0); + candidates.remove(0); + + final Object sceneGraphObject = candidate.getSceneGraphObject(); + if (sceneGraphObject instanceof TabPane) { + final TabPane tabPane = (TabPane) sceneGraphObject; + final FXOMObject tabObject = tabPaneMap.get(candidate); + if ((tabObject != null) && (tabObject.getParentObject() == candidate)) { + assert tabObject.getSceneGraphObject() instanceof Tab; + final Tab tab = (Tab) tabObject.getSceneGraphObject(); + assert tabPane.getTabs().contains(tab); + tabPane.getSelectionModel().select(tab); + } + } else if (sceneGraphObject instanceof Accordion) { + final Accordion accordion = (Accordion) sceneGraphObject; + final FXOMObject titlePaneObject = accordionMap.get(candidate); + if ((titlePaneObject != null) && (titlePaneObject.getParentObject() == candidate)) { + assert titlePaneObject.getSceneGraphObject() instanceof TitledPane; + final TitledPane titledPane = (TitledPane) titlePaneObject.getSceneGraphObject(); + assert accordion.getPanes().contains(titledPane); + accordion.setExpandedPane(titledPane); + } + } + + candidates.addAll(candidate.getChildObjects()); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/fxom/sampledata/ChoiceBoxSampleData.java Mon Dec 23 13:59:52 2013 +0100 @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. + * All rights reserved. Use is subject to license terms. + * + * This file is available and licensed under the following license: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * - Neither the name of Oracle Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.oracle.javafx.scenebuilder.kit.fxom.sampledata; + +import java.util.ArrayList; +import java.util.List; +import javafx.scene.control.ChoiceBox; + +/** + * + */ +class ChoiceBoxSampleData extends AbstractSampleData { + + private final List<String> samples = new ArrayList<>(); + + public ChoiceBoxSampleData() { + for (int i = 0; i < 20; i++) { + samples.add(lorem(i)); + } + } + + /* + * AbstractSampleData + */ + + @Override + public void applyTo(Object sceneGraphObject) { + assert sceneGraphObject != null; + + @SuppressWarnings("unchecked") + final ChoiceBox<String> choiceBox = (ChoiceBox<String>) sceneGraphObject; + choiceBox.getItems().clear(); + choiceBox.getItems().addAll(samples); + choiceBox.getSelectionModel().select(samples.get(0)); + } + + @Override + public void removeFrom(Object sceneGraphObject) { + assert sceneGraphObject != null; + + @SuppressWarnings("unchecked") + final ChoiceBox<String> choiceBox = (ChoiceBox<String>) sceneGraphObject; + choiceBox.getItems().clear(); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/fxom/sampledata/ComboBoxSampleData.java Mon Dec 23 13:59:52 2013 +0100 @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. + * All rights reserved. Use is subject to license terms. + * + * This file is available and licensed under the following license: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * - Neither the name of Oracle Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.oracle.javafx.scenebuilder.kit.fxom.sampledata; + +import java.util.ArrayList; +import java.util.List; +import javafx.scene.control.ComboBox; + +/** + * + */ +class ComboBoxSampleData extends AbstractSampleData { + + private final List<String> samples = new ArrayList<>(); + + public ComboBoxSampleData() { + for (int i = 0; i < 20; i++) { + samples.add(lorem(i)); + } + } + + /* + * AbstractSampleData + */ + + @Override + public void applyTo(Object sceneGraphObject) { + assert sceneGraphObject != null; + + @SuppressWarnings("unchecked") + final ComboBox<String> comboBox = (ComboBox<String>) sceneGraphObject; + comboBox.getItems().clear(); + comboBox.getItems().addAll(samples); + comboBox.getSelectionModel().select(samples.get(0)); + } + + @Override + public void removeFrom(Object sceneGraphObject) { + assert sceneGraphObject != null; + + @SuppressWarnings("unchecked") + final ComboBox<String> comboBox = (ComboBox<String>) sceneGraphObject; + comboBox.getItems().clear(); + } + +}
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/fxom/sampledata/SampleDataGenerator.java Fri Dec 20 15:48:27 2013 -0800 +++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/fxom/sampledata/SampleDataGenerator.java Mon Dec 23 13:59:52 2013 +0100 @@ -40,6 +40,9 @@ import java.util.HashMap; import java.util.Map; import javafx.scene.chart.PieChart; +import javafx.scene.chart.XYChart; +import javafx.scene.control.ChoiceBox; +import javafx.scene.control.ComboBox; import javafx.scene.control.ListView; import javafx.scene.control.TableView; import javafx.scene.control.TreeTableView; @@ -64,7 +67,29 @@ newData = null; } else { final Class<?> sceneGraphClass = sceneGraphObject.getClass(); - if (sceneGraphClass == ListView.class) { + if (sceneGraphClass == ChoiceBox.class) { + final ChoiceBox<?> choiceBox = (ChoiceBox) sceneGraphObject; + if (choiceBox.getItems().isEmpty()) { + if (currentData instanceof ChoiceBoxSampleData) { + newData = currentData; + } else { + newData = new ChoiceBoxSampleData(); + } + } else { + newData = null; + } + } else if (sceneGraphClass == ComboBox.class) { + final ComboBox<?> comboBox = (ComboBox) sceneGraphObject; + if (comboBox.getItems().isEmpty()) { + if (currentData instanceof ComboBoxSampleData) { + newData = currentData; + } else { + newData = new ComboBoxSampleData(); + } + } else { + newData = null; + } + } else if (sceneGraphClass == ListView.class) { final ListView<?> listView = (ListView) sceneGraphObject; if (listView.getItems().isEmpty()) { if (currentData instanceof ListViewSampleData) { @@ -119,6 +144,17 @@ } else { newData = null; } + } else if (XYChartSampleData.isKnownXYChart(sceneGraphObject)) { + final XYChart<?,?> xyChart = (XYChart) sceneGraphObject; + if (xyChart.getData().isEmpty()) { + if (currentData instanceof XYChartSampleData) { + newData = currentData; + } else { + newData = new XYChartSampleData(); + } + } else { + newData = null; + } } else { newData = null; } @@ -186,12 +222,12 @@ // // if (obj instanceof ListView) { // @SuppressWarnings("unchecked") -// final ListView<Object> pieChart = (ListView)obj; -// return visitList(pieChart); +// final ListView<Object> xyChart = (ListView)obj; +// return visitList(xyChart); // } else if (obj instanceof TreeView) { // @SuppressWarnings("unchecked") -// final TreeView<Object> pieChart = (TreeView)obj; -// return visitTree(pieChart); +// final TreeView<Object> xyChart = (TreeView)obj; +// return visitTree(xyChart); // } else if (obj instanceof TableView) { // @SuppressWarnings("unchecked") // final TableView<Object> tableView = (TableView)obj;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/fxom/sampledata/XYChartSampleData.java Mon Dec 23 13:59:52 2013 +0100 @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. + * All rights reserved. Use is subject to license terms. + * + * This file is available and licensed under the following license: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * - Neither the name of Oracle Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.oracle.javafx.scenebuilder.kit.fxom.sampledata; + +import java.util.ArrayList; +import java.util.List; +import javafx.scene.chart.AreaChart; +import javafx.scene.chart.Axis; +import javafx.scene.chart.BarChart; +import javafx.scene.chart.BubbleChart; +import javafx.scene.chart.CategoryAxis; +import javafx.scene.chart.LineChart; +import javafx.scene.chart.NumberAxis; +import javafx.scene.chart.ScatterChart; +import javafx.scene.chart.StackedAreaChart; +import javafx.scene.chart.StackedBarChart; +import javafx.scene.chart.XYChart; + +/** + * + */ +class XYChartSampleData extends AbstractSampleData { + + private final List<XYChart.Series<Object,Object>> samples = new ArrayList<>(); + private final List<String> categories = new ArrayList<>(); + private Class<?> sampleXAxisClass; + private Class<?> sampleYAxisClass; + + public static boolean isKnownXYChart(Object obj) { + final boolean result; + + if (obj instanceof XYChart) { + final Class<?> objClass = obj.getClass(); + result = (objClass == BarChart.class + || objClass == AreaChart.class + || objClass == BubbleChart.class + || objClass == LineChart.class + || objClass == ScatterChart.class + || objClass == StackedBarChart.class + || objClass == StackedAreaChart.class); + } else { + result = false; + } + + return result; + } + + /* + * AbstractSampleData + */ + + @Override + public void applyTo(Object sceneGraphObject) { + assert sceneGraphObject instanceof XYChart; + + @SuppressWarnings("unchecked") + final XYChart<Object,Object> xyChart = (XYChart<Object,Object>) sceneGraphObject; + updateSamples(xyChart); + xyChart.getData().clear(); + xyChart.getData().addAll(samples); + if (xyChart.getXAxis().getClass() == CategoryAxis.class) { + @SuppressWarnings("unchecked") + final CategoryAxis axis = (CategoryAxis)(Axis<?>) xyChart.getXAxis(); + axis.getCategories().setAll(categories); + } + if (xyChart.getYAxis().getClass() == CategoryAxis.class) { + @SuppressWarnings("unchecked") + final CategoryAxis axis = (CategoryAxis)(Axis<?>) xyChart.getYAxis(); + axis.getCategories().setAll(categories); + } + } + + @Override + public void removeFrom(Object sceneGraphObject) { + assert sceneGraphObject instanceof XYChart; + + @SuppressWarnings("unchecked") + final XYChart<Object,Object> xyChart = (XYChart<Object,Object>) sceneGraphObject; + xyChart.getData().clear(); + if (xyChart.getXAxis().getClass() == CategoryAxis.class) { + final CategoryAxis axis = (CategoryAxis)(Axis<?>) xyChart.getXAxis(); + axis.getCategories().clear(); + } + if (xyChart.getYAxis().getClass() == CategoryAxis.class) { + final CategoryAxis axis = (CategoryAxis)(Axis<?>) xyChart.getYAxis(); + axis.getCategories().clear(); + } + } + + + /* + * Private + */ + + private void updateSamples(XYChart<?,?> xyChart) { + + final Class<?> xAxisClass = xyChart.getXAxis().getClass(); + final Class<?> yAxisClass = xyChart.getYAxis().getClass(); + + if ((xAxisClass != sampleXAxisClass) || (yAxisClass != sampleYAxisClass)) { + sampleXAxisClass = xAxisClass; + sampleYAxisClass = yAxisClass; + + for (int i = 0; i < 3; i++) { + final XYChart.Series<Object, Object> serie = new XYChart.Series<>(); + for (int j = 0; j < 10; j++) { + final Object xValue = makeValue(sampleXAxisClass, i); + final Object yValue = makeValue(sampleYAxisClass, i); + final XYChart.Data<Object, Object> data = new XYChart.Data<>(xValue, yValue); + serie.getData().add(data); + + } + samples.add(serie); + } + + categories.clear(); + if ((sampleXAxisClass == CategoryAxis.class) || (sampleYAxisClass == CategoryAxis.class)) { + for (int j = 0; j < 10; j++) { + categories.add(String.valueOf(2000 + j)); + } + } + } + } + + private Object makeValue(Class<?> axisClass, int index) { + final Object result; + + if (axisClass == NumberAxis.class) { + result = Math.random() * 100.0; + } else if (axisClass == CategoryAxis.class) { + result = String.valueOf(2000 + index); + } else { + assert false : "Unexpected Axis subclass" + axisClass; + result = String.valueOf(index); + } + + return result; + } +}
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/library/builtin/ChoiceBox.fxml Fri Dec 20 15:48:27 2013 -0800 +++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/library/builtin/ChoiceBox.fxml Mon Dec 23 13:59:52 2013 +0100 @@ -37,12 +37,4 @@ <?import javafx.scene.layout.*?> <?import javafx.scene.paint.*?> -<ChoiceBox xmlns:fx="http://javafx.com/fxml"> - <items> - <FXCollections fx:factory="observableArrayList"> - <String fx:value="Item 1" /> - <String fx:value="Item 2" /> - <String fx:value="Item 3" /> - </FXCollections> - </items> -</ChoiceBox> +<ChoiceBox xmlns:fx="http://javafx.com/fxml" prefWidth="150.0" />
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/library/builtin/ComboBox.fxml Fri Dec 20 15:48:27 2013 -0800 +++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/library/builtin/ComboBox.fxml Mon Dec 23 13:59:52 2013 +0100 @@ -37,12 +37,4 @@ <?import javafx.scene.layout.*?> <?import javafx.scene.paint.*?> -<ComboBox xmlns:fx="http://javafx.com/fxml"> - <items> - <FXCollections fx:factory="observableArrayList"> - <String fx:value="Item 1" /> - <String fx:value="Item 2" /> - <String fx:value="Item 3" /> - </FXCollections> - </items> -</ComboBox> +<ComboBox xmlns:fx="http://javafx.com/fxml" prefWidth="150.0" />
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/library/user/LibraryFolderWatcher.java Fri Dec 20 15:48:27 2013 -0800 +++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/library/user/LibraryFolderWatcher.java Mon Dec 23 13:59:52 2013 +0100 @@ -54,6 +54,7 @@ import java.nio.file.WatchService; import java.util.ArrayList; import java.util.Collection; +import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Locale; @@ -81,6 +82,7 @@ try { library.updateExplorationCount(0); + library.updateExplorationDate(new Date()); runDiscovery(); runWatching(); } catch(InterruptedException x) { @@ -243,6 +245,7 @@ library.addItems(newItems); library.updateExplorationCount(library.getExplorationCount()+1); + library.updateExplorationDate(new Date()); } @@ -300,6 +303,7 @@ library.addItems(newItems); library.updateJarReports(new ArrayList<>(jarReports)); library.updateExplorationCount(library.getExplorationCount()+1); + library.updateExplorationDate(new Date()); }
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/library/user/UserLibrary.java Fri Dec 20 15:48:27 2013 -0800 +++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/library/user/UserLibrary.java Mon Dec 23 13:59:52 2013 +0100 @@ -50,11 +50,14 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; +import java.util.Date; import java.util.List; import java.util.TreeSet; import javafx.application.Platform; import javafx.beans.property.ReadOnlyIntegerProperty; +import javafx.beans.property.ReadOnlyObjectProperty; import javafx.beans.property.SimpleIntegerProperty; +import javafx.beans.property.SimpleObjectProperty; import javafx.collections.FXCollections; import javafx.collections.ObservableList; @@ -73,7 +76,8 @@ private final ObservableList<JarReport> jarReports = FXCollections.observableArrayList(); private final SimpleIntegerProperty explorationCountProperty = new SimpleIntegerProperty(); - + private final SimpleObjectProperty<Date> explorationDateProperty = new SimpleObjectProperty<>(); + private State state = State.READY; private Exception exception; private LibraryFolderWatcher watcher; @@ -153,7 +157,15 @@ public ReadOnlyIntegerProperty explorationCountProperty() { return explorationCountProperty; } + + public Object getExplorationDate() { + return explorationDateProperty.get(); + } + public ReadOnlyObjectProperty<Date> explorationDateProperty() { + return explorationDateProperty; + } + public void setFilter(List<String> classnames) throws FileNotFoundException, IOException { if (classnames != null && classnames.size() > 0) { File filterFile = new File(getFilterFileName()); @@ -275,7 +287,6 @@ } } - void updateExplorationCount(int count) { if (Platform.isFxApplicationThread()) { explorationCountProperty.set(count); @@ -289,6 +300,19 @@ } } + void updateExplorationDate(Date date) { + if (Platform.isFxApplicationThread()) { + explorationDateProperty.set(date); + } else { + Platform.runLater(new Runnable() { + @Override + public void run() { + explorationDateProperty.set(date); + } + }); + } + } + /* * Library */
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/metadata/Metadata.java Fri Dec 20 15:48:27 2013 -0800 +++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/metadata/Metadata.java Mon Dec 23 13:59:52 2013 +0100 @@ -36,6 +36,7 @@ */ import com.oracle.javafx.scenebuilder.kit.fxom.FXOMInstance; +import com.oracle.javafx.scenebuilder.kit.metadata.property.value.keycombination.KeyCombinationPropertyMetadata; import com.oracle.javafx.scenebuilder.kit.metadata.property.value.paint.PaintPropertyMetadata; import com.oracle.javafx.scenebuilder.kit.metadata.property.value.paint.ColorPropertyMetadata; import com.oracle.javafx.scenebuilder.kit.metadata.klass.ComponentClassMetadata; @@ -2074,7 +2075,7 @@ new StringPropertyMetadata( idName, true, /* readWrite */ - null, /* defaultValue */ + "", /* defaultValue */ new InspectorPath("Properties", "JavaFX CSS", 0)); private final ValuePropertyMetadata imagePropertyMetadata = new ImagePropertyMetadata( @@ -2114,7 +2115,7 @@ new StringPropertyMetadata( labelName, true, /* readWrite */ - null, /* defaultValue */ + "", /* defaultValue */ new InspectorPath("Properties", "Specific", 24)); private final ComponentPropertyMetadata labelForPropertyMetadata = new ComponentPropertyMetadata( @@ -3289,13 +3290,7 @@ true, /* readWrite */ 1.0, /* defaultValue */ new InspectorPath("Properties", "Stroke", 1)); - private final ValuePropertyMetadata style_NULL_PropertyMetadata = - new StringPropertyMetadata( - styleName, - true, /* readWrite */ - null, /* defaultValue */ - new InspectorPath("Properties", "JavaFX CSS", 1)); - private final ValuePropertyMetadata style__PropertyMetadata = + private final ValuePropertyMetadata stylePropertyMetadata = new StringPropertyMetadata( styleName, true, /* readWrite */ @@ -3653,18 +3648,12 @@ tabsName, TabMetadata, true); /* collection */ - private final ValuePropertyMetadata text__PropertyMetadata = + private final ValuePropertyMetadata textPropertyMetadata = new StringPropertyMetadata( textName, true, /* readWrite */ "", /* defaultValue */ new InspectorPath("Properties", "Text", 2)); - private final ValuePropertyMetadata text_NULL_PropertyMetadata = - new StringPropertyMetadata( - textName, - true, /* readWrite */ - null, /* defaultValue */ - new InspectorPath("Properties", "Text", 2)); private final ValuePropertyMetadata textAlignmentPropertyMetadata = new EnumerationPropertyMetadata( textAlignmentName, @@ -3781,7 +3770,7 @@ new StringPropertyMetadata( titleName, true, /* readWrite */ - null, /* defaultValue */ + "", /* defaultValue */ new InspectorPath("Properties", "Specific", 35)); private final ValuePropertyMetadata titleSidePropertyMetadata = new EnumerationPropertyMetadata( @@ -4636,7 +4625,7 @@ LabeledMetadata.getProperties().add(lineSpacingPropertyMetadata); LabeledMetadata.getProperties().add(mnemonicParsing_true_PropertyMetadata); LabeledMetadata.getProperties().add(styleClass_c37_PropertyMetadata); - LabeledMetadata.getProperties().add(text__PropertyMetadata); + LabeledMetadata.getProperties().add(textPropertyMetadata); LabeledMetadata.getProperties().add(textAlignmentPropertyMetadata); LabeledMetadata.getProperties().add(textFillPropertyMetadata); LabeledMetadata.getProperties().add(textOverrunPropertyMetadata); @@ -4690,7 +4679,6 @@ MenuMetadata.getProperties().add(onShowingPropertyMetadata); MenuMetadata.getProperties().add(onShownPropertyMetadata); MenuMetadata.getProperties().add(styleClass_c27_PropertyMetadata); - MenuMetadata.getProperties().add(text__PropertyMetadata); MenuBarMetadata.getProperties().add(menusPropertyMetadata); MenuBarMetadata.getProperties().add(styleClass_c18_PropertyMetadata); @@ -4707,9 +4695,9 @@ MenuItemMetadata.getProperties().add(mnemonicParsing_true_PropertyMetadata); MenuItemMetadata.getProperties().add(onActionPropertyMetadata); MenuItemMetadata.getProperties().add(onMenuValidationPropertyMetadata); - MenuItemMetadata.getProperties().add(style_NULL_PropertyMetadata); + MenuItemMetadata.getProperties().add(stylePropertyMetadata); MenuItemMetadata.getProperties().add(styleClass_c32_PropertyMetadata); - MenuItemMetadata.getProperties().add(text_NULL_PropertyMetadata); + MenuItemMetadata.getProperties().add(textPropertyMetadata); MenuItemMetadata.getProperties().add(visiblePropertyMetadata); MeshViewMetadata.getProperties().add(meshPropertyMetadata); @@ -4786,7 +4774,7 @@ NodeMetadata.getProperties().add(scaleXPropertyMetadata); NodeMetadata.getProperties().add(scaleYPropertyMetadata); NodeMetadata.getProperties().add(scaleZPropertyMetadata); - NodeMetadata.getProperties().add(style__PropertyMetadata); + NodeMetadata.getProperties().add(stylePropertyMetadata); NodeMetadata.getProperties().add(styleClass_empty_PropertyMetadata); NodeMetadata.getProperties().add(transformsPropertyMetadata); NodeMetadata.getProperties().add(translateXPropertyMetadata); @@ -4882,7 +4870,7 @@ PopupControlMetadata.getProperties().add(opacityPropertyMetadata); PopupControlMetadata.getProperties().add(prefHeight_COMPUTED_PropertyMetadata); PopupControlMetadata.getProperties().add(prefWidth_COMPUTED_PropertyMetadata); - PopupControlMetadata.getProperties().add(style_NULL_PropertyMetadata); + PopupControlMetadata.getProperties().add(stylePropertyMetadata); PopupControlMetadata.getProperties().add(styleClass_empty_PropertyMetadata); PopupControlMetadata.getProperties().add(width_Double_0_PropertyMetadata); PopupControlMetadata.getProperties().add(x_NaN_PropertyMetadata); @@ -5074,9 +5062,9 @@ TabMetadata.getProperties().add(onCloseRequestPropertyMetadata); TabMetadata.getProperties().add(onSelectionChangedPropertyMetadata); TabMetadata.getProperties().add(selected_Boolean_ro_PropertyMetadata); - TabMetadata.getProperties().add(style_NULL_PropertyMetadata); + TabMetadata.getProperties().add(stylePropertyMetadata); TabMetadata.getProperties().add(styleClass_c19_PropertyMetadata); - TabMetadata.getProperties().add(text_NULL_PropertyMetadata); + TabMetadata.getProperties().add(textPropertyMetadata); TabMetadata.getProperties().add(tooltipPropertyMetadata); TabPaneMetadata.getProperties().add(focusTraversable_true_PropertyMetadata); @@ -5106,9 +5094,9 @@ TableColumnBaseMetadata.getProperties().add(resizable_Boolean_PropertyMetadata); TableColumnBaseMetadata.getProperties().add(sortablePropertyMetadata); TableColumnBaseMetadata.getProperties().add(sortNodePropertyMetadata); - TableColumnBaseMetadata.getProperties().add(style_NULL_PropertyMetadata); + TableColumnBaseMetadata.getProperties().add(stylePropertyMetadata); TableColumnBaseMetadata.getProperties().add(styleClass_c38_PropertyMetadata); - TableColumnBaseMetadata.getProperties().add(text__PropertyMetadata); + TableColumnBaseMetadata.getProperties().add(textPropertyMetadata); TableColumnBaseMetadata.getProperties().add(visiblePropertyMetadata); TableColumnBaseMetadata.getProperties().add(width_Double_ro_PropertyMetadata); @@ -5131,7 +5119,7 @@ TextMetadata.getProperties().add(fontSmoothingType_GRAY_PropertyMetadata); TextMetadata.getProperties().add(lineSpacingPropertyMetadata); TextMetadata.getProperties().add(strikethroughPropertyMetadata); - TextMetadata.getProperties().add(text__PropertyMetadata); + TextMetadata.getProperties().add(textPropertyMetadata); TextMetadata.getProperties().add(textAlignmentPropertyMetadata); TextMetadata.getProperties().add(textOriginPropertyMetadata); TextMetadata.getProperties().add(underlinePropertyMetadata); @@ -5164,7 +5152,7 @@ TextInputControlMetadata.getProperties().add(length_Integer_ro_PropertyMetadata); TextInputControlMetadata.getProperties().add(promptTextPropertyMetadata); TextInputControlMetadata.getProperties().add(styleClass_c46_PropertyMetadata); - TextInputControlMetadata.getProperties().add(text__PropertyMetadata); + TextInputControlMetadata.getProperties().add(textPropertyMetadata); TilePaneMetadata.getProperties().add(alignment_TOP_LEFT_PropertyMetadata); TilePaneMetadata.getProperties().add(contentBiasPropertyMetadata); @@ -5208,7 +5196,7 @@ TooltipMetadata.getProperties().add(onShownPropertyMetadata); TooltipMetadata.getProperties().add(opacityPropertyMetadata); TooltipMetadata.getProperties().add(styleClass_c15_PropertyMetadata); - TooltipMetadata.getProperties().add(text__PropertyMetadata); + TooltipMetadata.getProperties().add(textPropertyMetadata); TooltipMetadata.getProperties().add(textAlignmentPropertyMetadata); TooltipMetadata.getProperties().add(textOverrunPropertyMetadata); TooltipMetadata.getProperties().add(width_Double_0_PropertyMetadata);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/metadata/property/value/keycombination/KeyCharacterCombinationPropertyMetadata.java Mon Dec 23 13:59:52 2013 +0100 @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. + * All rights reserved. Use is subject to license terms. + * + * This file is available and licensed under the following license: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * - Neither the name of Oracle Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.oracle.javafx.scenebuilder.kit.metadata.property.value.keycombination; + +import com.oracle.javafx.scenebuilder.kit.fxom.FXOMInstance; +import com.oracle.javafx.scenebuilder.kit.metadata.property.value.ComplexPropertyMetadata; +import com.oracle.javafx.scenebuilder.kit.metadata.property.value.EnumerationPropertyMetadata; +import com.oracle.javafx.scenebuilder.kit.metadata.property.value.StringPropertyMetadata; +import com.oracle.javafx.scenebuilder.kit.metadata.util.InspectorPath; +import com.oracle.javafx.scenebuilder.kit.metadata.util.PropertyName; +import javafx.scene.input.KeyCharacterCombination; +import javafx.scene.input.KeyCombination; + +/** + * + */ +public class KeyCharacterCombinationPropertyMetadata extends ComplexPropertyMetadata<KeyCharacterCombination> { + + /* + * NOTE : KeyCharacterCombination singularity + * + * Same as KeyCodeCombination => see comments in KeyCodeCombination + */ + private static final String DUMMY = "dummy"; //NOI18N + + private final EnumerationPropertyMetadata altMetadata + = new EnumerationPropertyMetadata(new PropertyName("alt"), //NOI18N + KeyCombination.ModifierValue.class, DUMMY, true, + InspectorPath.UNUSED); + private final EnumerationPropertyMetadata controlMetadata + = new EnumerationPropertyMetadata(new PropertyName("control"), //NOI18N + KeyCombination.ModifierValue.class, DUMMY, true, + InspectorPath.UNUSED); + private final EnumerationPropertyMetadata metaMetadata + = new EnumerationPropertyMetadata(new PropertyName("meta"), //NOI18N + KeyCombination.ModifierValue.class, DUMMY, true, + InspectorPath.UNUSED); + private final EnumerationPropertyMetadata shiftMetadata + = new EnumerationPropertyMetadata(new PropertyName("shift"), //NOI18N + KeyCombination.ModifierValue.class, DUMMY, true, + InspectorPath.UNUSED); + private final EnumerationPropertyMetadata shortcutMetadata + = new EnumerationPropertyMetadata(new PropertyName("shortcut"), //NOI18N + KeyCombination.ModifierValue.class, DUMMY, true, + InspectorPath.UNUSED); + private final StringPropertyMetadata characterMetadata + = new StringPropertyMetadata(new PropertyName("character"), //NOI18N + true, null, InspectorPath.UNUSED); + + public KeyCharacterCombinationPropertyMetadata(PropertyName name, boolean readWrite, + KeyCharacterCombination defaultValue, InspectorPath inspectorPath) { + super(name, KeyCharacterCombination.class, readWrite, defaultValue, inspectorPath); + } + + @Override + protected KeyCharacterCombination castValue(Object value) { + return (KeyCharacterCombination) value; + } + + @Override + protected void updateFxomInstanceWithValue(FXOMInstance valueInstance, KeyCharacterCombination value) { + altMetadata.setValue(valueInstance, value.getAlt().toString()); + controlMetadata.setValue(valueInstance, value.getControl().toString()); + metaMetadata.setValue(valueInstance, value.getMeta().toString()); + shiftMetadata.setValue(valueInstance, value.getShift().toString()); + shortcutMetadata.setValue(valueInstance, value.getShortcut().toString()); + characterMetadata.setValue(valueInstance, value.getCharacter()); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/metadata/property/value/keycombination/KeyCodeCombinationPropertyMetadata.java Mon Dec 23 13:59:52 2013 +0100 @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. + * All rights reserved. Use is subject to license terms. + * + * This file is available and licensed under the following license: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * - Neither the name of Oracle Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.oracle.javafx.scenebuilder.kit.metadata.property.value.keycombination; + +import com.oracle.javafx.scenebuilder.kit.fxom.FXOMInstance; +import com.oracle.javafx.scenebuilder.kit.metadata.property.value.ComplexPropertyMetadata; +import com.oracle.javafx.scenebuilder.kit.metadata.property.value.EnumerationPropertyMetadata; +import com.oracle.javafx.scenebuilder.kit.metadata.util.InspectorPath; +import com.oracle.javafx.scenebuilder.kit.metadata.util.PropertyName; +import javafx.scene.input.KeyCode; +import javafx.scene.input.KeyCodeCombination; +import javafx.scene.input.KeyCombination; + +/** + * + */ +public class KeyCodeCombinationPropertyMetadata extends ComplexPropertyMetadata<KeyCodeCombination> { + + /* + * NOTE : KeyCodeCombination singularity + * + * Default value for 'alt', 'control', 'meta', 'shift' and 'shortcut' is 'UP'. + * However FXMLLoader refuses to load: + * + * <KeyCombinationCode code='PASTE' /> + * + * Properties must be explicitely specified even when they have the default value. + * + * <KeyCombinationCode code='PASTE' alt='UP' control='UP' meta='UP' shift='UP' shortcut='UP' /> + * + * To force this behavior, the EnumerationPropertyMetadata below are all + * set with a dummy default value. + */ + private static final String DUMMY = "dummy"; //NOI18N + + private final EnumerationPropertyMetadata altMetadata + = new EnumerationPropertyMetadata(new PropertyName("alt"), //NOI18N + KeyCombination.ModifierValue.class, DUMMY, true, + InspectorPath.UNUSED); + private final EnumerationPropertyMetadata controlMetadata + = new EnumerationPropertyMetadata(new PropertyName("control"), //NOI18N + KeyCombination.ModifierValue.class, DUMMY, true, + InspectorPath.UNUSED); + private final EnumerationPropertyMetadata metaMetadata + = new EnumerationPropertyMetadata(new PropertyName("meta"), //NOI18N + KeyCombination.ModifierValue.class, DUMMY, true, + InspectorPath.UNUSED); + private final EnumerationPropertyMetadata shiftMetadata + = new EnumerationPropertyMetadata(new PropertyName("shift"), //NOI18N + KeyCombination.ModifierValue.class, DUMMY, true, + InspectorPath.UNUSED); + private final EnumerationPropertyMetadata shortcutMetadata + = new EnumerationPropertyMetadata(new PropertyName("shortcut"), //NOI18N + KeyCombination.ModifierValue.class, DUMMY, true, + InspectorPath.UNUSED); + private final EnumerationPropertyMetadata codeMetadata + = new EnumerationPropertyMetadata(new PropertyName("code"), //NOI18N + KeyCode.class, DUMMY, true, + InspectorPath.UNUSED); + + public KeyCodeCombinationPropertyMetadata(PropertyName name, boolean readWrite, + KeyCodeCombination defaultValue, InspectorPath inspectorPath) { + super(name, KeyCodeCombination.class, readWrite, defaultValue, inspectorPath); + } + + @Override + protected KeyCodeCombination castValue(Object value) { + return (KeyCodeCombination) value; + } + + @Override + protected void updateFxomInstanceWithValue(FXOMInstance valueInstance, KeyCodeCombination value) { + altMetadata.setValue(valueInstance, value.getAlt().toString()); + controlMetadata.setValue(valueInstance, value.getControl().toString()); + metaMetadata.setValue(valueInstance, value.getMeta().toString()); + shiftMetadata.setValue(valueInstance, value.getShift().toString()); + shortcutMetadata.setValue(valueInstance, value.getShortcut().toString()); + codeMetadata.setValue(valueInstance, value.getCode().toString()); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/metadata/property/value/keycombination/KeyCombinationPropertyMetadata.java Mon Dec 23 13:59:52 2013 +0100 @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. + * All rights reserved. Use is subject to license terms. + * + * This file is available and licensed under the following license: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * - Neither the name of Oracle Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.oracle.javafx.scenebuilder.kit.metadata.property.value.keycombination; + +import com.oracle.javafx.scenebuilder.kit.fxom.FXOMDocument; +import com.oracle.javafx.scenebuilder.kit.fxom.FXOMInstance; +import com.oracle.javafx.scenebuilder.kit.fxom.FXOMIntrinsic; +import com.oracle.javafx.scenebuilder.kit.fxom.FXOMObject; +import com.oracle.javafx.scenebuilder.kit.fxom.FXOMProperty; +import com.oracle.javafx.scenebuilder.kit.fxom.FXOMPropertyC; +import com.oracle.javafx.scenebuilder.kit.metadata.property.value.ComplexPropertyMetadata; +import com.oracle.javafx.scenebuilder.kit.metadata.util.InspectorPath; +import com.oracle.javafx.scenebuilder.kit.metadata.util.PropertyName; +import javafx.scene.input.KeyCharacterCombination; +import javafx.scene.input.KeyCodeCombination; +import javafx.scene.input.KeyCombination; + +/** + * + */ +public class KeyCombinationPropertyMetadata extends ComplexPropertyMetadata<KeyCombination> { + + private final KeyCodeCombinationPropertyMetadata keyCodeCombinationMetadata; + private final KeyCharacterCombinationPropertyMetadata keyCharacterCombinationMetadata; + + public KeyCombinationPropertyMetadata(PropertyName name, boolean readWrite, + KeyCombination defaultValue, InspectorPath inspectorPath) { + super(name, KeyCombination.class, readWrite, defaultValue, inspectorPath); + keyCodeCombinationMetadata = new KeyCodeCombinationPropertyMetadata(name, readWrite, null, inspectorPath); + keyCharacterCombinationMetadata = new KeyCharacterCombinationPropertyMetadata(name, readWrite, null, inspectorPath); + } + + /* + * ComplexPropertyMetadata + */ + @Override + protected KeyCombination castValue(Object value) { + return (KeyCombination) value; + } + + + @Override + protected void updateFxomPropertyWithValue(FXOMProperty fxomProperty, KeyCombination value) { + assert fxomProperty instanceof FXOMPropertyC; + assert value != null; + + final FXOMPropertyC fxomPropertyC = (FXOMPropertyC) fxomProperty; + assert fxomPropertyC.getValues().size() == 1; + + FXOMObject valueObject = fxomPropertyC.getValues().get(0); + if (valueObject instanceof FXOMInstance) { + final FXOMInstance currentValueInstance = (FXOMInstance) valueObject; + final Class<?> currentValueClass = currentValueInstance.getDeclaredClass(); + + if (currentValueClass != value.getClass()) { + // Eg current value is a KeyCodeCombination, new value is a KeyCharacterCombination + final FXOMDocument fxomDocument = fxomProperty.getFxomDocument(); + final FXOMInstance valueInstance = new FXOMInstance(fxomDocument, value.getClass()); + updateFxomInstanceWithValue(valueInstance, value); + valueInstance.addToParentProperty(0, fxomPropertyC); + valueObject.removeFromParentProperty(); + } else { + updateFxomInstanceWithValue(currentValueInstance, value); + } + } else { + assert valueObject instanceof FXOMIntrinsic; + + final FXOMDocument fxomDocument = fxomProperty.getFxomDocument(); + final FXOMInstance valueInstance = new FXOMInstance(fxomDocument, value.getClass()); + updateFxomInstanceWithValue(valueInstance, value); + valueInstance.addToParentProperty(0, fxomPropertyC); + valueObject.removeFromParentProperty(); + } + } + + @Override + protected void updateFxomInstanceWithValue(FXOMInstance valueInstance, KeyCombination value) { + if (value instanceof KeyCodeCombination) { + keyCodeCombinationMetadata.updateFxomInstanceWithValue(valueInstance, (KeyCodeCombination) value); + } else { + assert value instanceof KeyCharacterCombination; + keyCharacterCombinationMetadata.updateFxomInstanceWithValue(valueInstance, (KeyCharacterCombination) value); + } + } + +}
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/metadata/util/ClipboardDecoder.java Fri Dec 20 15:48:27 2013 -0800 +++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/metadata/util/ClipboardDecoder.java Mon Dec 23 13:59:52 2013 +0100 @@ -41,8 +41,10 @@ import com.oracle.javafx.scenebuilder.kit.metadata.property.PropertyMetadata; import com.oracle.javafx.scenebuilder.kit.metadata.property.value.DoublePropertyMetadata; import com.oracle.javafx.scenebuilder.kit.metadata.property.value.ImagePropertyMetadata; +import java.io.File; import java.io.IOException; import java.net.URL; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -50,7 +52,6 @@ import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.input.Clipboard; -import javafx.scene.input.DataFormat; /** * @@ -100,18 +101,40 @@ } } - // DataFormat.IMAGE - if ((result == null) - && clipboard.hasContent(DataFormat.IMAGE)) { - final Object content = clipboard.getContent(DataFormat.IMAGE); - if (content instanceof Image) { - final Image image = (Image) content; - try { - final FXOMDocument transientDoc = - makeFxomDocumentFromImageURL(image, 200.0); - result = Arrays.asList(transientDoc.getFxomRoot()); - } catch(IOException x) { - result = null; + // DataFormat.FILES + if ((result == null) && clipboard.hasFiles()) { + result = new ArrayList<>(); + for (File f : clipboard.getFiles()) { + if (f.getAbsolutePath().endsWith(".fxml")) { //NOI18N + try { + final String fxmlText + = FXOMDocument.readContentFromURL(f.toURI().toURL()); + final FXOMDocument transientDoc = new FXOMDocument( + fxmlText, + targetDocument.getLocation(), + targetDocument.getClassLoader(), + targetDocument.getResources()); + final FXOMObject fxomObject = transientDoc.getFxomRoot(); + fxomObject.moveToFxomDocument(targetDocument); + result.add(fxomObject); + } catch(IOException x) { + // Then we silently ignore this file + } + } else { + // Try load the file has an image + try { + final String fileURL = f.toURI().toURL().toString(); + final Image image = new Image(fileURL); + if (image.isError() == false) { + final FXOMDocument transientDoc = + makeFxomDocumentFromImageURL(image, 200.0); + final FXOMObject fxomObject = transientDoc.getFxomRoot(); + fxomObject.moveToFxomDocument(targetDocument); + result.add(fxomObject); + } + } catch(IOException x) { + // Then we silently ignore this file + } } } }
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/metadata/util/DesignHierarchyMask.java Fri Dec 20 15:48:27 2013 -0800 +++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/metadata/util/DesignHierarchyMask.java Mon Dec 23 13:59:52 2013 +0100 @@ -69,6 +69,7 @@ import javafx.scene.layout.AnchorPane; import javafx.scene.layout.GridPane; import javafx.scene.layout.Pane; +import javafx.scene.text.Text; /** * @@ -550,6 +551,7 @@ || sceneGraphObject instanceof TableColumn || sceneGraphObject instanceof TextInputControl || sceneGraphObject instanceof TitledPane + || sceneGraphObject instanceof Text || sceneGraphObject instanceof Tooltip) { propertyName = new PropertyName("text"); }
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/util/Deprecation.java Fri Dec 20 15:48:27 2013 -0800 +++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/util/Deprecation.java Mon Dec 23 13:59:52 2013 +0100 @@ -85,6 +85,10 @@ public static ObservableMap<StyleableProperty<?>, List<Style>> getStyleMap(Node node) { return node.impl_getStyleMap(); } + + public static void reapplyCSS(Node node) { + node.impl_reapplyCSS(); + } // Retrieve the node of the Styleable. public static Node getNode(Styleable styleable) { @@ -196,9 +200,39 @@ } + public static URL getCaspianHighContrastStylesheetURL() { + final String resourceName = "com/sun/javafx/scene/control/skin/caspian/highcontrast.bss"; //NOI18N + return ClassLoader.getSystemResource(resourceName); + } + + + public static URL getCaspianVirtualKeyboardStylesheetURL() { + final String resourceName = "com/sun/javafx/scene/control/skin/caspian/fxvk.bss"; //NOI18N + return ClassLoader.getSystemResource(resourceName); + } + + + public static URL getCaspianEmbeddedStylesheetURL() { + final String resourceName = "com/sun/javafx/scene/control/skin/caspian/embedded.bss"; //NOI18N + return ClassLoader.getSystemResource(resourceName); + } + + + public static URL getCaspianEmbeddedQVGAStylesheetURL() { + final String resourceName = "com/sun/javafx/scene/control/skin/caspian/embedded-qvga.bss"; //NOI18N + return ClassLoader.getSystemResource(resourceName); + } + + public static URL getModenaStylesheetURL() { final String resourceName = "com/sun/javafx/scene/control/skin/modena/modena.bss"; //NOI18N return ClassLoader.getSystemResource(resourceName); } + + + public static URL getModenaTouchStylesheetURL() { + final String resourceName = "com/sun/javafx/scene/control/skin/modena/touch.bss"; //NOI18N + return ClassLoader.getSystemResource(resourceName); + } }