diff --git a/pom.xml b/pom.xml index 1b45b96..1e057af 100644 --- a/pom.xml +++ b/pom.xml @@ -3,10 +3,10 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.dockfx + de.sandec dockfx jar - 0.4-SNAPSHOT + 0.4.1 DockFX https://github.com/RobertBColton/DockFX.git @@ -16,10 +16,22 @@ true UTF-8 java, properties, xml + 2020.1.1-SNAPSHOT + 15 + + com.sandec.jpro + jpro-maven-plugin + ${jpro.version} + + false + org.dockfx.demo.DockFX + / + + org.apache.maven.plugins maven-jar-plugin @@ -71,9 +83,77 @@ ${project.build.sourceEncoding} + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + + jar + + + + + + + + bintray-sandec-repo + sandec-repo + https://api.bintray.com/maven/sandec/repo/dockfx/;publish=1 + + + + + + jpro - sandec repository + https://sandec.bintray.com/repo + + + + + + jpro - sandec repository + https://sandec.bintray.com/repo + + + + + + org.openjfx + javafx-controls + ${javafx.version} + compile + + + org.openjfx + javafx-web + ${javafx.version} + compile + + + org.openjfx + javafx-swing + ${javafx.version} + compile + + + org.openjfx + javafx-fxml + ${javafx.version} + compile + + + org.openjfx + javafx-media + ${javafx.version} + compile + + + diff --git a/src/main/java/org/dockfx/DockNode.java b/src/main/java/org/dockfx/DockNode.java index bf91f12..d35d94e 100644 --- a/src/main/java/org/dockfx/DockNode.java +++ b/src/main/java/org/dockfx/DockNode.java @@ -95,6 +95,18 @@ protected void invalidated() { borderPane.pseudoClassStateChanged(MAXIMIZED_PSEUDO_CLASS, get()); } + Stage rootWindow = (Stage) stage; + while(rootWindow.getOwner() != null) { + rootWindow = (Stage) rootWindow.getOwner(); + } + if(this.get()) { + stage.setX(rootWindow.getX()); + stage.setY(rootWindow.getY()); + stage.setWidth(rootWindow.getWidth()); + stage.setHeight(rootWindow.getHeight()); + } + + /* stage.setMaximized(get()); // TODO: This is a work around to fill the screen bounds and not overlap the task bar when @@ -113,7 +125,7 @@ protected void invalidated() { stage.setWidth(bounds.getWidth()); stage.setHeight(bounds.getHeight()); - } + }*/ } @Override diff --git a/src/main/java/org/dockfx/DockPane.java b/src/main/java/org/dockfx/DockPane.java index d70bc5a..d3e9b05 100644 --- a/src/main/java/org/dockfx/DockPane.java +++ b/src/main/java/org/dockfx/DockPane.java @@ -13,12 +13,16 @@ import java.util.ArrayList; import java.util.List; import java.util.Stack; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.BiConsumer; import com.sun.javafx.css.StyleManager; +import com.sun.javafx.scene.NodeHelper; import javafx.animation.KeyFrame; import javafx.animation.KeyValue; import javafx.animation.Timeline; +import javafx.beans.value.ChangeListener; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.collections.ObservableMap; @@ -29,12 +33,15 @@ import javafx.geometry.Pos; import javafx.scene.Node; import javafx.scene.Parent; +import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.SplitPane; import javafx.scene.layout.GridPane; import javafx.scene.layout.StackPane; import javafx.scene.shape.Rectangle; import javafx.stage.Popup; +import javafx.stage.Stage; +import javafx.stage.Window; import javafx.util.Duration; /** @@ -48,7 +55,14 @@ public class DockPane extends StackPane implements EventHandler { /** * Package-private internal list of all DockPanes for event mouse picking. */ - static List dockPanes = new ArrayList(); + final static String DOCKFX_DOCKPANES_CONTEXT = "DOCKFX_DOCKPANES_CONTEXT"; + public static List getDockPanes(Stage context) { + if(context.getOwner() != null) return getDockPanes((Stage) context.getOwner()); + if(!context.getProperties().containsKey(DOCKFX_DOCKPANES_CONTEXT)) { + context.getProperties().put(DOCKFX_DOCKPANES_CONTEXT, new ArrayList()); + } + return (List) context.getProperties().get(DOCKFX_DOCKPANES_CONTEXT); + } /** * The current root node of this dock pane's layout. @@ -181,7 +195,6 @@ public final boolean isDockRoot() { */ public DockPane() { super(); - DockPane.dockPanes.add(this); this.addEventHandler(DockEvent.ANY, this); this.addEventFilter(DockEvent.ANY, new EventHandler() { @@ -220,7 +233,19 @@ public void handle(DockEvent event) { KeyValue kv = new KeyValue(dockAreaIndicator.strokeDashOffsetProperty(), 12); KeyFrame kf = new KeyFrame(Duration.millis(500), kv); dockAreaStrokeTimeline.getKeyFrames().add(kf); - dockAreaStrokeTimeline.play(); + + NodeHelper.treeShowingProperty(this).addListener((p,o,n) -> { + if(n) { + DockPane.getDockPanes((Stage) this.getScene().getWindow()).add(this); + dockAreaStrokeTimeline.play(); + } else { + dockAreaStrokeTimeline.stop(); + } + }); + if(NodeHelper.isTreeShowing(this)) { + DockPane.getDockPanes((Stage) this.getScene().getWindow()).add(this); + dockAreaStrokeTimeline.play(); + } DockPosButton dockCenter = new DockPosButton(false, DockPos.CENTER); dockCenter.getStyleClass().add("dock-center"); diff --git a/src/main/java/org/dockfx/DockTitleBar.java b/src/main/java/org/dockfx/DockTitleBar.java index 3406522..fc36e30 100644 --- a/src/main/java/org/dockfx/DockTitleBar.java +++ b/src/main/java/org/dockfx/DockTitleBar.java @@ -211,16 +211,20 @@ public void reset() { * @param eventTask The event task to be run when the event target is found. * @param explicit The explicit event to be fired on the stage root when no event target is found. */ - private void pickEventTarget(Point2D location, EventTask eventTask, Event explicit) { + private void pickEventTarget(Point2D location, EventTask eventTask, Event explicit, Stage context) { // RFE for public scene graph traversal API filed but closed: // https://bugs.openjdk.java.net/browse/JDK-8133331 - List dockPanes = DockPane.dockPanes; + List dockPanes = DockPane.getDockPanes(context); // fire the dock over event for the active stages for (DockPane dockPane : dockPanes) { + if(dockPane.getScene() == null) continue; Window window = dockPane.getScene().getWindow(); if (!(window instanceof Stage)) continue; + if (!window.isShowing()) { + continue; + } Stage targetStage = (Stage) window; // obviously this title bar does not need to receive its own events @@ -386,7 +390,7 @@ public void run(Node node, Node dragNode) { }; this.pickEventTarget(new Point2D(event.getScreenX(), event.getScreenY()), eventTask, - dockExitEvent); + dockExitEvent, stage); } else if (event.getEventType() == MouseEvent.MOUSE_RELEASED) { dragging = false; @@ -405,7 +409,7 @@ public void run(Node node, Node dragNode) { } }; - this.pickEventTarget(new Point2D(event.getScreenX(), event.getScreenY()), eventTask, null); + this.pickEventTarget(new Point2D(event.getScreenX(), event.getScreenY()), eventTask, null, (Stage) this.getScene().getWindow()); dragNodes.clear(); diff --git a/src/main/java/org/dockfx/demo/DockFX.java b/src/main/java/org/dockfx/demo/DockFX.java index 5cf8935..924f8f5 100644 --- a/src/main/java/org/dockfx/demo/DockFX.java +++ b/src/main/java/org/dockfx/demo/DockFX.java @@ -16,23 +16,13 @@ import java.nio.file.Paths; import java.util.Random; +import javafx.scene.control.*; import org.dockfx.DockNode; import org.dockfx.DockPane; import org.dockfx.DockPos; import javafx.application.Application; 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.TabPane; -import javafx.scene.control.TableColumn; -import javafx.scene.control.TableView; -import javafx.scene.control.ToolBar; -import javafx.scene.control.TreeItem; -import javafx.scene.control.TreeView; import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.layout.Priority; @@ -56,15 +46,10 @@ public void start(Stage primaryStage) { // create a default test node for the center of the dock area TabPane tabs = new TabPane(); - HTMLEditor htmlEditor = new HTMLEditor(); - try { - htmlEditor.setHtmlText(new String(Files.readAllBytes(Paths.get("readme.html")))); - } catch (IOException e) { - e.printStackTrace(); - } + // empty tabs ensure that dock node has its own background color when floating - tabs.getTabs().addAll(new Tab("Tab 1", htmlEditor), new Tab("Tab 2"), new Tab("Tab 3")); + tabs.getTabs().addAll(new Tab("Tab 1", new Label("Coontent!")), new Tab("Tab 2"), new Tab("Tab 3")); TableView tableView = new TableView(); // this is why @SupressWarnings is used above