FULL PRODUCT VERSION :
java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
the bug is OS-independent
A DESCRIPTION OF THE PROBLEM :
The layout algorithm of TreeCellSkin uses a default value of 18 pixels for the width of disclosure node. This value is increased and cached for every TreeView in maxDisclosureWidthMap, but never decreased.
Hence, whenever no or a small disclosure node is shown, for example as in one of the following cases
- user sets custom disclosure node to something smaller than 18 pixels
- user sets disclosure node to null
- TreeView has showRoot=null and maximum level of shown tree is 1 (that is, there are only leaves)
an unwanted indentation of up to 18 pixels is rendered for every TreeCell.
Forthermore, the computePrefWidth-algorithm works correctly and so the TreeCells in question have wrongly calculated prefWidths. For example, this results in text overrun as shown in the given test case.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
It happens on every TreeView that matches the conditions given in "Description". The test case given below creates a TreeView with showRoot=false and puts a tree with maximum level 1 into it.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
We do not expect any indentation on the TreeItems.
We want to see all TreeItems completely, if they are wider than TreeView, this should be possible by vertical scrolling.
ACTUAL -
We see an indentation of 18 pixels at every TreeItem.
The TreeItem with content "This is very, very, very long text." is not completely shown, even when scrolled to the right.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
package application;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
try {
TreeItem<String> root = new TreeItem<>();
root.getChildren().add(new TreeItem<>("Short text."));
root.getChildren().add(new TreeItem<>("This is very, very, very long text."));
TreeView<String> treeView = new TreeView<>(root);
treeView.setShowRoot(false);
treeView.setMinWidth(150);
treeView.setPrefWidth(150);
treeView.setMaxWidth(150);
Scene scene = new Scene(treeView, 150, 150);
primaryStage.setScene(scene);
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
One can trick TreeCellSkin by the following hack that has to be applied on every TreeView and that initializes the maximum width of the disclosure node to 0 pixels. If there actually is a disclosure node to show, the existing layout code automatically increases this value.
static public void workaroundForJDK8090897(TreeView<?> treeView) {
try {
Field maxDisclosureWidthMapField = TreeCellSkin.class.getDeclaredField("maxDisclosureWidthMap"); //$NON-NLS-1$
maxDisclosureWidthMapField.setAccessible(true);
@SuppressWarnings("unchecked")
Map<TreeView<?>, Double> maxDisclosureWidthMap = (Map<TreeView<?>, Double>) maxDisclosureWidthMapField
.get(null);
maxDisclosureWidthMap.put(treeView, 0.0);
} catch (Exception e) {
// If TreeCellSkin has not the expected structure, we cannot know
// how anything works - so we silently give up.
}
}
java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
the bug is OS-independent
A DESCRIPTION OF THE PROBLEM :
The layout algorithm of TreeCellSkin uses a default value of 18 pixels for the width of disclosure node. This value is increased and cached for every TreeView in maxDisclosureWidthMap, but never decreased.
Hence, whenever no or a small disclosure node is shown, for example as in one of the following cases
- user sets custom disclosure node to something smaller than 18 pixels
- user sets disclosure node to null
- TreeView has showRoot=null and maximum level of shown tree is 1 (that is, there are only leaves)
an unwanted indentation of up to 18 pixels is rendered for every TreeCell.
Forthermore, the computePrefWidth-algorithm works correctly and so the TreeCells in question have wrongly calculated prefWidths. For example, this results in text overrun as shown in the given test case.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
It happens on every TreeView that matches the conditions given in "Description". The test case given below creates a TreeView with showRoot=false and puts a tree with maximum level 1 into it.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
We do not expect any indentation on the TreeItems.
We want to see all TreeItems completely, if they are wider than TreeView, this should be possible by vertical scrolling.
ACTUAL -
We see an indentation of 18 pixels at every TreeItem.
The TreeItem with content "This is very, very, very long text." is not completely shown, even when scrolled to the right.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
package application;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
try {
TreeItem<String> root = new TreeItem<>();
root.getChildren().add(new TreeItem<>("Short text."));
root.getChildren().add(new TreeItem<>("This is very, very, very long text."));
TreeView<String> treeView = new TreeView<>(root);
treeView.setShowRoot(false);
treeView.setMinWidth(150);
treeView.setPrefWidth(150);
treeView.setMaxWidth(150);
Scene scene = new Scene(treeView, 150, 150);
primaryStage.setScene(scene);
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
One can trick TreeCellSkin by the following hack that has to be applied on every TreeView and that initializes the maximum width of the disclosure node to 0 pixels. If there actually is a disclosure node to show, the existing layout code automatically increases this value.
static public void workaroundForJDK8090897(TreeView<?> treeView) {
try {
Field maxDisclosureWidthMapField = TreeCellSkin.class.getDeclaredField("maxDisclosureWidthMap"); //$NON-NLS-1$
maxDisclosureWidthMapField.setAccessible(true);
@SuppressWarnings("unchecked")
Map<TreeView<?>, Double> maxDisclosureWidthMap = (Map<TreeView<?>, Double>) maxDisclosureWidthMapField
.get(null);
maxDisclosureWidthMap.put(treeView, 0.0);
} catch (Exception e) {
// If TreeCellSkin has not the expected structure, we cannot know
// how anything works - so we silently give up.
}
}
- relates to
-
JDK-8090897 [TreeView] DisclosureNode set to null, still takes up space
-
- Open
-