树形视图,TreeItem / TreeCell上的JavaFX自动换行

时间:2016-09-26 21:25:18

标签: java css javafx treeview word-wrap

我希望有一个可折叠的列表,所以我使用TreeView,但更长的字符串给出水平滚动条而不是自动换行。我尝试在-fx-wrap-text课程中使用CSS属性.tree-cell,但遗憾的是似乎没有发生任何事情。

TreeCell是不是要跨越多行?如果是这样的话会有什么替代方案?

这是现在的样子:

enter image description here

test.css

.tree-cell {
        -fx-wrap-text: true;
        -fx-text-fill: blue;
    }

subjects.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import java.net.URL?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.TreeView?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="javafxapplication1.FXMLDocumentController">
    <Button fx:id="button" layoutX="182.0" layoutY="14.0" onAction="#handleButtonAction" text="Click Me!" />
    <TextField fx:id="filterSubject" layoutX="21.0" layoutY="14.0" />
    <TreeView fx:id="subjectList" editable="true" layoutX="14.0" layoutY="61.0" prefHeight="200.0" prefWidth="365.0" />
    <stylesheets>
            <URL value="@test.css" />
    </stylesheets>  
</AnchorPane>

subjects.txt - 只是第一个是主题的文本对,第二个是描述。

1
Somewhat long string that I want to wordwrap.
2
Somewhat long string that I want to wordwrap.
3
Somewhat long string that I want to wordwrap.

FXMLDocumentController.java

package javafxapplication1;

import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.control.TreeView;
import javafx.scene.control.TreeItem;
import java.io.*;

public class FXMLDocumentController implements Initializable {


    @FXML
    private TreeView<String> subjectList;

    @FXML
    private void handleButtonAction(ActionEvent event) {
        System.out.println("You clicked me!");
    }

    private void getSubjects(){
        TreeItem<String> subjectRoot = new TreeItem<String> ("Subject");
        subjectRoot.setExpanded(true);
        try {
            BufferedReader fileReader = new BufferedReader(
                    new FileReader("subjects.txt")
            );
            String subject = null;
            String description = null;
            while((subject = fileReader.readLine()) != null) {
                description = fileReader.readLine();
                TreeItem<String> subjectTree = new TreeItem<String> (subject);
                TreeItem<String> descriptionItem = new TreeItem<String> (description);
                subjectTree.getChildren().add(descriptionItem);
                subjectRoot.getChildren().add(subjectTree);

            }  
        } catch(FileNotFoundException e) {
            System.out.println("File not found");
        } catch(IOException e) {
            e.printStackTrace();
        }
        subjectList.setRoot(subjectRoot);
    }
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        getSubjects();
    }      
}

JavaFXApplication1.Java

package javafxapplication1;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;


public class JavaFXApplication1 extends Application {

    @Override
    public void start(Stage stage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));

        Scene scene = new Scene(root);

        stage.setScene(scene);
        stage.show();
    }


    public static void main(String[] args) {
        launch(args);
    }

}

2 个答案:

答案 0 :(得分:1)

实际上CSS类正如您所期望的那样工作。

问题是:TreeView包含TreeCell。这些TreeCell将包装其文本,以防它们没有足够的垂直空间来垂直增长。由于TreeView内置了“ScrollPane”,其中视口将垂直增长,因此它将为TreeCell实例提供足够的空间以便在任何情况下增长,因此包装将永远不会被启用。

为避免这种情况,您可以设置cell factory以手动生成TreeCell个实例。然后,您可以将prefWidthProperty这些元素绑定到TreeView的{​​{3}}。

示例

public class WrappedTreeView extends Application {

    @Override
    public void start(Stage stage) {
        final Scene scene = new Scene(new Group(), 200, 400);
        Group sceneRoot = (Group) scene.getRoot();

        scene.getStylesheets().add(getClass().getResource("application.css").toString());

        TreeItem<String> root = new TreeItem<>("Root");
        root.setExpanded(true);

        TreeItem<String> childNode1 = new TreeItem<>("I am a very long node - the first one -, my text must be wrapped! If it is not wrapped, it's a problem!");
        TreeItem<String> childNode2 = new TreeItem<>("I am a very long node - the second one -, my text must be wrapped! If it is not wrapped, it's a problem!");
        TreeItem<String> childNode3 = new TreeItem<>("I am a very long node - the third one -, my text must be wrapped! If it is not wrapped, it's a problem!");

        root.getChildren().addAll(childNode1, childNode2, childNode3);
        childNode2.getChildren().add(new TreeItem<>("And I am a very long embedded node, so my text must be wrapped!"));

        TreeView<String> treeView = new TreeView<>(root);
        treeView.setCellFactory(item -> {
            TreeCell<String> treeCell = new TreeCell<String>() {
                @Override
                protected void updateItem(String item, boolean empty) {
                    super.updateItem(item, empty);
                    if (item != null && !empty)
                        setText(item);
                    else
                        setText("");
                }
            };

            treeCell.prefWidthProperty().bind(treeView.widthProperty().subtract(5.0));
            return treeCell;
        });

        treeView.setMaxWidth(200);

        sceneRoot.getChildren().add(treeView);
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        Application.launch(args);
    }
}

application.css的内容

.tree-cell { 
    -fx-wrap-text: true;
    -fx-text-fill: blue;
}

以及生成的TreeView

widthProperty

答案 1 :(得分:0)

您可以通过在树状单元cellfactory中设置树状单元格的prefWidth值(以及树状单元的wraptext值为true)来执行此操作,然后使用scrollPane停止单元格水平扩展。