How to display white text with a black background? - java

I am trying to figure out why my text isn't being displayed here. I assume it isn't being colored white, and simply doesn't show up against the black background. So, I'm trying to figure out why the background is being colored black, but the text isn't being shown.
I am using JavaFX 12.
How can I color the letters white?
public class MCVE extends Application {
private static Stage gameStage = new Stage();
#Override
public void start(Stage primaryStage) {
gameStage.setScene(new Scene(createScreen(), 1280.0, 800.0));
// adjust window settings.
gameStage.setTitle("my game");
gameStage.setResizable(false);
gameStage.show();
}
private Pane createScreen() {
Text welcome = new Text("Welcome,");
welcome.setFont(new Font("Old_Style", 22.0));
welcome.setStyle("-fx-text-fill: whitesmoke");
Text toMyGame = new Text(" to my game.");
toMyGame.setFont(new Font("System", 14.0));
toMyGame.setStyle("-fx-text-fill: whitesmoke");
TextFlow tf = createTextFlow();
ObservableList list = tf.getChildren();
list.addAll(welcome, toMyGame);
return tf;
}
private TextFlow createTextFlow() {
String style = "-fx-background-color: black;";
style += " -fx-text-fill: whitesmoke;";
TextFlow tf = new TextFlow();
tf.setStyle(style);
return tf;
}
}

-fx-text-fill is a CSS property of Labeled, not Text. Text is a type of shape, and Shape supports -fx-fill rather than -fx-text-fill.
Changing every occurrence of -fx-text-fill to -fx-fill should give you the appearance you want.

Related

Multilne text. Libgdx

How to crate a multiline text? I tried to use Label , but text have only 1 line.
Table table = new Table();
table.setPosition(0,0);
table.setSize(800,440);
label = new Label("Some long string here...", skin);
label.setFillParent(true);
label.setAlignment(center);
label.setPosition(0,0);
label.setWidth(40);
label.setHeight(label.getPrefHeight());
label.setText(tutortext);
table.addActor(label);
stage.addActor(table);
stage.setDebugAll(true);
https://i.stack.imgur.com/3whQr.png
Use setWrap(true); on label.
According to doc.
If false, the text will only wrap where it contains newlines (\n). The preferred size of the label will be the text bounds.
If true, the text will word wrap using the width of the label. The preferred width of the label will be 0, it is expected that something external will set the width of the label. Wrapping will not occur when ellipsis is enabled. Default is false.
When wrap is enabled, the label's preferred height depends on the width of the label. In some cases the parent of the label will need to layout twice: once to set the width of the label and a second time to adjust to the label's new preferred height.
I've tested with small example :
public class MultiLine extends ApplicationAdapter {
Stage stage;
Skin skin;
#Override
public void create() {
stage=new Stage();
skin=new Skin(Gdx.files.internal("skin/glassy-ui.json"));
Label label=new Label("MULTILINE IN LIBGDX GAME DEVELOPMENT",skin);
label.setWrap(true);
Table table=new Table();
table.setFillParent(true);
table.add(label).width(150);
stage.addActor(table);
}
#Override
public void render() {
Gdx.gl.glClearColor(0,0,0,0);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.draw();
stage.act();
}
#Override
public void dispose() {
stage.dispose();
skin.dispose();
}
}
Here is the output :
A way simpler solution is to just use \n for linebreaks so instead of
Label label=new Label("MULTILINE IN LIBGDX GAME DEVELOPMENT",skin);
you would just do
Label label=new Label("MULTILINE\nIN\nLIBGDX\nGAME\nDEVELOPMENT",skin);
The label will be:
MULTILINE
IN
LIBGDX
GAME
DEVELOPMENT

JavaFX- how to hide tab content area and show only tab headers on selection of specific tab

