-
-
Save jewelsea/5036908 to your computer and use it in GitHub Desktop.
/** | |
* 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; | |
} | |
} | |
} |
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.
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
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.
error in Java 8
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).
Answer to StackOverflow question: JavaFX text multi-word colorization.