Javafx Text multi-word colorization

前端 未结 1 1941
礼貌的吻别
礼貌的吻别 2020-12-09 23:28

Ok, I have a ListView object. I\'m using this as a sort of console window for my server. It was really the only way I could think of to display colorized text in a box like

相关标签:
1条回答
  • 2020-12-10 00:11

    Create a custom cellfactory for your ListView and have it generate cells containing a FlowPane with different Text instances, each with different styles. I created a sample to demonstrate this method.

    Sample output:

    colorized text

    In Java 8 you can you can use the TextFlow to style your text rather than a combination of different Text instances in a FlowPane.

    Sample code

    fruits.css

    /** 
     * fruits.css - place in same source directory as FruitsDisplay.java and 
     * ensure the build system copies the file over to the output path
     */
    .root {
      -fx-font-size: 20px;
      -fx-font-family: "Comic Sans MS";
    }
    
    .list-cell {
      -fx-background-color: azure;
    }
    
    .fruit {
      -fx-font-weight: bold;
      -fx-font-style: italic;
    }
    
    .apple {
      -fx-fill: forestgreen;
    }
    
    .orange {
      -fx-fill: orange;
    }
    
    .pear {
      -fx-fill: gold;
    }
    

    FruitsDisplay.java

    import javafx.application.Application;
    import javafx.collections.FXCollections;
    import javafx.scene.*;
    import javafx.scene.control.*;
    import javafx.scene.image.*;
    import javafx.scene.layout.*;
    import javafx.scene.text.Text;
    import javafx.stage.Stage;
    
    import java.util.*;
    
    /**
     * Sample of using a FlowPane to create styled text in JavaFX
     */
    public class FruitsDisplay extends Application {
        private static final String[] fruits = {"apple", "orange", "pear"};
        private static final String[] fruitImageLocs = {
                "http://weknowyourdreamz.com/images/apple/apple-02.jpg",
                "http://pic.1fotonin.com/data/wallpapers/165/WDF_2048871.png",
                "http://vignette1.wikia.nocookie.net/pikmin/images/c/cc/Pear-01.jpg"
        };
        private Map<String, Image> fruitImages = new HashMap<>();
    
        public static void main(String[] args) {
            Application.launch(FruitsDisplay.class);
        }
    
        @Override
        public void start(Stage stage) throws Exception {
            stage.setTitle("Fruit Tales");
    
            for (int i = 0; i < fruits.length; i++) {
                Image image = new Image(fruitImageLocs[i], 0, 30, true, true);
                fruitImages.put(fruits[i], image);
            }
    
            ListView<String> list = new ListView<>(FXCollections.observableArrayList(fruits));
            list.setCellFactory(listView -> new FruitFlowCell());
            list.setPrefSize(440, 180);
    
            Scene scene = new Scene(list);
            scene.getStylesheets().add(getResource("fruits.css"));
            stage.setScene(scene);
            stage.show();
        }
    
        private String getResource(String resourceName) {
            return getClass().getResource(resourceName).toExternalForm();
        }
    
        private class FruitFlowCell extends ListCell<String> {
            static final String FRUIT_PLACEHOLDER = "%f";
    
            {
                setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
            }
    
            @Override
            protected void updateItem(String s, boolean empty) {
                super.updateItem(s, empty);
                if (s != null && !"".equals(s) && !isEmpty()) {
                    setGraphic(createFruitFlow(s));
                } else {
                    setGraphic(null);
                }
            }
    
            private Node createFruitFlow(String s) {
                switch (s) {
                    case "apple":
                        return createTextFlow("Eat an ", FRUIT_PLACEHOLDER, s, " a day.");
                    case "orange":
                        return createTextFlow("An ", FRUIT_PLACEHOLDER, s, " has many vitamins.");
                    case "pear":
                        return createTextFlow("A ", FRUIT_PLACEHOLDER, s, " has a funny shape.");
                    default:
                        return null;
                }
            }
    
            private Node createTextFlow(String... msg) {
                FlowPane flow = new FlowPane();
                boolean isFruit = false;
    
                for (String s : msg) {
                    if (FRUIT_PLACEHOLDER.equals(s)) {
                        isFruit = true;
                        continue;
                    }
    
                    Text text = new Text(s);
                    if (isFruit) {
                        flow.getChildren().addAll(
                                new ImageView(fruitImages.get(s)),
                                createSpacer(5)
                        );
                        text.getStyleClass().addAll(
                                "fruit",
                                s
                        );
                        isFruit = false;
                    } else {
                        text.getStyleClass().add("plain");
                    }
    
                    flow.getChildren().add(text);
                }
    
                return flow;
            }
    
            private Node createSpacer(int width) {
                HBox spacer = new HBox();
                spacer.setMinWidth(HBox.USE_PREF_SIZE);
                spacer.setPrefWidth(width);
                spacer.setMaxWidth(HBox.USE_PREF_SIZE);
    
                return spacer;
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题