JAVAFX TableView CELL should display text in multiline in single cell with multi color. possible?

后端 未结 2 752
别跟我提以往
别跟我提以往 2021-01-15 10:28

I need to have TableView CELL should display text in multi line in single cell with multi color.

In CELL I am displaying Multiline text using \"\\n\" currently. But

相关标签:
2条回答
  • 2021-01-15 10:38

    You can use a custom cell factory in this case, here is an example:

    • I've created an FXML document that contains a TableView holding two TableColumns, one for the fullname and the second for the address of a Person instance.
    • I've then set the cellFactory as follows:

      addressCol.setCellFactory(column->{
                  return new TableCell<Person, String>() {
                      @Override
                      protected void updateItem(String item, boolean empty) {
                          super.updateItem(item, empty);
                          if(item==null || empty) {
                              setGraphic(null);
                          } else {
                              VBox vbox = new VBox();
                              List<String> textList = Arrays.asList(item.split("\n"));
                              String[] colors = {"#3E50B4", "#FF3F80", "#727272"};
                              int colorCount = colors.length;
                              for(int i=0;i<textList.size();i++) {
                                  Label lbl = new Label(textList.get(i));
                                  lbl.setStyle("-fx-text-fill: "+colors[i%colorCount]);
                                  vbox.getChildren().add(lbl);
                              }
                              setGraphic(vbox);
                          }
                      }
                  };
              });
      

    Now this is just an example where I've used a VBox containing a bunch of Label instances (one for each line), and I've hard coded the colors, you can use whatever you like, for example, you can try a TextFlow with Text nodes and you can also use CSS Style classes.

    Here is the full example code:

    TableViewExample.fxml

    <?xml version="1.0" encoding="UTF-8"?>
    
    <?import javafx.scene.text.*?>
    <?import javafx.scene.control.*?>
    <?import javafx.geometry.*?>
    <?import java.lang.*?>
    <?import javafx.scene.layout.*?>
    <?import javafx.scene.layout.AnchorPane?>
    
    <VBox alignment="CENTER" spacing="10.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
       <padding>
          <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
       </padding>
       <children>
          <Label text="Colored Lines of Text in a Table Cell Example">
             <font>
                <Font size="16.0" />
             </font>
          </Label>
          <TableView fx:id="personTable" prefHeight="200.0" prefWidth="200.0">
            <columns>
              <TableColumn fx:id="fullnameCol" prefWidth="75.0" text="Full Name" />
                <TableColumn fx:id="addressCol" prefWidth="75.0" text="Address" />
            </columns>
             <columnResizePolicy>
                <TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
             </columnResizePolicy>
          </TableView>
       </children>
    </VBox>
    

    Person.java

    public class Person {
    
        private String fullname, address;
    
        public Person() {}
    
        public Person(String fullname, String address) {
            this.fullname = fullname;
            this.address = address;
        }
    
        public String getFullname() {
            return fullname;
        }
    
        public void setFullname(String fullname) {
            this.fullname = fullname;
        }
    
        public String getAddress() {
            return address;
        }
    
        public void setAddress(String address) {
            this.address = address;
        }
    }
    

    MainApp.java

    import java.net.URL;
    import java.util.Arrays;
    import java.util.List;
    import java.util.ResourceBundle;
    
    import javafx.application.Application;
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableList;
    import javafx.fxml.FXML;
    import javafx.fxml.FXMLLoader;
    import javafx.fxml.Initializable;
    import javafx.scene.Parent;
    import javafx.scene.Scene;
    import javafx.scene.control.Label;
    import javafx.scene.control.TableCell;
    import javafx.scene.control.TableColumn;
    import javafx.scene.control.TableView;
    import javafx.scene.control.cell.PropertyValueFactory;
    import javafx.scene.layout.VBox;
    import javafx.stage.Stage;
    
    public class MainApp extends Application implements Initializable {
    
        @FXML private TableView<Person> personTable;
        @FXML private TableColumn<Person, String> fullnameCol, addressCol;
        ObservableList<Person> persons = FXCollections.observableArrayList();
    
        public static void main(String [] args) {
            launch(args);
        }
    
        @Override
        public void initialize(URL url, ResourceBundle rb) {
            Person p1 = new Person("John Doe", "Charlotte ,\n403 St. Tryon Street");
            Person p2 = new Person("Riyad Mahrez", "xxxxx, \n007 St.YYYY");
            persons.addAll(p1, p2);
            fullnameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("fullname"));
            addressCol.setCellValueFactory(new PropertyValueFactory<Person, String>("address"));
    
            addressCol.setCellFactory(column->{
                return new TableCell<Person, String>() {
                    @Override
                    protected void updateItem(String item, boolean empty) {
                        super.updateItem(item, empty);
                        if(item==null || empty) {
                            setGraphic(null);
                        } else {
                            VBox vbox = new VBox();
                            List<String> textList = Arrays.asList(item.split("\n"));
                            String[] colors = {"#3E50B4", "#FF3F80", "#727272"};
                            int colorCount = colors.length;
                            for(int i=0;i<textList.size();i++) {
                                Label lbl = new Label(textList.get(i));
                                lbl.setStyle("-fx-text-fill: "+colors[i%colorCount]);
                                vbox.getChildren().add(lbl);
                            }
                            setGraphic(vbox);
                        }
                    }
                };
            });
            personTable.setItems(persons);
        }
    
        @Override
        public void start(Stage primaryStage) throws Exception {
            FXMLLoader loader = new FXMLLoader();
            loader.setLocation(getClass().getResource("TableViewExample.fxml"));
            loader.setController(this);
            Parent parent = loader.load();
            Scene scene = new Scene(parent);
            primaryStage.setScene(scene);
            primaryStage.show();
        }
    }
    

    I hope this helps...

    0 讨论(0)
  • 2021-01-15 10:48

    You can use a cellFactory to customize the way the content is displayed. Assuming the values for the column are Strings like "Charlotte\n403 St. Tryon Street" and "Tony Stark\n10880 Malibu Point\n90265"

    It could be done like this:

    column.setCellFactory(tv -> new TableCell<MyItemType, String>() {
    
        private final VBox lines;
    
        {
            lines = new VBox();
            lines.getStyleClass().add("address");
            setGraphic(lines);
        }
    
        @Override
        protected void updateItem(String item, boolean empty) {
            super.updateItem(item, empty);
    
            lines.getChildren().clear();
    
            if (!empty && item != null) {
                int lineNo = 1;
                for (String line : item.split("\n")) {
                    Text text = new Text(line);
                    text.getStyleClass().add("line-" + (lineNo++));
                    lines.getChildren().add(text);
                }
            }
        }
    
    });
    

    CSS stylesheet

    .address > * {
        -fx-fill: green;
    }
    
    .address > .line-1 {
        -fx-fill: red;
    }
    

    Note that this uses CSS to style the lines, but you could also assign the color in the updateItem method directly...

    0 讨论(0)
提交回复
热议问题