Skip to content
Permalink
Browse files
8253597: TreeTableView: must select leaf row on click into indentatio…
…n region

Reviewed-by: aghaisas
  • Loading branch information
Jeanette Winzenburg committed Oct 12, 2020
1 parent 205e4b9 commit 00f5b7c2687e22d40a5cf81c691609f00e583e3a
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -120,7 +120,8 @@ public TreeTableCellBehavior(TreeTableCell<S,T> control) {

if (column == treeColumn) {
final Node disclosureNode = getNode().getTreeTableRow().getDisclosureNode();
if (disclosureNode != null) {
// fix JDK-8253597: check disclosure node for visibility along with existence
if (disclosureNode != null && disclosureNode.isVisible()) {
double startX = 0;
for (TreeTableColumn<S,?> tc : treeTableView.getVisibleLeafColumns()) {
if (tc == treeColumn) break;
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,28 +25,38 @@

package test.com.sun.javafx.scene.control.infrastructure;

import java.util.Arrays;
import java.util.List;

import javafx.event.Event;
import javafx.event.EventTarget;
import javafx.event.EventType;
import javafx.geometry.BoundingBox;
import javafx.geometry.Bounds;
import javafx.geometry.Point2D;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.PickResult;
import javafx.stage.Window;

import java.util.Arrays;
import java.util.List;

/**
* Helper to fire MouseEvents onto a EventTarget which is either Node or Scene.
* There are methods to configure the event by eventType, clickCount, location (delta from default),
* mouseButton and keyModifiers.
* <p>
* The default local coordinates are the center of the target.
*/
public final class MouseEventFirer {
private final EventTarget target;

private final Scene scene;
private final Bounds targetBounds;
private StageLoader sl;

private boolean alternative;

public MouseEventFirer(EventTarget target) {
this.target = target;

@@ -73,6 +83,19 @@ public MouseEventFirer(EventTarget target) {
}
}

/**
* Instantiates a MouseEventFirer on the given node.
* <p>
* Note: this was added as hot-fix for JDK-8253769.
*
* @param target the node to fire on
* @param alternative uses alternative creation path for mouseEvent if true.
*/
public MouseEventFirer(Node target, boolean alternative) {
this(target);
this.alternative = alternative;
}

public void dispose() {
if (sl != null) {
sl.dispose();
@@ -158,6 +181,15 @@ public void fireMouseEvent(EventType<MouseEvent> evtType, MouseButton button, do
}

private void fireMouseEvent(EventType<MouseEvent> evtType, MouseButton button, int clickCount, double deltaX, double deltaY, KeyModifier... modifiers) {
if (alternative) {
fireMouseEventAlternative(evtType, button, clickCount, deltaX, deltaY, modifiers);
return;
}
// TBD: JDK-8253769
// the mouseEvent created here seems to be valid (in regard to coordinate transformations
// of local/scene/screen) only if the target is glued to the upper leading edge of the scene
// and zero deltaX/Y!

// calculate bounds
final Window window = scene.getWindow();

@@ -221,6 +253,55 @@ private void fireMouseEvent(EventType<MouseEvent> evtType, MouseButton button, i
Event.fireEvent(target, evt);
}

/**
* Fires a mouseEvent with the given configuration options onto the target.
* Hot-fix for JDK-8253769.
* The mouseEvent is created such that coordinate transformation constraints seem to be respected.
*/
private void fireMouseEventAlternative(EventType<MouseEvent> evtType, MouseButton button, int clickCount, double deltaX, double deltaY, KeyModifier... modifiers) {

// width / height of target node
final double w = targetBounds.getWidth();
final double h = targetBounds.getHeight();

// x / y click position is centered
final double x = w / 2.0 + deltaX;
final double y = h / 2.0 + deltaY;

Node node = (Node) target;

Point2D localP = new Point2D(x, y);
Point2D sceneP = node.localToScene(localP);
Point2D screenP = node.localToScreen(localP);

final List<KeyModifier> ml = Arrays.asList(modifiers);

MouseEvent evt = new MouseEvent(
target, // target of this firer
null, // default source (don't care, event dispatch will take over)
evtType,
sceneP.getX(), sceneP.getY(), // can use scene coordinates because source is null
screenP.getX(), screenP.getY(),
button,
clickCount,
ml.contains(KeyModifier.SHIFT), // shiftDown
ml.contains(KeyModifier.CTRL), // ctrlDown
ml.contains(KeyModifier.ALT), // altDown
ml.contains(KeyModifier.META), // metaData
button == MouseButton.PRIMARY, // primary button
button == MouseButton.MIDDLE, // middle button
button == MouseButton.SECONDARY, // secondary button
button == MouseButton.BACK, // back button
button == MouseButton.FORWARD, // forward button
false, // synthesized
button == MouseButton.SECONDARY, // is popup trigger
true, // still since pick
null // default pick (don't care, event constructor will take over)
);

Event.fireEvent(target, evt);
}

// public void fireMouseEvent(Scene target, EventType<MouseEvent> evtType, MouseButton button, int clickCount, double deltaX, double deltaY, KeyModifier... modifiers) {
// List<KeyModifier> ml = Arrays.asList(modifiers);
//

0 comments on commit 00f5b7c

Please sign in to comment.