带有 ChoiceBox 的 JavaFX 更新字体

JavaFX Update font with ChoiceBox

我有一个带有文本的 ScrollPane,我需要更新颜色和字体。颜色选择器工作正常。我的问题是 selecting 字体的 ChoiceBox。当我第一个 select 一个字体时它会改变,但是当我 select 另一个选项时,它不会更新字体。这是代码:

package helloearthrisemain;

import javafx.animation.Interpolator;
import javafx.animation.Timeline;
import javafx.animation.TranslateTransition;
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.geometry.VPos;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.ColorPicker;
import javafx.scene.control.ScrollPane;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
import javafx.scene.text.TextAlignment;
import javafx.stage.Stage;
import javafx.util.Duration;

public class HelloEarthRiseMain extends Application {

    @Override
    public void start(Stage stage) {

        String message
                = "Earthrise at Christmas: "
                + "[Forty] years ago this Christmas, a turbulent world "
                + "looked to the heavens for a unique view of our home "
                + "planet. This photo of Earthrise over the lunar horizon "
                + "was taken by the Apollo 8 crew in December 1968, showing "
                + "Earth for the first time as it appears from deep space. "
                + "Astronauts Frank Borman, Jim Lovell and William Anders "
                + "had become the first humans to leave Earth orbit, "
                + "entering lunar orbit on Christmas Eve. In a historic live "
                + "broadcast that night, the crew took turns reading from "
                + "the Book of Genesis, closing with a holiday wish from "
                + "Commander Borman: \"We close with good night, good luck, "
                + "a Merry Christmas, and God bless all of you -- all of "
                + "you on the good Earth.\"";

        //Color picker
        ColorPicker colorPicker = new ColorPicker();
        colorPicker.setValue(Color.CORAL);
        colorPicker.setLayoutX(400);
        colorPicker.setLayoutY(200);

        //List of fonts
        ObservableList fonts = FXCollections.observableArrayList(
        Font.getFamilies());

        //Select font
        ChoiceBox selectFont;
        selectFont = new ChoiceBox();
        selectFont.setValue("SansSerif");
        selectFont.setLayoutX(600);
        selectFont.setLayoutY(200);
        selectFont.setItems(fonts);

        // Reference to the Text
        Text textRef = new Text(message);
        textRef.setLayoutY(100);
        textRef.setTextOrigin(VPos.TOP);
        textRef.setTextAlignment(TextAlignment.JUSTIFY);
        textRef.setWrappingWidth(600);
        textRef.setFill(colorPicker.getValue());
        textRef.setFont(Font.font("SansSerif", FontWeight.BOLD, 24));

        //Action for selecting text color.
        colorPicker.setOnAction(new EventHandler() {
            public void handle(Event t) {
                textRef.setFill(colorPicker.getValue());               
            }
        });

selecting 字体的操作。我相信这就是问题所在。 第一个 selection 会改变,但当我再做一个时不会 select离子.

    selectFont.getSelectionModel().selectedIndexProperty()
            .addListener(new ChangeListener<Number>() {
              public void changed(ObservableValue ov, Number value, Number new_value) {
                textRef.setFont(Font.font(selectFont.getAccessibleText(), FontWeight.BOLD, 24));
              }
            });

//I tried this as well. This code did not work either.


/*
        selectFont.setOnAction(new EventHandler() {
            public void handle(Event u) {
                textRef.setFont(Font.font(selectFont.getAccessibleText(), FontWeight.BOLD, 24));
            }
        });
                */

        // Provides the animated scrolling behavior for the text
        TranslateTransition transTransition = new TranslateTransition(new Duration(75000), textRef);
        transTransition.setToY(-820);
        transTransition.setInterpolator(Interpolator.LINEAR);
        transTransition.setCycleCount(Timeline.INDEFINITE);

        // Create a ScrollPane containing the text
        ScrollPane scrollPane = new ScrollPane();
        scrollPane.setLayoutX(450);
        scrollPane.setLayoutY(400);
        scrollPane.setPrefWidth(600);
        scrollPane.setPrefHeight(400);
        scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
        scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
        scrollPane.setPannable(true);
        scrollPane.setContent(textRef);


        // Combine ImageView and Group
        Group root = new Group(scrollPane, colorPicker, selectFont);
        Scene scene = new Scene(root);

        stage.setScene(scene);
        stage.setTitle("Hello Earthrise");
        stage.setMaximized(true);
        stage.show();

        // Start the text animation
        transTransition.play();
    }

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

我试过你的代码,甚至第一个选择实际上不起作用,你有这种印象,因为如果你进入调试,你会注意到 selectFont.getAccessibleText() returns 为空。因此 Font.font(selectFont.getAccessibleText(), FontWeight.BOLD, 24) 将覆盖默认的 SansSerif,并且在下一次选择时该值仍然为空,您不会看到任何明显的变化。

我通过这样做让它工作:

    ObservableList<String> fonts = FXCollections.observableArrayList(Font.getFamilies());

    // Select font
    ChoiceBox<String> selectFont;
    selectFont = new ChoiceBox<>();
    selectFont.setValue("SansSerif");
    selectFont.setLayoutX(600);
    selectFont.setLayoutY(200);
    selectFont.setItems(fonts);
    selectFont.getSelectionModel().selectedItemProperty().addListener((obs, oldValue, newValue) -> textRef.setFont(Font.font(newValue, FontWeight.BOLD,24)));

希望对您有所帮助!