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
# https://gradle.org/
# https://github.com/gradle/gradle
image: key-dev-jdk8
image: key-dev-jdk10
cache:
paths:
......@@ -13,13 +13,15 @@ cache:
# runtime for each build is more reliable since the runtime is completely
# isolated from any previous builds.
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:
- 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:
- build
......@@ -39,10 +41,26 @@ build:jdk9:
- .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:
stage: build
variables:
GRADLE_OPTS: "-Dorg.gradle.daemon=false"
script: gradle --build-cache assemble
image: key-dev-jdk8
cache:
key: "$CI_COMMIT_REF_NAME"
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;
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
* 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
......
/**
* @file DockNode.java
* @brief Class implementing basic dock node with floating and styling.
*
* @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/>.
* <p>
* This file is a part of the DockFX Library. Copyright (C) 2015 Robert B. Colton
* <p>
* 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.
* <p>
* 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.
* <p>
* 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;
import javafx.stage.WindowEvent;
import org.dockfx.viewControllers.DockFXViewController;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.binding.BooleanBinding;
import javafx.beans.property.*;
import javafx.css.PseudoClass;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Insets;
import javafx.geometry.Point2D;
import javafx.geometry.Rectangle2D;
import javafx.scene.Cursor;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Screen;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.stage.Window;
import org.dockfx.pane.DockNodeTab;
/**
* Base class for a dock node that provides the layout of the content along with a title bar and a
* styled border. The dock node can be detached and floated or closed and removed from the layout.
* Dragging behavior is implemented through the title bar.
*
*
* @since DockFX 0.1
*/
public class DockNode extends VBox implements EventHandler<MouseEvent> {
/**
* The style this dock node should use on its stage when set to floating.
*/
private StageStyle stageStyle = StageStyle.UNDECORATED;
/**
* The stage that this dock node is currently using when floating.
*/
private Stage stage;
/**
* The contents of the dock node, i.e. a TreeView or ListView.
*/
private Node contents;
/**
* The title bar that implements our dragging and state manipulation.
*/
private DockTitleBar dockTitleBar;
/**
* The border pane used when floating to provide a styled custom border.
*/
private BorderPane borderPane;
/**
* The dock pane this dock node belongs to when not floating.
*/
private DockPane dockPane;
/**
* View controller of node inside this DockNode
*/
private DockFXViewController viewController;
/**
* Keep window state before its maximizing.
*/
private double widthBeforeMaximizing;
private double heightBeforeMaximizing;
private double xPosBeforeMaximizing;
private double yPosBeforeMaximizing;
/**
* CSS pseudo class selector representing whether this node is currently floating.
*/
private static final PseudoClass FLOATING_PSEUDO_CLASS = PseudoClass.getPseudoClass("floating");
/**
* CSS pseudo class selector representing whether this node is currently docked.
*/
private static final PseudoClass DOCKED_PSEUDO_CLASS = PseudoClass.getPseudoClass("docked");
/**
* CSS pseudo class selector representing whether this node is currently maximized.
*/
private static final PseudoClass MAXIMIZED_PSEUDO_CLASS = PseudoClass.getPseudoClass("maximized");
/**
* Boolean property maintaining whether this node is currently maximized.
*
* @defaultValue false
*/
private BooleanProperty maximizedProperty = new SimpleBooleanProperty(false) {
/**
* CSS pseudo class selector representing whether this node is currently floating.
*/
private static final PseudoClass FLOATING_PSEUDO_CLASS = PseudoClass.getPseudoClass("floating");
/**
* CSS pseudo class selector representing whether this node is currently docked.
*/
private static final PseudoClass DOCKED_PSEUDO_CLASS = PseudoClass.getPseudoClass("docked");
/**
* CSS pseudo class selector representing whether this node is currently maximized.
*/
private static final PseudoClass MAXIMIZED_PSEUDO_CLASS = PseudoClass.getPseudoClass("maximized");
/**
* The style this dock node should use on its stage when set to floating.
*/
private StageStyle stageStyle = StageStyle.TRANSPARENT;
/**
* The stage that this dock node is currently using when floating.
*/
private Stage stage;
/**
* The contents of the dock node, i.e. a TreeView or ListView.
*/
private Node contents;
/**
* The title bar that implements our dragging and state manipulation.
*/
private DockTitleBar dockTitleBar;
/**
* The border pane used when floating to provide a styled custom border.
*/
private BorderPane borderPane;
/**
* The dock pane this dock node belongs to when not floating.
*/
private DockPane dockPane;
/**
* Boolean property maintaining whether this node is currently maximized.
*
* @defaultValue false
*/
private BooleanProperty maximizedProperty = new SimpleBooleanProperty(false) {
@Override
protected void invalidated() {
DockNode.this.pseudoClassStateChanged(MAXIMIZED_PSEUDO_CLASS, get());
if (borderPane != null) {
borderPane.pseudoClassStateChanged(MAXIMIZED_PSEUDO_CLASS, get());
}
stage.setMaximized(get());
// TODO: This is a work around to fill the screen bounds and not overlap the task bar when
// the window is undecorated as in Visual Studio. A similar work around needs applied for
// JFrame in Swing. http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4737788
// Bug report filed:
// https://bugs.openjdk.java.net/browse/JDK-8133330
if (this.get()) {
Screen screen = Screen
.getScreensForRectangle(stage.getX(), stage.getY(), stage.getWidth(), stage.getHeight())
.get(0);
Rectangle2D bounds = screen.getVisualBounds();
stage.setX(bounds.getMinX());
stage.setY(bounds.getMinY());
stage.setWidth(bounds.getWidth());
stage.setHeight(bounds.getHeight());
}
}
@Override
protected void invalidated() {
DockNode.this.pseudoClassStateChanged(MAXIMIZED_PSEUDO_CLASS, get());
if (borderPane != null) {
borderPane.pseudoClassStateChanged(MAXIMIZED_PSEUDO_CLASS, get());
}
if (!get()) {
stage.setX(xPosBeforeMaximizing);
stage.setY(yPosBeforeMaximizing);
stage.setWidth(widthBeforeMaximizing);
stage.setHeight(heightBeforeMaximizing);
}else{
widthBeforeMaximizing = stage.getWidth();
heightBeforeMaximizing = stage.getHeight();
xPosBeforeMaximizing = stage.getX();
yPosBeforeMaximizing = stage.getY();
}
// TODO: This is a work around to fill the screen bounds and not overlap the task bar when
// the window is undecorated as in Visual Studio. A similar work around needs applied for
// JFrame in Swing. http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4737788
// Bug report filed:
// https://bugs.openjdk.java.net/browse/JDK-8133330
if (this.get()) {
Screen screen = Screen
.getScreensForRectangle(stage.getX(), stage.getY(), stage.getWidth(), stage.getHeight())
.get(0);
Rectangle2D bounds = screen.getVisualBounds();
stage.setX(bounds.getMinX());
stage.setY(bounds.getMinY());
stage.setWidth(bounds.getWidth());
stage.setHeight(bounds.getHeight());
}
}
@Override
public String getName() {
return "maximized";
}
};
private ObjectProperty<Node> graphicProperty = new SimpleObjectProperty<Node>() {
@Override
public String getName() {
return "graphic";
}
};
private StringProperty titleProperty = new SimpleStringProperty("Dock") {
@Override
public String getName() {
return "title";
}
};
private BooleanProperty customTitleBarProperty = new SimpleBooleanProperty(true) {
@Override
public String getName() {
return "customTitleBar";
}
};
private BooleanProperty floatingProperty = new SimpleBooleanProperty(false) {
@Override
protected void invalidated() {
DockNode.this.pseudoClassStateChanged(FLOATING_PSEUDO_CLASS, get());
if (borderPane != null) {
borderPane.pseudoClassStateChanged(FLOATING_PSEUDO_CLASS, get());
}
}
@Override
public String getName() {
return "maximized";
}
};
public DockNode(Node contents, String title, Node graphic, DockFXViewController controller) {
initializeDockNode(contents, title, graphic, controller);
}
/**
* Creates a default DockNode with a default title bar and layout.
*
* @param contents The contents of the dock node which may be a tree or another scene graph node.
* @param title The caption title of this dock node which maintains bidirectional state with the
* title bar and stage.
* @param graphic The caption graphic of this dock node which maintains bidirectional state with
* the title bar and stage.
*/
public DockNode(Node contents, String title, Node graphic) {
this(contents, title, graphic, null);
}
/**
* Creates a default DockNode with a default title bar and layout.
*
* @param contents The contents of the dock node which may be a tree or another scene graph node.
* @param title The caption title of this dock node which maintains bidirectional state with the
* title bar and stage.
*/
public DockNode(Node contents, String title) {
this(contents, title, null);
}
/**
* Creates a default DockNode with a default title bar and layout.
*
* @param contents The contents of the dock node which may be a tree or another scene graph node.
*/
public DockNode(Node contents) {
this(contents, null, null);
}
/**
*
* Creates a default DockNode with contents loaded from FXMLFile at provided path.
*
* @param FXMLPath path to fxml file.
* @param title The caption title of this dock node which maintains bidirectional state with the
* title bar and stage.
* @param graphic The caption title of this dock node which maintains bidirectional state with the
* title bar and stage.
*/
public DockNode(String FXMLPath, String title, Node graphic) {
FXMLLoader loader = loadNode(FXMLPath);
initializeDockNode(loader.getRoot(), title, graphic, loader.getController());
}
/**
* Creates a default DockNode with contents loaded from FXMLFile at provided path.
*
* @param FXMLPath path to fxml file.
* @param title The caption title of this dock node which maintains bidirectional state with the
* title bar and stage.
*/
public DockNode(String FXMLPath, String title) {
this(FXMLPath, title, null);
}
/**
* Creates a default DockNode with contents loaded from FXMLFile at provided path with default
* title bar.
*
* @param FXMLPath path to fxml file.
*/
public DockNode(String FXMLPath) {
this(FXMLPath, null, null);
}
/**
* Loads Node from fxml file located at FXMLPath and returns it.
*
* @param FXMLPath Path to fxml file.
* @return Node loaded from fxml file or StackPane with Label with error message.
*/
private static FXMLLoader loadNode(String FXMLPath) {
FXMLLoader loader = new FXMLLoader();
try {
loader.load(DockNode.class.getResourceAsStream(FXMLPath));
@Override
public String getName() {
return "floating";
}
};
private BooleanProperty floatableProperty = new SimpleBooleanProperty(true) {
@Override
public String getName() {
return "floatable";
}
};
private BooleanProperty closableProperty = new SimpleBooleanProperty(true) {
@Override
public String getName() {
return "closable";
}
};
private BooleanProperty stageResizableProperty = new SimpleBooleanProperty(true) {
@Override
public String getName() {
return "resizable";
}
};
private BooleanProperty dockedProperty = new SimpleBooleanProperty(false) {
@Override
protected void invalidated() {
if (get()) {
if (dockTitleBar != null) {
dockTitleBar.setVisible(true);
dockTitleBar.setManaged(true);
}
}
DockNode.this.pseudoClassStateChanged(DOCKED_PSEUDO_CLASS, get());
}
@Override
public String getName() {
return "docked";
}
};
/**
* The last position of the mouse that was within the minimum layout bounds.
*/
private Point2D sizeLast;
/**
* Whether we are currently resizing in a given direction.
*/
private boolean sizeWest = false, sizeEast = false, sizeNorth = false, sizeSouth = false;
/**
* Creates a default DockNode with a default title bar and layout.
*
* @param contents The contents of the dock node which may be a tree or another scene graph node.
* @param title The caption title of this dock node which maintains bidirectional state with the
* title bar and stage.
* @param graphic The caption graphic of this dock node which maintains bidirectional state with
* the title bar and stage.
*/
public DockNode(Node contents, String title, Node graphic) {
this.titleProperty.setValue(title);
this.graphicProperty.setValue(graphic);
this.contents = contents;
dockTitleBar = new DockTitleBar(this);
getChildren().addAll(dockTitleBar, contents);
VBox.setVgrow(contents, Priority.ALWAYS);
this.getStyleClass().add("dock-node");
}
catch (Exception e) {
e.printStackTrace();
loader.setRoot(new StackPane(new Label("Could not load FXML file")));
/**
* Creates a default DockNode with a default title bar and layout.
*
* @param contents The contents of the dock node which may be a tree or another scene graph node.
* @param title The caption title of this dock node which maintains bidirectional state with the
* title bar and stage.
*/
public DockNode(Node contents, String title) {
this(contents, title, null);
}
return loader;
}
/**
* Sets DockNodes contents, title and title bar graphic
*
* @param contents The contents of the dock node which may be a tree or another scene graph node.
* @param title The caption title of this dock node which maintains bidirectional state with the
* title bar and stage.
* @param graphic The caption title of this dock node which maintains bidirectional state with the
* title bar and stage.
*/
private void initializeDockNode(Node contents, String title, Node graphic, DockFXViewController controller) {
if ( null == title || title.isEmpty() )
title = "New Dock";
this.titleProperty.setValue(title);
this.graphicProperty.setValue(graphic);
this.contents = contents;
this.viewController = controller;
dockTitleBar = new DockTitleBar( this );
getChildren().addAll( dockTitleBar, contents );
if (viewController != null) {
viewController.setDockTitleBar(dockTitleBar);
/**
* Creates a default DockNode with a default title bar and layout.
*
* @param contents The contents of the dock node which may be a tree or another scene graph node.
*/
public DockNode(Node contents) {
this(contents, null, null);
}
VBox.setVgrow(contents, Priority.ALWAYS);
this.getStyleClass().add("dock-node");
}
/**
* The stage style that will be used when the dock node is floating. This must be set prior to
* setting the dock node to floating.
*
* @param stageStyle The stage style that will be used when the node is floating.
*/
public void setStageStyle(StageStyle stageStyle) {
this.stageStyle = stageStyle;
}
/**
* Changes the contents of the dock node.
*
* @param contents The new contents of this dock node.
*/
public void setContents(Node contents) {
this.getChildren().set(this.getChildren().indexOf(this.contents), contents);
this.contents = contents;
}
/**
* Changes the title bar in the layout of this dock node. This can be used to remove the dock
* title bar from the dock node by passing null.
*
* @param dockTitleBar null The new title bar of this dock node, can be set null indicating no
* title bar is used.
*/
public void setDockTitleBar(DockTitleBar dockTitleBar) {
if (dockTitleBar != null) {
if (this.dockTitleBar != null) {
this.getChildren().set(this.getChildren().indexOf(this.dockTitleBar), dockTitleBar);
} else {
this.getChildren().add(0, dockTitleBar);
}
} else {
this.getChildren().remove(this.dockTitleBar);
/**
* The stage style that will be used when the dock node is floating. This must be set prior to
* setting the dock node to floating.
*
* @param stageStyle The stage style that will be used when the node is floating.
*/