Commit 9f895c89 authored by alexander.weigl's avatar alexander.weigl 🐼

Merge branch 'weiglJDK10' into 'master'

Weigl jdk10

See merge request !16
parents bb3d81e0 352d07c6
Pipeline #21796 passed with stages
in 5 minutes and 50 seconds
# This is the Gradle build system for JVM applications # This is the Gradle build system for JVM applications
# https://gradle.org/ # https://gradle.org/
# https://github.com/gradle/gradle # https://github.com/gradle/gradle
image: key-dev-jdk8 image: key-dev-jdk10
cache: cache:
paths: paths:
...@@ -13,13 +13,15 @@ cache: ...@@ -13,13 +13,15 @@ cache:
# runtime for each build is more reliable since the runtime is completely # runtime for each build is more reliable since the runtime is completely
# isolated from any previous builds. # isolated from any previous builds.
variables: variables:
GRADLE_OPTS: "-Dorg.gradle.daemon=false" GRADLE_OPTS: "-Dorg.gradle.daemon=false \
--add-modules java.xml.bind \
'-Dorg.gradle.jvmargs=--add-modules java.xml.bind'"
GIT_SSL_NO_VERIFY: "true"
before_script: before_script:
- export GRADLE_USER_HOME=`pwd`/.gradle - export GRADLE_USER_HOME=`pwd`/.gradle
# - export GRADLE_OPTS="-Dorg.gradle.daemon=false --add-modules java.xml.bind '-Dorg.gradle.jvmargs=--add-modules java.xml.bind'"
variables:
GIT_SSL_NO_VERIFY: "true"
stages: stages:
- build - build
...@@ -39,10 +41,26 @@ build:jdk9: ...@@ -39,10 +41,26 @@ build:jdk9:
- .gradle - .gradle
build:jdk10:
stage: build
image: key-dev-jdk10
script: gradle --build-cache assemble
allow_failure: true
cache:
key: "$CI_COMMIT_REF_NAME"
policy: push
paths:
- build
- .gradle
build:jdk8: build:jdk8:
stage: build stage: build
variables:
GRADLE_OPTS: "-Dorg.gradle.daemon=false"
script: gradle --build-cache assemble script: gradle --build-cache assemble
image: key-dev-jdk8 image: key-dev-jdk8
cache: cache:
key: "$CI_COMMIT_REF_NAME" key: "$CI_COMMIT_REF_NAME"
policy: push policy: push
......
package org.dockfx;
import java.util.LinkedList;
import java.util.Properties;
/**
* ContentHolder has common functions for storing persistent object for node
*
* @author HongKee Moon
*/
public class ContentHolder
{
/**
* The enum ContentHolder Type.
*/
public enum Type {
/**
* The SplitPane.
*/
SplitPane,
/**
* The TabPane.
*/
TabPane,
/**
* The Collection.
*/
Collection,
/**
* The FloatingNode.
*/
FloatingNode,
/**
* The DockNode.
*/
DockNode
}
String name;
Properties properties;
LinkedList children;
Type type;
public ContentHolder()
{
}
public ContentHolder( String name, Type type )
{
this.name = name;
this.properties = new Properties();
this.children = new LinkedList();
this.type = type;
}
public void addProperty( Object key, Object value )
{
properties.put( key, value );
}
public void addChild( Object child )
{
children.add( child );
}
public String getName()
{
return name;
}
public void setName( String name )
{
this.name = name;
}
public Properties getProperties()
{
return properties;
}
public void setProperties( Properties properties )
{
this.properties = properties;
}
public LinkedList getChildren()
{
return children;
}
public void setChildren( LinkedList children )
{
this.children = children;
}
public Type getType()
{
return type;
}
public void setType( Type type )
{
this.type = type;
}
}
package org.dockfx;
/**
* To support the delayed open process for some specific applications, this interface implementation is used.
*/
public interface DelayOpenHandler {
public DockNode open(String nodeName);
}
...@@ -30,7 +30,7 @@ import javafx.scene.Node; ...@@ -30,7 +30,7 @@ import javafx.scene.Node;
import javafx.scene.input.PickResult; import javafx.scene.input.PickResult;
/** /**
* Base class for DockFX events. Each DockFX event has associated an event source, event target and * Base class for DockFX events. Each DockFX event has an associated event source, event target and
* an event type. The event source specifies for an event handler the object on which that handler * an event type. The event source specifies for an event handler the object on which that handler
* has been registered and which sent the event to it. The event target defines the path through * has been registered and which sent the event to it. The event target defines the path through
* which the event will travel when posted. The event type provides additional classification to * which the event will travel when posted. The event type provides additional classification to
......
...@@ -21,14 +21,9 @@ ...@@ -21,14 +21,9 @@
package org.dockfx; package org.dockfx;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Stack; import java.util.Stack;
import com.sun.javafx.stage.StageHelper;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent; import javafx.event.ActionEvent;
import javafx.event.Event; import javafx.event.Event;
import javafx.event.EventHandler; import javafx.event.EventHandler;
...@@ -57,15 +52,15 @@ public class DockTitleBar extends HBox implements EventHandler<MouseEvent> { ...@@ -57,15 +52,15 @@ public class DockTitleBar extends HBox implements EventHandler<MouseEvent> {
/** /**
* The DockNode this node is a title bar for. * The DockNode this node is a title bar for.
*/ */
private final DockNode dockNode; private DockNode dockNode;
/** /**
* The label node used for captioning and the graphic. * The label node used for captioning and the graphic.
*/ */
private final Label label; private Label label;
/** /**
* State manipulation buttons including close, maximize, detach, and restore. * State manipulation buttons including close, maximize, detach, and restore.
*/ */
private final Button closeButton, stateButton, minimizeButton; private Button closeButton, stateButton;
/** /**
* Creates a default DockTitleBar with captions and dragging behavior. * Creates a default DockTitleBar with captions and dragging behavior.
...@@ -93,67 +88,28 @@ public class DockTitleBar extends HBox implements EventHandler<MouseEvent> { ...@@ -93,67 +88,28 @@ public class DockTitleBar extends HBox implements EventHandler<MouseEvent> {
closeButton = new Button(); closeButton = new Button();
closeButton.setOnAction(new EventHandler<ActionEvent>() { closeButton.setOnAction(new EventHandler<ActionEvent>() {
@Override @Override
public void handle(ActionEvent event) { public void handle(ActionEvent event) {
dockNode.close(); dockNode.close();
} }
}); });
closeButton.visibleProperty().bind(dockNode.closableProperty());
minimizeButton = new Button();
minimizeButton.setOnAction(new EventHandler<ActionEvent>() { // create a pane that will stretch to make the buttons right aligned
@Override Pane fillPane = new Pane();
public void handle(ActionEvent event) { HBox.setHgrow(fillPane, Priority.ALWAYS);
dockNode.setMinimized(true);
} getChildren().addAll(label, fillPane, stateButton, closeButton);
});
this.addEventHandler(MouseEvent.MOUSE_PRESSED, this); this.addEventHandler(MouseEvent.MOUSE_PRESSED, this);
this.addEventHandler(MouseEvent.DRAG_DETECTED, this); this.addEventHandler(MouseEvent.DRAG_DETECTED, this);
this.addEventHandler(MouseEvent.MOUSE_DRAGGED, this); this.addEventHandler(MouseEvent.MOUSE_DRAGGED, this);
this.addEventHandler(MouseEvent.MOUSE_RELEASED, this); this.addEventHandler(MouseEvent.MOUSE_RELEASED, this);
label.getStyleClass().add("dock-title-label"); label.getStyleClass().add("dock-title-label");
closeButton.getStyleClass().add("dock-close-button"); closeButton.getStyleClass().add("dock-close-button");
stateButton.getStyleClass().add("dock-state-button"); stateButton.getStyleClass().add("dock-state-button");
minimizeButton.getStyleClass().add("dock-minimize-button");
this.getStyleClass().add("dock-title-bar"); this.getStyleClass().add("dock-title-bar");
// create a pane that will stretch to make the buttons right aligned
Pane fillPane = new Pane();
HBox.setHgrow(fillPane, Priority.ALWAYS);
dockNode.closableProperty().addListener( new ChangeListener< Boolean >()
{
@Override public void changed( ObservableValue< ? extends Boolean > observable, Boolean oldValue, Boolean newValue )
{
if(newValue)
{
if(!getChildren().contains( closeButton ))
getChildren().add( closeButton );
}
else
{
getChildren().removeIf( c -> c.equals( closeButton ) );
}
}
} );
dockNode.minimizableProperty().addListener( new ChangeListener< Boolean >()
{
@Override public void changed( ObservableValue< ? extends Boolean > observable, Boolean oldValue, Boolean newValue )
{
if(newValue)
{
getChildren().add(2, minimizeButton);
}
else
{
getChildren().remove( minimizeButton );
}
}
} );
getChildren().addAll( label, fillPane, stateButton, closeButton );
} }
/** /**
...@@ -193,15 +149,6 @@ public class DockTitleBar extends HBox implements EventHandler<MouseEvent> { ...@@ -193,15 +149,6 @@ public class DockTitleBar extends HBox implements EventHandler<MouseEvent> {
public final Button getStateButton() { public final Button getStateButton() {
return stateButton; return stateButton;
} }
/**
* The button used for minimizing this title bar and its associated dock node.
*
* @return The button used for minimizing this title bar and its associated dock node.
*/
public final Button getMinimizeButton() {
return minimizeButton;
}
/** /**
* The dock node that is associated with this title bar. * The dock node that is associated with this title bar.
...@@ -278,10 +225,14 @@ public class DockTitleBar extends HBox implements EventHandler<MouseEvent> { ...@@ -278,10 +225,14 @@ public class DockTitleBar extends HBox implements EventHandler<MouseEvent> {
// RFE for public scene graph traversal API filed but closed: // RFE for public scene graph traversal API filed but closed:
// https://bugs.openjdk.java.net/browse/JDK-8133331 // https://bugs.openjdk.java.net/browse/JDK-8133331
ObservableList<Stage> stages = List<DockPane> dockPanes = DockPane.dockPanes;
FXCollections.unmodifiableObservableList(StageHelper.getStages());
// fire the dock over event for the active stages // fire the dock over event for the active stages
for (Stage targetStage : stages) { for (DockPane dockPane : dockPanes) {
Window window = dockPane.getScene().getWindow();
if (!(window instanceof Stage)) continue;
Stage targetStage = (Stage) window;
// obviously this title bar does not need to receive its own events // obviously this title bar does not need to receive its own events
// though users of this library may want to know when their // though users of this library may want to know when their
// dock node is being dragged by subclassing it or attaching // dock node is being dragged by subclassing it or attaching
...@@ -352,7 +303,7 @@ public class DockTitleBar extends HBox implements EventHandler<MouseEvent> { ...@@ -352,7 +303,7 @@ public class DockTitleBar extends HBox implements EventHandler<MouseEvent> {
// then we need to offset the stage position by // then we need to offset the stage position by
// the height of this title bar // the height of this title bar
if (!dockNode.isCustomTitleBar() && dockNode.isDecorated()) { if (!dockNode.isCustomTitleBar() && dockNode.isDecorated()) {
dockNode.setFloating(true, new Point2D(0, DockTitleBar.this.getHeight()), null); dockNode.setFloating(true, new Point2D(0, DockTitleBar.this.getHeight()));
} else { } else {
dockNode.setFloating(true); dockNode.setFloating(true);
} }
...@@ -404,12 +355,6 @@ public class DockTitleBar extends HBox implements EventHandler<MouseEvent> { ...@@ -404,12 +355,6 @@ public class DockTitleBar extends HBox implements EventHandler<MouseEvent> {
Stage stage = dockNode.getStage(); Stage stage = dockNode.getStage();
Insets insetsDelta = this.getDockNode().getBorderPane().getInsets(); Insets insetsDelta = this.getDockNode().getBorderPane().getInsets();
// it is possible that drag start has not been set if some other node had focus when
// we started the drag
if (null == dragStart) {
dragStart = new Point2D(event.getX(), event.getY());
}
// dragging this way makes the interface more responsive in the event // dragging this way makes the interface more responsive in the event
// the system is lagging as is the case with most current JavaFX // the system is lagging as is the case with most current JavaFX
// implementations on Linux // implementations on Linux
...@@ -419,13 +364,13 @@ public class DockTitleBar extends HBox implements EventHandler<MouseEvent> { ...@@ -419,13 +364,13 @@ public class DockTitleBar extends HBox implements EventHandler<MouseEvent> {
// TODO: change the pick result by adding a copyForPick() // TODO: change the pick result by adding a copyForPick()
DockEvent dockEnterEvent = DockEvent dockEnterEvent =
new DockEvent(this, DockEvent.NULL_SOURCE_TARGET, DockEvent.DOCK_ENTER, event.getX(), new DockEvent(this, DockEvent.NULL_SOURCE_TARGET, DockEvent.DOCK_ENTER, event.getX(),
event.getY(), event.getScreenX(), event.getScreenY(), null, this.getDockNode()); event.getY(), event.getScreenX(), event.getScreenY(), null);
DockEvent dockOverEvent = DockEvent dockOverEvent =
new DockEvent(this, DockEvent.NULL_SOURCE_TARGET, DockEvent.DOCK_OVER, event.getX(), new DockEvent(this, DockEvent.NULL_SOURCE_TARGET, DockEvent.DOCK_OVER, event.getX(),
event.getY(), event.getScreenX(), event.getScreenY(), null, this.getDockNode()); event.getY(), event.getScreenX(), event.getScreenY(), null);
DockEvent dockExitEvent = DockEvent dockExitEvent =
new DockEvent(this, DockEvent.NULL_SOURCE_TARGET, DockEvent.DOCK_EXIT, event.getX(), new DockEvent(this, DockEvent.NULL_SOURCE_TARGET, DockEvent.DOCK_EXIT, event.getX(),
event.getY(), event.getScreenX(), event.getScreenY(), null, this.getDockNode()); event.getY(), event.getScreenX(), event.getScreenY(), null);
EventTask eventTask = new EventTask() { EventTask eventTask = new EventTask() {
@Override @Override
......
...@@ -21,35 +21,32 @@ ...@@ -21,35 +21,32 @@
package org.dockfx.demo; package org.dockfx.demo;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.Random; import java.util.Random;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.layout.BorderPane;
import org.dockfx.DockNode; import org.dockfx.DockNode;
import org.dockfx.DockPane; import org.dockfx.DockPane;
import org.dockfx.DockPos; import org.dockfx.DockPos;
import javafx.application.Application; import javafx.application.Application;
import javafx.scene.Scene; import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.Separator;
import javafx.scene.control.Tab; import javafx.scene.control.Tab;
import javafx.scene.control.TabPane; import javafx.scene.control.TabPane;
import javafx.scene.control.TableColumn; import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView; import javafx.scene.control.TableView;
import javafx.scene.control.ToolBar;
import javafx.scene.control.TreeItem; import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView; import javafx.scene.control.TreeView;
import javafx.scene.image.Image; import javafx.scene.image.Image;
import javafx.scene.image.ImageView; import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane; import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.scene.web.HTMLEditor; import javafx.scene.web.HTMLEditor;
import javafx.stage.Stage; import javafx.stage.Stage;
...@@ -102,63 +99,50 @@ public class DockFX extends Application { ...@@ -102,63 +99,50 @@ public class DockFX extends Application {
DockNode tabsDock = new DockNode(tabs, "Tabs Dock", new ImageView(dockImage)); DockNode tabsDock = new DockNode(tabs, "Tabs Dock", new ImageView(dockImage));
tabsDock.setPrefSize(300, 100); tabsDock.setPrefSize(300, 100);
tabsDock.dock(dockPane, DockPos.TOP); tabsDock.dock(dockPane, DockPos.TOP);
DockNode tableDock = new DockNode(tableView);
DockNode tableDock = new DockNode(tableView, "Table"); // let's disable our table from being undocked
tableDock.setDockTitleBar(null);
tableDock.setPrefSize(300, 100); tableDock.setPrefSize(300, 100);
tableDock.dock(dockPane, DockPos.BOTTOM); tableDock.dock(dockPane, DockPos.BOTTOM);
MenuItem saveMenuItem = new MenuItem("Save"); final Menu menu1 = new Menu("File");
saveMenuItem.setOnAction(new EventHandler<ActionEvent>() { final Menu menu2 = new Menu("Options");
@Override final Menu menu3 = new Menu("Help");
public void handle(ActionEvent event) {
if(dirExist(getUserDataDirectory())) MenuBar menuBar = new MenuBar();
dockPane.storePreference(getUserDataDirectory() + "dock.pref"); menuBar.getMenus().addAll(menu1, menu2, menu3);
}
}); ToolBar toolBar = new ToolBar(
new Button("New"),
MenuItem restoreMenuItem = new MenuItem("Restore"); new Button("Open"),
restoreMenuItem.setOnAction(new EventHandler<ActionEvent>() { new Button("Save"),
@Override new Separator(),
public void handle(ActionEvent event) { new Button("Clean"),
dockPane.loadPreference(getUserDataDirectory() + "dock.pref"); new Button("Compile"),
} new Button("Run"),
}); new Separator(),
new Button("Debug"),
Menu fileMenu = new Menu("File"); new Button("Profile")
MenuBar menuBar = new MenuBar(fileMenu); );
fileMenu.getItems().addAll(saveMenuItem, restoreMenuItem);
VBox vbox = new VBox();
BorderPane mainBorderPane = new BorderPane(); vbox.getChildren().addAll(menuBar, toolBar, dockPane);
mainBorderPane.setTop(menuBar); VBox.setVgrow(dockPane, Priority.ALWAYS);
mainBorderPane.setCenter(dockPane);
primaryStage.setScene(new Scene(vbox, 800, 500));
// show that overlays are relative to the docking area
mainBorderPane.setLeft(new AnchorPane(generateRandomTree()));
primaryStage.setScene(new Scene(mainBorderPane, 800, 500));
primaryStage.sizeToScene(); primaryStage.sizeToScene();
primaryStage.show(); primaryStage.show();
// can be created and docked before or after the scene is created // can be created and docked before or after the scene is created
// and the stage is shown // and the stage is shown
DockNode treeDock = new DockNode(generateRandomTree(), "Tree Dock1", new ImageView(dockImage)); DockNode treeDock = new DockNode(generateRandomTree(), "Tree Dock", new ImageView(dockImage));
treeDock.setPrefSize(100, 100); treeDock.setPrefSize(100, 100);
treeDock.dock(dockPane, DockPos.LEFT); treeDock.dock(dockPane, DockPos.LEFT);
treeDock = new DockNode(generateRandomTree(), "Tree Dock2", new ImageView(dockImage)); treeDock = new DockNode(generateRandomTree(), "Tree Dock", new ImageView(dockImage));
treeDock.setPrefSize(100, 100); treeDock.setPrefSize(100, 100);
treeDock.dock(dockPane, DockPos.RIGHT); treeDock.dock(dockPane, DockPos.RIGHT);
// If you want to get notified when the docknode is closed. You can add ChangeListener to DockNode's closedProperty()
treeDock.closedProperty().addListener( new ChangeListener< Boolean >()
{
@Override public void changed( ObservableValue< ? extends Boolean > observable, Boolean oldValue, Boolean newValue )
{
if(newValue)
System.out.println("TreeDock(DockPos.RIGHT) is closed.");
}
} );
// test the look and feel with both Caspian and Modena // test the look and feel with both Caspian and Modena
Application.setUserAgentStylesheet(Application.STYLESHEET_MODENA); Application.setUserAgentStylesheet(Application.STYLESHEET_MODENA);
// initialize the default styles for the dock pane and undocked nodes using the DockFX // initialize the default styles for the dock pane and undocked nodes using the DockFX
...@@ -191,23 +175,4 @@ public class DockFX extends Application { ...@@ -191,23 +175,4 @@ public class DockFX extends Application {
return treeView; return treeView;
} }
public static boolean dirExist(String dir)
{
String path = getUserDataDirectory();
if(!new File(path).exists())
return new File(path).mkdirs();
else
return true;
}
public static String getUserDataDirectory() {
return System.getProperty("user.home") + File.separator + ".dockfx" + File.separator
+ getApplicationVersionString() + File.separator;
}
public static String getApplicationVersionString() {
return "1.0";
}
} }
/**
* @file DockFX.java
* @brief Driver demonstrating basic dock layout with prototypes. Maintained in a separate package
* to ensure the encapsulation of org.dockfx private package members.
*
* @section License
*
* This file is a part of the DockFX Library. Copyright (C) 2015 Robert B. Colton
*
* This program is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program. If not, see <http://www.gnu.org/licenses/>.
**/
package org.dockfx.demo;
import org.dockfx.DockPane;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.control.ToolBar;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import org.dockfx.DockNode;
import org.dockfx.DockPos;
/**
* This app creates two dock panes, one over the other. Nodes can be added to either.
* If dock pane A is "exclusive", then A will ignore nodes from B (because A is
* exclusive and won't accept nodes from any other dockpane, and B will ignore nodes
* from A because A is exclusive and won't let go of them.
*
* If neither A or B is exclusive, Issue #24 from RobertBColton/DockFX will occur.
* @author will
*/
public class TwoDockPanes extends Application {
public static void main(String[] args) {
launch(args);
}
private VBox vbox;
private DockPane dp1;
private DockPane dp2;
private int counter = 0;
private final Image dockImage =
new Image(DockFX.class.getResource("docknode.png").toExternalForm());
@SuppressWarnings("unchecked")
@Override
public void start(Stage primaryStage) {
primaryStage.setTitle("DockFX");
vbox = new VBox();
dp1 = makeDockPane("A");
dp2 = makeDockPane("B");