代码之家  ›  专栏  ›  技术社区  ›  Will Hartung

使用JavaFX进行字体选择和渲染

  •  0
  • Will Hartung  · 技术社区  · 3 年前

    我有一个Swing程序,它有这样一点点代码:

    font = new Font(Font.SANS_SERIF, Font.PLAIN, 8);
    

    它的渲染方式如下: enter image description here

    我选择这个是因为我想要简单的字体,我想要它“便携”。

    在JavaFX中,我有:

    font = Font.font("SansSerif", 8);
    

    我曾希望有一个类似的结果,但我得到了: enter image description here

    它看起来更大胆了。

    我已经尝试了所有的JavaFX选项,例如 font = Font.font("SansSerif", FontWeight.NORMAL, 8) .

    我试过不同的重量:轻,薄,等等。

    我直接试过Helvetica。我试过Ariel。它们看起来都一样。

    我写了一个简单的采样器,你可以选择字体名称,看看你得到了什么。很多字体都有不同的名称,但不会改变。

    我浏览了Helveticas:Helvetica,HelveticaBold,HelveTICaBold Oblique,Helvedica Light,Helvetiga Light Oblique。它们看起来都一样,没有一个是粗体,也没有一个斜体或浅色或其他什么。这些名字似乎没有任何区别。

    有些作品,Monospace的作品,Times的作品——因为它们不是SansSerif/Helvetica。

    现在,对于JavaFX,我只是在做:

    Text t = new Text(x, y, text);
    t.setFont(font);
    getChildren.add(t);
    

    我没有使用CSS做任何事情,不是有意识的。我没有CSS文件。

    所以,我不知道为什么我的字体选择不起作用。

    这是我的字体选择器实验的代码。

    很明显,我认为我在JavaFX中缺少了一些字体和文本的基本功能。

    public class App extends Application {
        @Override
        public void start(Stage stage) {
            FontControlPane pane = new FontControlPane();
            var scene = new Scene(pane, 640, 480);
            stage.setScene(scene);
            stage.show();
        }
    
        public static void main(String[] args) {
            launch();
        }
    }
    
    public class FontControlPane extends Pane {
        FontSizePane fsPane;
        ComboBox<String> comboBox;
    
        public FontControlPane() {
            fsPane = new FontSizePane();
            ObservableList<String> families = FXCollections.observableList(Font.getFontNames());
            comboBox = new ComboBox<>(families);
            comboBox.setOnAction(e -> fsPane.setFontName(comboBox.getValue()));
            populateMap();
        }
    
        private void populateMap() {
            ObservableList<Node> list = getChildren();
            list.clear();
            BorderPane pane = new BorderPane();
            pane.setTop(comboBox);
            pane.setCenter(fsPane);
            list.add(pane);
        }
    }
    
    public class FontSizePane extends Pane {
        String fontName;
    
        public FontSizePane() {
            this.fontName = fontName;
            populate();
        }
    
        public String getFontName() {
            return fontName;
        }
    
        public void setFontName(String fontName) {
            this.fontName = fontName;
            populate();
        }
    
        private void populate() {
            ObservableList<Node> list = getChildren();
            list.clear();
            setBackground(new Background(new BackgroundFill(Color.WHITE, CornerRadii.EMPTY, Insets.EMPTY)));
            if (fontName == null) {
                Text t = new Text(0, 20, "No font selected");
                list.add(t);
                return;
            }
    
            Set<Line> lines = new HashSet<>();
    
            Text t = new Text(0, 20, fontName);
            list.add(t);
            double y = 30;
            double x = 0;
            String text = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz 0123456789";
            for (int size = 4; size < 72; size += 4) {
                Font f = Font.font(fontName, size);
                t = new Text(x, y, text);
                t.setFont(f);
                list.add(t);
    
                y += (t.getLayoutBounds().getHeight() + 2);
            }
        }
    }
    
    1 回复  |  直到 3 年前
        1
  •  4
  •   VGR    3 年前

    JavaFX使用 CSS generic font families (在我的Linux系统上, serif , sans-serif monospace 工作,但是 cursive fantasy 不要。)

    据我所知,没有名为Ariel的字体。也许你是说Ari l?

    Helvetica只有在您的计算机上实际安装了该字体时才能工作。据我所知,默认情况下,Windows不附带Helvetica。

    使现代化

    这一行不正确:

    ObservableList<String> families = FXCollections.observableList(Font.getFontNames());
    

    getFontNames方法未返回有效的族。为此,请使用 Font.getFamilies() .