I want to provide a way for users to hide/ unhide tab pane contents without adding additional buttons to UI. One way I thought was to provide a "dummy" tab in tabpane and on selecting it, all contents of tabpane will be hidden, except for headers. On selecting any other tab, contents will be made visible again. I have tried changing min/max/pref width of tabpane.
You can simply set the max height of the TabPane:
public class Main extends Application {
private static final int TABPANE_HEADER_HEIGHT = 29;
#Override
public void start(Stage primaryStage) throws Exception{
BorderPane root = new BorderPane();
// Add simple tabs
TabPane tp = new TabPane();
tp.getTabs().add(new Tab("Tab1", new Label(" Content of the first tab")));
tp.getTabs().add(new Tab("Tab2", new Label(" Content of the second tab")));
// Create the Tab which hides the content
Tab hideTab = new Tab("Hide", new Label(" Content of the third tab"));
tp.getTabs().add(hideTab);
hideTab.selectedProperty().addListener((obs, oldval, newval) ->
tp.setMaxHeight(((newval) ? TABPANE_HEADER_HEIGHT : -1)));
root.setTop(tp);
Scene scene = new Scene(root, 300, 275);
scene.getStylesheets().addAll(getClass().getResource("style.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Result:
Note
You can do the same using CSS by adding a new pseudo-class for .tab-pane called e.g. tabcontenthidden. In this pseudo class the max height of the TabPane is the height of the tabs.
style.css
.root { TAB_HEADER_HEIGHT: 29; }
.tab-pane:tabcontenthidden { -fx-max-height: TAB_HEADER_HEIGHT; }
.tab-pane {
-fx-max-height: -1;
-fx-background-color: orange;
}
In the Java code, you can create a PseudoClass like
PseudoClass TABPANE_CONTENT_HIDDEN = PseudoClass.getPseudoClass("tabcontenthidden");
and you can activate this pseudo-class with the pseudoClassStateChanged method:
tabPane.pseudoClassStateChanged(TABPANE_CONTENT_HIDDEN, true); // false to show
Note2
You can add Buttons to the tab area like in this answer (one button to hide and show) which maybe more ergonomic than an additional Tab.

setFont() method not working on label as expected javafx

I am creating a short javafx program containing a label with some text and a button which is supposed to change the font of the label to italic. Since the font I use is a custom font, I can't directly call new Font("human.ttf", FontPosture.ITALIC, 20) as javafx can't convert a custom font to italic or bold.
So I decided to have two different font files with the same font family with one having regular style and the other having italic style. Thus, when the italic button is clicked, the program would load the italic font file and set the font of the label to be the italic font.
But when I tried the program, the font of the label remains unaffected after clicking the italic button. I tried hard to find the source of the issue and added several print statements. During the process I found the problem was that the setFont method in the eventHandler of the button was not working correctly. Due to the print statements I also found that the font file path was correct. Hence, I am unable to figure out my mistake in the code.
This is the FontChanger class:
public class FontChanger extends Application{
private Label label;
private Font font;
public void start(Stage primaryStage){
AnchorPane root = new AnchorPane();
root.setPrefHeight(30);
root.setPrefWidth(30);
addLabel(root);
addItalicButton(root);
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.sizeToScene();
primaryStage.show();
}
public void addLabel(AnchorPane root){
label = new Label("Sample text");
font = Font.loadFont(FontChanger.this.getClass().getResource("human.ttf").toExternalForm (), 20);
label.setFont(font);
label.setLayoutX(10);
label.setLayoutY(10);
root.getChildren().add(label);
}
public void addItalicButton(AnchorPane root){
Button italicButton = new Button("italic");
italicButton.setLayoutX(10);
italicButton.setLayoutY(35);
italicButton.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
font = Font.loadFont(FontChanger.this.getClass().getResource("human_italic.ttf").toExternalForm(), 20);
System.out.println(FontChanger.this.getClass().getResource("human_italic.ttf").to ExternalForm());
label.setFont(font);
}
});
root.getChildren().add(italicButton);
}
public static void main(String[] args){
launch(args);
}
}
Please tell me if any kind of clarification is needed. Thanks in advance.
Finally after hours of experimentation, I have found that the problem is that whenever the font of a label or any similar control is already set to a custom font, you cannot set it once again to another custom font. I don't know the reason why this happens.
You cannot do this:
public void setFont(){
Font firstCustomFont = Font.loadFont(FontChanger.this.getClass().getResource("firstCustomFont.ttf").toExternalForm(), 20);
label.setFont(firstCustomFont);
Font secondCustomFont = Font.loadFont(FontChanger.this.getClass().getResource("secondCustomFont.ttf").toExternalForm(), 20);
label.setFont(secondCustomFont);// this will not work
}
I also found that you could set the font of a label to be a normal font after setting it to a custom font. And also you could set the font to a custom font if it is already set to a local font.
These two examples will work:
public void setFont(){
Font customFont = Font.loadFont(FontChanger.this.getClass().getResource("customFont.ttf").toExternalForm(), 20);
label.setFont(customFont);
Font normalFont = Font.font(20);
label.setFont(normalFont);// this will work
}
And:
public void setFont(){
Font normalFont = Font.font(20);
label.setFont(normalFont);
Font customFont = Font.loadFont(FontChanger.this.getClass().getResource("customFont.ttf").toExternalForm(), 20);
label.setFont(customFont);// this will work
}
So the trick I applied is that I first set the font of the label to a local font and then setting the font once again to the custom font you want to be set.
Something like this:
public void setFont(){
Font firstCustomFont = Font.loadFont(FontChanger.this.getClass().getResource("firstCustomFont.ttf").toExternalForm(), 20);
label.setFont(font);
Font normalFont = Font.font(20);
label.setFont(normalFont);
Font secondCustomFont = Font.loadFont(FontChanger.this.getClass().getResource("secondCustomFont.ttf").toExternalForm(), 20);
label.setFont(secondFont);// this will work
}
Edit: This problem occurred because the font files I used were the edited versions of the same font family. So this method could work pretty well if you have a regular and styled version of a font file and then you want to apply the styled version to a text which is already set to the regular version.

JavaFX Change textcolor of disabled textfield in CSS

I have a texfield in a stage:
#FXML
private TextField tfAdUsername;
tfAdUsername.setPromptText(userName);
tfAdUsername.setDisable(true);
The textcolor is lightgray, i want to change it to black:
.text-field:readonly {
-fx-background-color: #E0E0E2;
-fx-border-color: #94BBDA;
-fx-text-fill: #000000;
}
.text-field:disabled {
-fx-background-color: #E0E0E2;
-fx-border-color: #94BBDA;
-fx-text-fill: #000000;
}
This doesn't change the textcolor. What is the correct CSS Property to use?
The reason why color turns grey on disabling is because of the opacity change. Just try adding the following css to your textfield.
-fx-opacity: 1.0;
Working example (using setStyle() )
public class KeyStroke extends Application {
#Override
public void start(Stage primaryStage) {
Pane root = new Pane();
TextField textField = new TextField("Itachi");
textField.setDisable(true);
textField.setStyle("-fx-opacity: 1.0;");
root.getChildren().add(textField);
Scene scene = new Scene(root, 200, 200);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
For changing the opacity use:
.text-input:disabled {
-fx-opacity: 1.0;
}
in the css file.
To change the textcolor used (after i read the question properly i know this wasn't asked.)
From the modena.css stylesheet:
.root {
/* Used for the inside of text boxes, password boxes, lists, trees, and
* tables. See also -fx-text-inner-color, which should be used as the
* -fx-text-fill value for text painted on top of backgrounds colored
* with -fx-control-inner-background.
*/
-fx-control-inner-background: derive(-fx-base,80%);
/* Version of -fx-control-inner-background for alternative rows */
-fx-control-inner-background-alt: derive(-fx-control-inner-background,-2%);
/* One of these colors will be chosen based upon a ladder calculation
* that uses the brightness of a background color. Instead of using these
* colors directly as -fx-text-fill values, the sections in this file should
* use a derived color to match the background in use. See also:
*
* -fx-text-base-color for text on top of -fx-base, -fx-color, and -fx-body-color
* -fx-text-background-color for text on top of -fx-background
* -fx-text-inner-color for text on top of -fx-control-inner-color
* -fx-selection-bar-text for text on top of -fx-selection-bar
*/
}
.root {
-fx-text-inner-color: #FF01F3;
}
For example:
#Override
public void start(Stage primaryStage) {
VBox root = new VBox();
root.setAlignment(Pos.CENTER);
Button btn = new Button();
TextField text= new TextField();
btn.setText("Press me!");
btn.setOnAction((ActionEvent event) -> {
text.setText("Goodbye World");
});
root.getChildren().addAll(btn, text);
Scene scene = new Scene(root, 300, 250);
scene.getStylesheets().addAll(getClass().getResource("css.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
}
And the color of the text in the textfield will be pink?purple?
This is by the way not a means to change the color for each textfield individually, if you change this for the root then all the textfields will use this color instead of the usual black. I don't know how to change the color for one textfield to blue and for another one in the same application to red.

JavaFX labels height

I'm developing software in JavaFX and JavaFX Scene Builder.
I have a grid pane with 2 columns. Actually in each of the cells there are labels.
In the first column of the table the text inside the label is a default constant, in the second one the text can change.
The problem is that if the text variable is too long, it's automatically truncated.
How to start a new line trimming the text and re-sizing the height of the rows in the grid pane?
EDIT:
Thanks to #fabian issues, this is the solution to the initial question.
In addiction is necessary to set the fx:id of each element into Scene Builder.
#FXML private GridPane gridPane;
#FXML private Text text1;
#FXML private Text text2;
#FXML private Text text3;
private void setGridRowHeight(GridPane gpName, int numRow, double height){
ObservableList<RowConstraints> rows = gpName.getRowConstraints();
rows.get(numRow).setMinHeight(32);
rows.get(numRow).setPrefHeight(height);
rows.get(numRow).setMaxHeight(height);
}
private void addTextListener(final GridPane gridPane, final Text text){
text.textProperty().addListener(new ChangeListener<String>() {
#Override
public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
scrollPane.setFitToHeight(true);
text.setWrappingWidth( gridPane.getColumnConstraints().get(1).getPrefWidth() );
setGridRowHeight(gridPane, gridPane.getRowIndex(text), text.getLayoutBounds().getHeight() );
}
});
}
#FXML public void initialize() {
addTextListener(gridPane, text1);
addTextListener(gridPane, text2);
addTextListener(gridPane, text3);
}
Unfortunately the Label element does not resize depending on the text displayed. I recommend using the Text Shape. You can specify the maximal width using wrapping width in the scene builder.
You could try:
Label col2Label = new Label();
col2Label.setWrapText( true );
col2Label.setMaxHeight( Double.MAX_VALUE );
col_1_Label.prefHeightProperty().bind( col2Label.heightProperty() );
You can wrap [Region - Label - Region] in HBox.
The region will keep the label always centered.

Categories