Skip to content

Instantly share code, notes, and snippets.

@jewelsea
Last active April 28, 2016 23:05
Show Gist options
  • Save jewelsea/5036908 to your computer and use it in GitHub Desktop.
Save jewelsea/5036908 to your computer and use it in GitHub Desktop.
Sample of using a FlowPane to create styled text in JavaFX
/**
* fruits.css - place in same source directory as FruitsDisplay.java and
* ensure the build system copies the file over to the output path
*/
.root {
-fx-font-size: 20px;
-fx-font-family: "Comic Sans MS";
}
.list-cell {
-fx-background-color: azure;
}
.fruit {
-fx-font-weight: bold;
-fx-font-style: italic;
}
.apple {
-fx-fill: forestgreen;
}
.orange {
-fx-fill: orange;
}
.pear {
-fx-fill: gold;
}
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.image.*;
import javafx.scene.layout.*;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import java.util.*;
/**
* Sample of using a FlowPane to create styled text in JavaFX
*/
public class FruitsDisplay extends Application {
private static final String[] fruits = {"apple", "orange", "pear"};
private static final String[] fruitImageLocs = {
"http://weknowyourdreamz.com/images/apple/apple-02.jpg",
"http://pic.1fotonin.com/data/wallpapers/165/WDF_2048871.png",
"http://vignette1.wikia.nocookie.net/pikmin/images/c/cc/Pear-01.jpg"
};
private Map<String, Image> fruitImages = new HashMap<>();
public static void main(String[] args) {
Application.launch(FruitsDisplay.class);
}
@Override
public void start(Stage stage) throws Exception {
stage.setTitle("Fruit Tales");
for (int i = 0; i < fruits.length; i++) {
Image image = new Image(fruitImageLocs[i], 0, 30, true, true);
fruitImages.put(fruits[i], image);
}
ListView<String> list = new ListView<>(FXCollections.observableArrayList(fruits));
list.setCellFactory(listView -> new FruitFlowCell());
list.setPrefSize(440, 180);
Scene scene = new Scene(list);
scene.getStylesheets().add(getResource("fruits.css"));
stage.setScene(scene);
stage.show();
}
private String getResource(String resourceName) {
return getClass().getResource(resourceName).toExternalForm();
}
private class FruitFlowCell extends ListCell<String> {
static final String FRUIT_PLACEHOLDER = "%f";
{
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
}
@Override
protected void updateItem(String s, boolean empty) {
super.updateItem(s, empty);
if (s != null && !"".equals(s) && !isEmpty()) {
setGraphic(createFruitFlow(s));
} else {
setGraphic(null);
}
}
private Node createFruitFlow(String s) {
switch (s) {
case "apple":
return createTextFlow("Eat an ", FRUIT_PLACEHOLDER, s, " a day.");
case "orange":
return createTextFlow("An ", FRUIT_PLACEHOLDER, s, " has many vitamins.");
case "pear":
return createTextFlow("A ", FRUIT_PLACEHOLDER, s, " has a funny shape.");
default:
return null;
}
}
private Node createTextFlow(String... msg) {
FlowPane flow = new FlowPane();
boolean isFruit = false;
for (String s : msg) {
if (FRUIT_PLACEHOLDER.equals(s)) {
isFruit = true;
continue;
}
Text text = new Text(s);
if (isFruit) {
flow.getChildren().addAll(
new ImageView(fruitImages.get(s)),
createSpacer(5)
);
text.getStyleClass().addAll(
"fruit",
s
);
isFruit = false;
} else {
text.getStyleClass().add("plain");
}
flow.getChildren().add(text);
}
return flow;
}
private Node createSpacer(int width) {
HBox spacer = new HBox();
spacer.setMinWidth(HBox.USE_PREF_SIZE);
spacer.setPrefWidth(width);
spacer.setMaxWidth(HBox.USE_PREF_SIZE);
return spacer;
}
}
}
@jewelsea
Copy link
Author

This sample uses a FlowPane so that it works with JavaFX 2.2. Future version of JavaFX will add a TextFlow node, which would be the preferred way to to multi-word colorization in JavaFX.

@takasurazeem
Copy link

Can we have a multi-colored text inside the tableview cell? In swing I did that using html font tag but in JavaFx that doesn't work sample: http://s4.postimg.org/ck8sv41sd/help_aid.jpg

@jewelsea
Copy link
Author

Yes takasurazeem, create the TextFlow in the update method of a TableCell generated by a TableView CellFactory. If you have further questions, ask them on StackOveflow under the JavaFX tag please.

Copy link

ghost commented Nov 16, 2015

error in Java 8

@jewelsea
Copy link
Author

Yes haucongle, when I run the application with Java 8u72, the first image in the list is not displayed, but the others are. How bizarre. It used to work fine in earlier versions. I updated the code and resources used in the gist as they were pointing to some images that weren't existing on the web, but even then, it still doesn't work right anymore and the first image is not displayed. There is perhaps some bug introduced in Java 8 or something in the program that was always wrong and was exposed by the Java 8 implementation (I don't really know what is going wrong).

Anyway, the sample application is now pretty obsolete, and the appropriate way to do this in Java 8 would be to use the new TextFlow control that was added in Java 8, instead of using a FlowPane to contain styled text (as has been demonstrated in this application).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment