Java FX:部分更改 ListView 中的颜色?
Java FX: Partly change the color in a ListView?
我有一个包含文件夹路径的 ListView,它显示了添加到程序中的文件夹。
我现在想在每个条目中添加一个单词,具体取决于文件夹是否加密,例如我想添加绿色单词'encrypted'。
我尝试添加带有 html 颜色标签的字符串,但这不起作用。
if (loadedFolders != null) {
ObservableList<String> list = controller.folderList.getItems();
for (int i = 0; i < list.size(); i++) {
StringBuilder read = new StringBuilder();
read.append(list.get(i)).append("<html><font color='red'>test</font></html>");
controller.folderList.getItems().set(i, read.toString());
}
}
重要的是,只有添加的单词应该有不同的颜色,其余的保持不变。
您不能使用 HTML 在 JavaFX 中设置字符串样式。您需要做的是为 ListView
.
中显示的实际文本添加样式
为此,您需要实现自己的 ListCell
。 ListCell
是为您的 ListView
中的每个项目显示的实际单元格。起初看起来令人望而生畏,但它相当简单,并且是您可以有选择地更改数据在 ListView
.
中显示方式的唯一方法
下面是一个完整的示例应用程序,您可以通读并运行了解它是如何工作的。
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class ListCellSample extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
// **********************************************************************************************
// Create a simple base layout
// **********************************************************************************************
VBox root = new VBox(5);
root.setAlignment(Pos.CENTER);
root.setPadding(new Insets(5));
// Standard ListView for our sample data
ListView<Sample> listView = new ListView<>();
// Create some sample data for the ListView (some encrypted and others not)
listView.getItems().addAll(
new Sample("One", false),
new Sample("Two", true),
new Sample("Three", false),
new Sample("Four", true)
);
// Add the ListView to the layout
root.getChildren().add(listView);
// **********************************************************************************************
// Here we provide our own ListCell using the setCellFactory() method of the ListView
// **********************************************************************************************
listView.setCellFactory(lv -> new ListCell<Sample>() {
// Here we create the reusable layout for each cell. We will use an HBox for the root and labels
// for the name of the Sample and it's encryption status
final HBox root = new HBox(5);
final Label sampleNameLabel = new Label();
final Label encryptedLabel = new Label("Encrypted");
// Set the style for the encryptedLabel in a static block
{
encryptedLabel.setStyle("-fx-text-fill: green; " +
"-fx-font-style: italic;");
// Add the sampleNameLabel to the root HBox. We will add the Encrypted label later, if needed
root.getChildren().add(sampleNameLabel);
}
@Override
protected void updateItem(Sample sample, boolean empty) {
super.updateItem(sample, empty);
if (sample == null || empty) {
setGraphic(null);
// Remove the encrypted label
root.getChildren().remove(encryptedLabel);
} else {
// Set the sampleNameLabel to our sample's name
sampleNameLabel.setText(sample.getName());
// If the Sample is encrypted, add the encryptedLabel to our layout
if (sample.isEncrypted()) {
root.getChildren().add(encryptedLabel);
}
// Set our custom layout as the cell's graphic
setGraphic(root);
}
}
});
// Show the application
primaryStage.setScene(new Scene(root));
primaryStage.show();
}
}
class Sample {
private final String name;
private final boolean encrypted;
public Sample(String name, boolean encrypted) {
this.name = name;
this.encrypted = encrypted;
}
public String getName() {
return name;
}
public boolean isEncrypted() {
return encrypted;
}
}
这就是您最终得到的结果:
我有一个包含文件夹路径的 ListView,它显示了添加到程序中的文件夹。
我现在想在每个条目中添加一个单词,具体取决于文件夹是否加密,例如我想添加绿色单词'encrypted'。
我尝试添加带有 html 颜色标签的字符串,但这不起作用。
if (loadedFolders != null) {
ObservableList<String> list = controller.folderList.getItems();
for (int i = 0; i < list.size(); i++) {
StringBuilder read = new StringBuilder();
read.append(list.get(i)).append("<html><font color='red'>test</font></html>");
controller.folderList.getItems().set(i, read.toString());
}
}
重要的是,只有添加的单词应该有不同的颜色,其余的保持不变。
您不能使用 HTML 在 JavaFX 中设置字符串样式。您需要做的是为 ListView
.
为此,您需要实现自己的 ListCell
。 ListCell
是为您的 ListView
中的每个项目显示的实际单元格。起初看起来令人望而生畏,但它相当简单,并且是您可以有选择地更改数据在 ListView
.
下面是一个完整的示例应用程序,您可以通读并运行了解它是如何工作的。
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class ListCellSample extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
// **********************************************************************************************
// Create a simple base layout
// **********************************************************************************************
VBox root = new VBox(5);
root.setAlignment(Pos.CENTER);
root.setPadding(new Insets(5));
// Standard ListView for our sample data
ListView<Sample> listView = new ListView<>();
// Create some sample data for the ListView (some encrypted and others not)
listView.getItems().addAll(
new Sample("One", false),
new Sample("Two", true),
new Sample("Three", false),
new Sample("Four", true)
);
// Add the ListView to the layout
root.getChildren().add(listView);
// **********************************************************************************************
// Here we provide our own ListCell using the setCellFactory() method of the ListView
// **********************************************************************************************
listView.setCellFactory(lv -> new ListCell<Sample>() {
// Here we create the reusable layout for each cell. We will use an HBox for the root and labels
// for the name of the Sample and it's encryption status
final HBox root = new HBox(5);
final Label sampleNameLabel = new Label();
final Label encryptedLabel = new Label("Encrypted");
// Set the style for the encryptedLabel in a static block
{
encryptedLabel.setStyle("-fx-text-fill: green; " +
"-fx-font-style: italic;");
// Add the sampleNameLabel to the root HBox. We will add the Encrypted label later, if needed
root.getChildren().add(sampleNameLabel);
}
@Override
protected void updateItem(Sample sample, boolean empty) {
super.updateItem(sample, empty);
if (sample == null || empty) {
setGraphic(null);
// Remove the encrypted label
root.getChildren().remove(encryptedLabel);
} else {
// Set the sampleNameLabel to our sample's name
sampleNameLabel.setText(sample.getName());
// If the Sample is encrypted, add the encryptedLabel to our layout
if (sample.isEncrypted()) {
root.getChildren().add(encryptedLabel);
}
// Set our custom layout as the cell's graphic
setGraphic(root);
}
}
});
// Show the application
primaryStage.setScene(new Scene(root));
primaryStage.show();
}
}
class Sample {
private final String name;
private final boolean encrypted;
public Sample(String name, boolean encrypted) {
this.name = name;
this.encrypted = encrypted;
}
public String getName() {
return name;
}
public boolean isEncrypted() {
return encrypted;
}
}
这就是您最终得到的结果: