Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to calculate the pixel width of a String in JavaFX?

It appears that there is no API call to calculate the width (in pixels) of a text string in Java FX 2.2. There have been suggestions of workarounds on other forums, but my efforts to create or find any code that returns the width of a String, either using the default font or otherwise, have failed. Any help would be appreciated.

like image 309
Don Wills Avatar asked Oct 22 '12 16:10

Don Wills


People also ask

How do you find the width of a string?

var ww = string_width(str_Name + " "); draw_text(32, 32, str_Name)); draw_text(32 + ww, 32, "has won the game!"); The above code will get the width of the given string and then draw two lines of text, using the returned string width as a separator.

Which function is used to return the width of a string in pixels?

textwidth() function in C h contains textwidth () function which returns the width of input string in pixels.

What is computed size Javafx?

For example, the computed size of a Button object is determined by the length of the text and the size of the font used for the label, plus the size of any image. Typically, the computed size is just big enough for the control and the label to be fully visible.

How do you change the size of text in Javafx?

You can change the font size and color of the text using the setFont() method. This method accepts an object of the Font class. The class named Font of the package javafx.


1 Answers

If you are just measuring the default font without CSS:

  1. Place the String to be measured in a Text object.
  2. Get the width of the Text object's layout bounds.

If you need to apply CSS:

  1. Place the String to be measured in a Text object.
  2. Create a throwaway Scene and place the Text object in the Scene.
  3. Take a snapshot of the Text (if you are using Java 7) or call applyCss for Java 8.
  4. Get the width of the Text object's layout bounds.

This works because it forces a layout pass on the Text which calculates it's layout bounds. The scene in step 2 is required because that is just the way the CSS processor works (it needs a node to be located in a Scene to be able to do its job). Definitely read the linked javadoc for applyCss if you want to understand the processing further.

Sample Code

import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.control.*; import javafx.scene.text.Text; import javafx.stage.Stage;  // displays the width in pixels of an arbitrary piece of text. public class MeasureText extends Application {   public static void main(String[] args) { launch(args); }   @Override public void start(Stage stage) throws Exception {     final Text text = new Text("XYZZY");     new Scene(new Group(text));      // java 7 =>      //    text.snapshot(null, null);     // java 8 =>     text.applyCss();       final double width = text.getLayoutBounds().getWidth();      stage.setScene(new Scene(new Label(Double.toString(width))));     stage.show();   } } 

Sample program output (displays the width in pixels of an arbitrary piece of text):

Sample Program Output

How (if at all) would this change if the text was printed to a graphicscontext with a set font?

Apply the font to a text object containing the same message you will plot to the canvas. Unlike when you are measuring text plotted to the scene graph, items plotted to a canvas do not have CSS applied to them, so you don't need to place the Text object in a scene and have CSS applied to it before measuring the text. You can measure the layout bounds of your text object and it will be the same as the bounds of the text plotted within the canvas with the same font.

import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.canvas.*; import javafx.scene.control.Label; import javafx.scene.layout.VBox; import javafx.scene.text.*; import javafx.stage.Stage;  // displays the width in pixels of an arbitrary piece of text (which has been plotted on a canvas). public class MeasureText extends Application {     @Override     public void start(Stage stage) throws Exception {         final String msg = "XYZZY";         final Text text = new Text(msg);         Font font = Font.font("Arial", 20);         text.setFont(font);          final double width = text.getLayoutBounds().getWidth();          Canvas canvas = new Canvas(200, 50);         GraphicsContext gc = canvas.getGraphicsContext2D();         gc.setFont(font);         gc.fillText(msg, 0, 40);          stage.setScene(new Scene(                 new VBox(new Label(Double.toString(width)), canvas))         );         stage.show();     }      public static void main(String[] args) {         launch(args);     } } 
like image 184
jewelsea Avatar answered Sep 18 '22 14:09

jewelsea