I'm making a windows-run-mobile-concept stock market game using Java, and it's JavaFX libraries, and I'd like to have the form of currency on the lower right of the player's current balance, (in my case USD). The catch with this is, is that whenever the player gains a multiple of a thousand dollars in-game, the player's balance gets larger, which means that the string that holds the player's balance is also larger. This causes the fixed position of the string "USD" in the application to be overlapped by the player's current balance.
I've tried simply forcing the program to move the "USD" symbol whenever the number increases by a multiple of one thousand. This, however, seems highly inefficient and I'm willing to bet that there is a simpler way to do this.
double balance = 12313.00;
DecimalFormat decimalFormat = new DecimalFormat("#,###");
String numberAsString = decimalFormat.format(balance);
Text balanceText = new Text("$" + (numberAsString));
balanceText.setFont(Font.font("Modernist", 72));
balanceText.setFill(Color.web("77e6b3"));
balanceText.setLayoutX(25);
balanceText.setLayoutY(250);
Text currencyText = new Text("USD");
currencyText.setFont(Font.font("Modernist", 36));
currencyText.setFill(Color.web("77e6b3"));
currencyText.setLayoutX(275);
currencyText.setLayoutY(250);
You can use a TextFlow to render rich text in multiple fonts, sizes, styles and colors:
Sample Code
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.VPos;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.*;
import javafx.scene.text.TextFlow;
import javafx.stage.Stage;
import java.text.DecimalFormat;
public class MoMoney extends Application {
@Override
public void start(Stage stage) throws Exception {
double balance = 12313.00;
DecimalFormat decimalFormat = new DecimalFormat("#,###");
String numberAsString = decimalFormat.format(balance);
Text balanceText = new Text("$" + (numberAsString));
balanceText.setFont(Font.font("Modernist", 72));
balanceText.setFill(Color.web("77e6b3"));
Text currencyText = new Text("USD");
currencyText.setTextOrigin(VPos.TOP);
currencyText.setFont(Font.font("Modernist", 36));
currencyText.setFill(Color.web("77e6b3"));
TextFlow flow = new TextFlow(balanceText, currencyText);
flow.setMinSize(TextFlow.USE_PREF_SIZE, TextFlow.USE_PREF_SIZE);
VBox layout = new VBox(flow);
layout.setPadding(new Insets(10));
stage.setScene(new Scene(layout));
stage.getScene().setFill(Color.rgb(35, 39, 50));
stage.show();
}
public static void main(String[] args) {
launch();
}
}
JavaDoc Description
Description of TextFlow from the JavaDoc linked above:
TextFlow is special layout designed to lay out rich text. It can be used to layout several Text nodes in a single text flow. The TextFlow uses the text and the font of each Text node inside of it plus it own width and text alignment to determine the location for each child.
Implementation Comments
By default, TextFlow will wrap text to new lines if there is not enough space to render all text, so I set the minimum size of the TextFlow to its preferred size to prevent that.
TextFlow can align the text with standard width based alignment settings such as left align, right align, justify etc. However, TextFlow doesn't have any way to vertically align text, for example to generate a superscript value. There are also other limitations such as making the text selectable for copy and paste or editing text. So look at it, and try it to see if it fits your purpose, if not then consider some of the other alternative mechanisms mentioned below.
Alternative Approaches
Other valid ways to do this are: