This discussion is archived
6 Replies Latest reply: Mar 14, 2012 12:33 PM by 921851 RSS

Using custom fonts on MenuBar Menu and/or MenuItem

921851 Newbie
Currently Being Moderated
Hi all!

I was wondering if there's a way to set a custom font to a Menu and it's children. I can actually do this on the Text object like:
...

import javafx.scene.text.Font;
import javafx.scene.text.Text;

...

@FXML private Text lblAppName, lblLoginFailed;

...

Font myFont = Font.loadFont(getClass().getResourceAsStream("/fonts/TRON.TTF"), 40);
     
if(myFont != null)
 lblAppName.setFont(myFont);
But can't do it on the javafx.scene.control.Menu and javafx.scene.control.MenuItem objects.

I even tried the register font approach, even knowing that javafx.scene.text.Font and java.awt.Font are two different objects and got no success at all. As follows
try 
{
     GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
     ge.registerFont(Font.createFont(Font.TRUETYPE_FONT, getClass().getResourceAsStream("/fonts/Baumans-Regular.ttf")));
} 
catch (Exception e) 
{
     e.printStackTrace();
}
and then tried to use it from my css file:
.menu-bar
{
     -fx-background-color: transparent;
     -fx-font-family: Baumans;
     -fx-font-size: 14px;
     -fx-text-fill: #00CCFF;
}
But guess what? It didn't (obviously) work. Since Menu and MenuItem don't have a setFont() method I guess I'm stuck with this. Thanks in advance
  • 1. Re: Using custom fonts on MenuBar Menu and/or MenuItem
    jsmith Guru
    Currently Being Moderated
    Although I've used custom fonts for JavaFX 1.3, I've never been able to get them to work for JavaFX 2.x.

    Example 9 here talks about how to use custom fonts with JavaFX 2.x, but the example does not work for me (JavaFX 2.1-b16, WinXPsp3, JDK7u4ea) (http://docs.oracle.com/javafx/2.0/text/jfxpub-text.htm). Perhaps I am doing something wrong, but not really sure what it is. Also I don't know how to use custom fonts in conjunction with css. So if anybody can get either of these things working, it might be useful to post how it was done.

    Here is a sample code which demonstrates changing the font for the menu and the menuitem to a monospaced (e.g. Courier) font.
    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.control.*;
    import javafx.scene.layout.VBox;
    import javafx.scene.paint.Color;
    import javafx.scene.text.Font;
    import javafx.stage.Stage;
    
    public class MenuFont extends Application {
      public static void main(String[] args) { launch(args); }
      @Override public void start(Stage stage) {
        final Menu fileMenu = new Menu("File"); fileMenu.getItems().add(new MenuItem("Open"));
        MenuBar menuBar = new MenuBar(); menuBar.getMenus().add(fileMenu);
        
        Font font = Font.loadFont(MenuFont.class.getResource("TRON.TTF").toExternalForm(), 120);
        Label label = new Label("TRON");
    //    label.setFont(font);  // if this line is not commented out and the font is set, then no label is actually displayed...
        
        VBox layout = new VBox(10); layout.getChildren().addAll(menuBar, label);    
        Scene scene = new Scene(layout, 200, 200, Color.ANTIQUEWHITE);
        stage.setScene(scene);
        stage.show();
    
        scene.getStylesheets().add(MenuFont.class.getResource("menufont.css").toExternalForm());
      }
    }
    CSS used here:
    .menu-bar .label {
      -fx-font-family: monospace;  
      -fx-font-size: 20;
      -fx-text-fill: red;
    }
     
    .menu-item .label {
      -fx-font-family: monospace;  
      -fx-font-size: 20;
      -fx-text-fill: green;
    }
    TRON font used is this one: http://www.dafont.com/tron.font
  • 2. Re: Using custom fonts on MenuBar Menu and/or MenuItem
    921851 Newbie
    Currently Being Moderated
    Yours is a easy one. Use Text instead of Label.

    Check this forum entry:

    Font.loadFont doesn't work

    Edited by: 918848 on 13/03/2012 14:05
  • 3. Re: Using custom fonts on MenuBar Menu and/or MenuItem
    jsmith Guru
    Currently Being Moderated
    Yours is a easy one. Use Text instead of Label.
    Thanks for the info - this was almost correct.

    Setting the font on the label actually worked, but what happened was that the the custom font I created set the font size to 120, which is huge for the TRON font. This meant that the Scene was sized too small to display the Label and the label implementation converted the text to just ellipses . . ., but even the ellipses could not be seen because they were too large to be displayed on the small Scene I created. If I made the Scene larger, it displayed just fine. It seems that if you just remove the sizing on the Scene it does not work either as the font stuff does not compute the correct layout area for the custom font label and the Scene ends up too small, so you need to manually set it to the right size.

    Also, as the forum post you linked hints, if you do set any styling in your program for the label which has the custom font displayed (e.g. try to change the font size via label.setStyle("-fx-font-size: 10;"), the font just reverts back to a standard font - so I guess you want to avoid that for now. What I did instead to get multiple size fonts is just make multiple calls to Font.loadFont(fontName, size).

    Once I worked out how to get a custom font displayed in a label, this meant that I could perform css lookups on the scene at run-time to set the custom font for the menu items.

    An example which demonstrates this is here:
    https://gist.github.com/2032230
    The runtime lookups rely on a deprecated impl_ call to find the popped up menu items, Stage.impl_getWindows().
    A css based lookup or setting the custom font from a css stylesheet would be better, but I don't know how to accomplish either.

    Anyway, hope the above gives you enough information to accomplish what you want.
  • 4. Re: Using custom fonts on MenuBar Menu and/or MenuItem
    921851 Newbie
    Currently Being Moderated
    Man, you won't believe me. But I finally made it and it's pretty simple!

    In my Application, before call any other window, I make a call to load the font:
       javafx.scene.text.Font baumansFont = javafx.scene.text.Font.loadFont(getClass().getResourceAsStream("/fonts/Baumans-Regular.ttf"), 10);
    and then, at the css file:
    .menu-bar
    {
         -fx-background-color: transparent;
         -fx-font-family: Baumans;
         -fx-font-size: 14px;
         -fx-text-fill: #00CCFF;
    }
    .context-menu
    {
         -fx-font-family: Baumans;
         -fx-background-color: transparent;
         -fx-font-size: 12px;
         -fx-text-fill: white;
    }
    And that's it! By the way, the approach you've shown works too, but I found too much processor intensive (n² complexity) just to use a custom font in a menu. Thanks for all the help. By the way, I won't mark this thread as answered untill you say it works for you too.
  • 5. Re: Using custom fonts on MenuBar Menu and/or MenuItem
    jsmith Guru
    Currently Being Moderated
    Very cool. That loaded the custom font and styled it using css :-)

    I placed the loadFont call inside an overridden Application init method to make sure it was invoked before anything much happened in the application.
    Font.loadFont(CustomFontTest.class.getResource("TRON.TTF").toExternalForm(), 10);
    When I used the styles you provided the colors of the fonts in the menus did not come out right, they just remained their default colors and not the -fx-text-fill color.
    To get the right colors I had to use slightly modified css which explicitly set the -fx-text-fill on the label styleclass.
    .menu-bar {
         -fx-background-color: transparent;
         -fx-font-family: TRON;
         -fx-font-size: 40px;
    }
    .menu-bar .label {
            -fx-text-fill: #00CCFF;
    }
    
    .context-menu {
         -fx-font-family: TRON;
         -fx-background-color: transparent;
         -fx-font-size: 12px;
    }
    .menu-item .label {
         -fx-text-fill: red;
    }
    Nice that the CSS sized the fonts fine.
    Even when the font was loaded at size 10, the font was resized correctly to what was specified in the CSS fx-font-size specifications.

    Inline styling of a label via css using a Font loaded during application initialization also worked fine:
    Label testControl = new Label("TRON");
    testControl.setStyle("-fx-font-family: TRON; -fx-font-size: 120;");
  • 6. Re: Using custom fonts on MenuBar Menu and/or MenuItem
    921851 Newbie
    Currently Being Moderated
    Yes! Seems that using
    Font.loadFont()
    Registers the Custom Font and then we can set it using a css file. Also:

    "Place the loadFont call inside an overridden Application init method"

    Ensures we can access it from css. Marking this as Answered. Thank you JSmith for all the support!

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points