【问题标题】:Javafx Text multi-word colorizationJavafx 文本多字着色
【发布时间】:2013-02-26 05:18:55
【问题描述】:

好的,我有一个 ListView 对象。我将其用作服务器的一种控制台窗口。这确实是我能想到的在这样的框中显示彩色文本的唯一方法。到目前为止,这很有效。现在我想做的是在一个索引或行上为不同的文本着色。

例子:

listView[0] = "Hello " + "world";

Hello”为绿色,“world”为蓝色。如果这可以使用 javafx Text 或任何其他方式完成,我想知道如何去做。我使用 Javafx Text 作为罪魁祸首,因为您可以使用它进行很多自定义。

我希望每个人都能理解我在这里想要做什么,如果没有,请告诉我,我会尝试改写一下。

解决方案

多亏了jewelsea,我才找到了解决方案。我采用了一些不同的方法,而不是使用细胞工厂。

列表视图

ListView<FlowPane> consoleWindow = new ListView<>();
ArrayList<FlowPane> consoleBuffer = FXCollections.observableArrayList();

consoleWindow.setItems(consoleBuffer);

inputBox.setOnKeyPressed(new EventHandler<KeyEvent>() {
        @Override
        public void handle(KeyEvent keyEvent) {
           if (keyEvent.getCode() == KeyCode.ENTER) {
                consoleBuffer.add(parseInput.parseInputToArray(inputBox.getText()));
           }
            consoleWindow.scrollTo(consoleBuffer.size());
        }
});

ConsoleInputParse

public class ConsoleInputParse {

    private String[] wordList = {};

    public ConsoleInputParse() {}

    public FlowPane parseInputToArray(String input) {
        wordList = input.trim().split("[ ]+");

        return colorize();
    }

    public FlowPane colorize() {

        ArrayList<Text> textChunks = new ArrayList<>();
        FlowPane bundle = new FlowPane();

        //Todo: use regex to check for valid words
        for (String word : wordList) {
            String spaced = word + " ";
            switch (word) {
                case "Hello": case "hello":
                    textChunks.add(customize(spaced, "purple"));
                    break;
                case "World": case "world":
                    textChunks.add(customize(spaced, "blue"));
                    break;
                case "Stack Overflow":
                    textChunks.add(customize(spaced, "orange", "Arial Bold", 15));
                default:
                    textChunks.add(customize(spaced, "black", "Arial",  13));
                    break;
            }
        }

        bundle.getChildren().addAll(textChunks);
        return bundle;
    }

    public Text customize(String word, String color) {
        return TextBuilder.create().text(word).fill(Paint.valueOf(color)).build();
    }

    public Text customize(String word, String color, String font) {
        return TextBuilder.create()
                .text(word)
                .fill(Paint.valueOf(color))
                .font(Font.font(font, 12)).build();
    }

    public Text customize(String word, String color, String font, int fontSize) {
        return TextBuilder.create()
                .text(word)
                .fill(Paint.valueOf(color))
                .font(Font.font(font, fontSize)).build();
    }

}

“工作示例”

【问题讨论】:

    标签: java colors javafx


    【解决方案1】:

    为您的ListView 创建一个自定义cellfactory,并让它生成包含FlowPane 的单元格,其中包含不同的Text 实例,每个实例都有不同的样式。我创建了一个sample 来演示这个方法。

    样本输出:

    Java 8 中,您可以使用TextFlow 来设置文本样式,而不是在FlowPane 中组合不同的Text 实例。

    示例代码

    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;
            }
        }
    }
    

    【讨论】:

    • 你有什么资源可以分享,关于 cellfactory 的工作方式,或者客户如何构建类似的东西。 javafx 的那部分总是让我感到困惑。
    • Tom Schindl implemented something 使用 ListView 和 Java 8 TextFlow,但这可能对你想要的东西来说太过分了。我会看看我能不能把一个基本的例子放在一起。
    • 基于 ListView + FlowPane + 多个 Text 节点的组合添加了指向 sample solution 的链接。
    • 正在用我找到的解决方案编辑我的问题,我猜是:P.. 我现在正在查看,非常感谢!
    • 使用细胞工厂有什么好处吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-12
    • 1970-01-01
    • 1970-01-01
    • 2016-05-05
    • 2015-11-14
    • 2018-10-12
    • 2019-12-20
    相关资源
    最近更新 更多