Skip to content

Commit 00f5b7c

Browse files
author
Jeanette Winzenburg
committed
8253597: TreeTableView: must select leaf row on click into indentation region
Reviewed-by: aghaisas
1 parent 205e4b9 commit 00f5b7c

File tree

4 files changed

+702
-6
lines changed

4 files changed

+702
-6
lines changed

modules/javafx.controls/src/main/java/com/sun/javafx/scene/control/behavior/TreeTableCellBehavior.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -120,7 +120,8 @@ public TreeTableCellBehavior(TreeTableCell<S,T> control) {
120120

121121
if (column == treeColumn) {
122122
final Node disclosureNode = getNode().getTreeTableRow().getDisclosureNode();
123-
if (disclosureNode != null) {
123+
// fix JDK-8253597: check disclosure node for visibility along with existence
124+
if (disclosureNode != null && disclosureNode.isVisible()) {
124125
double startX = 0;
125126
for (TreeTableColumn<S,?> tc : treeTableView.getVisibleLeafColumns()) {
126127
if (tc == treeColumn) break;

modules/javafx.controls/src/test/java/test/com/sun/javafx/scene/control/infrastructure/MouseEventFirer.java

Lines changed: 85 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -25,28 +25,38 @@
2525

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

28+
import java.util.Arrays;
29+
import java.util.List;
30+
2831
import javafx.event.Event;
2932
import javafx.event.EventTarget;
3033
import javafx.event.EventType;
3134
import javafx.geometry.BoundingBox;
3235
import javafx.geometry.Bounds;
36+
import javafx.geometry.Point2D;
3337
import javafx.scene.Node;
3438
import javafx.scene.Scene;
3539
import javafx.scene.input.MouseButton;
3640
import javafx.scene.input.MouseEvent;
3741
import javafx.scene.input.PickResult;
3842
import javafx.stage.Window;
3943

40-
import java.util.Arrays;
41-
import java.util.List;
42-
44+
/**
45+
* Helper to fire MouseEvents onto a EventTarget which is either Node or Scene.
46+
* There are methods to configure the event by eventType, clickCount, location (delta from default),
47+
* mouseButton and keyModifiers.
48+
* <p>
49+
* The default local coordinates are the center of the target.
50+
*/
4351
public final class MouseEventFirer {
4452
private final EventTarget target;
4553

4654
private final Scene scene;
4755
private final Bounds targetBounds;
4856
private StageLoader sl;
4957

58+
private boolean alternative;
59+
5060
public MouseEventFirer(EventTarget target) {
5161
this.target = target;
5262

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

86+
/**
87+
* Instantiates a MouseEventFirer on the given node.
88+
* <p>
89+
* Note: this was added as hot-fix for JDK-8253769.
90+
*
91+
* @param target the node to fire on
92+
* @param alternative uses alternative creation path for mouseEvent if true.
93+
*/
94+
public MouseEventFirer(Node target, boolean alternative) {
95+
this(target);
96+
this.alternative = alternative;
97+
}
98+
7699
public void dispose() {
77100
if (sl != null) {
78101
sl.dispose();
@@ -158,6 +181,15 @@ public void fireMouseEvent(EventType<MouseEvent> evtType, MouseButton button, do
158181
}
159182

160183
private void fireMouseEvent(EventType<MouseEvent> evtType, MouseButton button, int clickCount, double deltaX, double deltaY, KeyModifier... modifiers) {
184+
if (alternative) {
185+
fireMouseEventAlternative(evtType, button, clickCount, deltaX, deltaY, modifiers);
186+
return;
187+
}
188+
// TBD: JDK-8253769
189+
// the mouseEvent created here seems to be valid (in regard to coordinate transformations
190+
// of local/scene/screen) only if the target is glued to the upper leading edge of the scene
191+
// and zero deltaX/Y!
192+
161193
// calculate bounds
162194
final Window window = scene.getWindow();
163195

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

256+
/**
257+
* Fires a mouseEvent with the given configuration options onto the target.
258+
* Hot-fix for JDK-8253769.
259+
* The mouseEvent is created such that coordinate transformation constraints seem to be respected.
260+
*/
261+
private void fireMouseEventAlternative(EventType<MouseEvent> evtType, MouseButton button, int clickCount, double deltaX, double deltaY, KeyModifier... modifiers) {
262+
263+
// width / height of target node
264+
final double w = targetBounds.getWidth();
265+
final double h = targetBounds.getHeight();
266+
267+
// x / y click position is centered
268+
final double x = w / 2.0 + deltaX;
269+
final double y = h / 2.0 + deltaY;
270+
271+
Node node = (Node) target;
272+
273+
Point2D localP = new Point2D(x, y);
274+
Point2D sceneP = node.localToScene(localP);
275+
Point2D screenP = node.localToScreen(localP);
276+
277+
final List<KeyModifier> ml = Arrays.asList(modifiers);
278+
279+
MouseEvent evt = new MouseEvent(
280+
target, // target of this firer
281+
null, // default source (don't care, event dispatch will take over)
282+
evtType,
283+
sceneP.getX(), sceneP.getY(), // can use scene coordinates because source is null
284+
screenP.getX(), screenP.getY(),
285+
button,
286+
clickCount,
287+
ml.contains(KeyModifier.SHIFT), // shiftDown
288+
ml.contains(KeyModifier.CTRL), // ctrlDown
289+
ml.contains(KeyModifier.ALT), // altDown
290+
ml.contains(KeyModifier.META), // metaData
291+
button == MouseButton.PRIMARY, // primary button
292+
button == MouseButton.MIDDLE, // middle button
293+
button == MouseButton.SECONDARY, // secondary button
294+
button == MouseButton.BACK, // back button
295+
button == MouseButton.FORWARD, // forward button
296+
false, // synthesized
297+
button == MouseButton.SECONDARY, // is popup trigger
298+
true, // still since pick
299+
null // default pick (don't care, event constructor will take over)
300+
);
301+
302+
Event.fireEvent(target, evt);
303+
}
304+
224305
// public void fireMouseEvent(Scene target, EventType<MouseEvent> evtType, MouseButton button, int clickCount, double deltaX, double deltaY, KeyModifier... modifiers) {
225306
// List<KeyModifier> ml = Arrays.asList(modifiers);
226307
//

0 commit comments

Comments
 (0)