Last active
April 28, 2016 23:05
-
-
Save jewelsea/5036908 to your computer and use it in GitHub Desktop.
Sample of using a FlowPane to create styled text in JavaFX
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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).