Comment désactiver ou modifier le remplissage de TreeCell dans TreeView

Environnement: JDK 7u75, Windows 8.1 x64, JavaFX2.2

Exemple de code:

public class TreeViewSample extends Application { public static void main(Ssortingng[] args) { launch(args); } @Override public void start(Stage primaryStage) throws MalformedURLException { primaryStage.setTitle("Tree View Sample"); TreeItem rootItem = new TreeItem("RootNode"); for (int i = 1; i < 5; i++) { TreeItem item = new TreeItem("SubNode" + i); rootItem.getChildren().add(item); item.getChildren().add(new TreeItem("SubSubNode" + i + "" + i)); } rootItem.getChildren().add(new TreeItem("SecondRootNode")); TreeView tree = new TreeView(rootItem); StackPane root = new StackPane(); root.getChildren().add(tree); Scene scene = new Scene(root, 300, 250); scene.getStylesheets().add((new File("../css/styletest.css").toURI()).toURL().toSsortingng()); primaryStage.setScene(scene); primaryStage.show(); } } 

CSS:

 .tree-cell { -fx-skin: "com.sun.javafx.scene.control.skin.TreeCellSkin"; -fx-background-color: -fx-control-inner-background; -fx-padding: 0.25em; /* 3 */ -fx-text-fill: -fx-text-inner-color; -fx-indent: 10; } .tree-cell .label { -fx-padding: 0.0em 0.0em 0.0em 0.25em; /* 0 0 0 3 */ } .tree-cell .tree-disclosure-node { -fx-padding: 4 2 4 8; -fx-background-color: transparent; } .tree-cell .tree-disclosure-node .arrow { -fx-background-color: -fx-mark-color; -fx-padding: 0.333333em; /* 4 */ -fx-shape: "M 0 -4 L 8 0 L 0 4 z"; } 

était

Nous devons supprimer tout l’espace et les flèches pour tous les nœuds. CSS modifié:

 .tree-cell { -fx-skin: "com.sun.javafx.scene.control.skin.TreeCellSkin"; -fx-background-color: -fx-control-inner-background; -fx-padding: 0px; -fx-text-fill: -fx-text-inner-color; -fx-indent: 0px; } .tree-cell .label { -fx-padding: 0.0em 0.0em 0.0em 0.0em; } .tree-cell .tree-disclosure-node { -fx-padding: 0px; -fx-background-color: transparent; } .tree-cell .tree-disclosure-node .arrow { -fx-background-color: -fx-mark-color; -fx-padding: 0.0em; } 

entrez la description de l'image ici

Comme vous le voyez, il n’y a pas de remplissage et d’indentation pour tous les nœuds sauf les feuilles.

Et la question – Comment supprimer \ modifier ce padding?

Dans ce cas, les développeurs JavaFX ont défini la longueur standard de 18 et n’ont pas fourni l’occasion de la modifier. Voici leur commentaire:

  /* * This is rather hacky - but it is a quick workaround to resolve the * issue that we don't know maximum width of a disclosure node for a given * TreeView. If we don't know the maximum width, we have no way to ensure * consistent indentation for a given TreeView. * * To work around this, we create a single WeakHashMap to store a max * disclosureNode width per TreeView. We use WeakHashMap to help prevent * any memory leaks. * * RT-19656 identifies a related issue, which is that we may not provide * indentation to any TreeItems because we have not yet encountered a cell * which has a disclosureNode. Once we scroll and encounter one, indentation * happens in a displeasing way. */ 

Mais si c’est vraiment nécessaire, nous substituons la classe TreeCellSkin et la méthode layoutChildren à l’aide de la reflection. Mais ce n’est pas sûr:

  final double defaultDisclosureWidth = maxDisclosureWidthMap.containsKey(tree) ? maxDisclosureWidthMap.get(tree) : 18; // RT-19656: default width of default disclosure node 

sur

  final double defaultDisclosureWidth = 0; 

Classe complète:

 public class CustomTreeCellSkin extends TreeCellSkin { public CustomTreeCellSkin(TreeCell control) { super(control); } private boolean disclosureNodeDirty = true; @Override protected void layoutChildren(double x, double y, double w, double h) { try { TreeView tree = getSkinnable().getTreeView(); if (tree == null) return; if (disclosureNodeDirty) { Method method =TreeCellSkin.class.getDeclaredMethod("updateDisclosureNode"); method.setAccessible(true); method.invoke(this); disclosureNodeDirty=false; } Node disclosureNode = getSkinnable().getDisclosureNode(); TreeItem treeItem = getSkinnable().getTreeItem(); int level = tree.getTreeItemLevel(treeItem); if (!tree.isShowRoot()) level--; double leftMargin = getIndent() * level; x += leftMargin; // position the disclosure node so that it is at the proper indent boolean disclosureVisible = disclosureNode != null && treeItem != null && !treeItem.isLeaf(); Field field = TreeCellSkin.class.getDeclaredField("maxDisclosureWidthMap"); field.setAccessible(true); Map, Double> maxDisclosureWidthMap = (Map, Double>) field.get(this); final double defaultDisclosureWidth = 0; // RT-19656: default width of default disclosure node double disclosureWidth = defaultDisclosureWidth; if (disclosureVisible) { if (disclosureNode == null || disclosureNode.getScene() == null) { updateChildren(); } if (disclosureNode != null) { disclosureWidth = disclosureNode.prefWidth(h); if (disclosureWidth > defaultDisclosureWidth) { maxDisclosureWidthMap.put(tree, disclosureWidth); } double ph = disclosureNode.prefHeight(disclosureWidth); disclosureNode.resize(disclosureWidth, ph); positionInArea(disclosureNode, x, y, disclosureWidth, ph, /*baseline ignored*/0, HPos.CENTER, VPos.CENTER); } } // determine starting point of the graphic or cell node, and the // remaining width available to them final int padding = treeItem != null && treeItem.getGraphic() == null ? 0 : 3; x += disclosureWidth + padding; w -= (leftMargin + disclosureWidth + padding); // Rather ugly fix for RT-38519, where graphics are disappearing in // certain circumstances Node graphic = getSkinnable().getGraphic(); if (graphic != null && !getChildren().contains(graphic)) { getChildren().add(graphic); } } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } layoutLabelInArea(x, y, w, h); } } 

Dans css dans ce cas, vous devez spécifier notre classe remplacée:

 .tree-cell { -fx-skin: "CustomTreeCellSkin"; -fx-background-color: -fx-control-inner-background; -fx-padding: 0px; -fx-text-fill: -fx-text-inner-color; -fx-indent: 0px; } .tree-cell .label { -fx-padding: 0.0em 0.0em 0.0em 0.0em; } .tree-cell .tree-disclosure-node { -fx-padding: 0px; -fx-background-color: transparent; } .tree-cell .tree-disclosure-node .arrow { -fx-background-color: -fx-mark-color; -fx-padding: 0.0em; } 

Désolé pour mon anglais. =)