2017-12-28 18 views
0

Ich habe eine Tableview mit ein paar Spalten mit FXML erstellt:Wie kann ich angeben, wie ein Objekt in eine Zeichenfolge konvertiert wird, um es in einem JavaFX TableView anzuzeigen?

<TableView fx:id="logTable" BorderPane.alignment="CENTER"> 
    <columns> 
     <TableColumn fx:id="timestampColumn" editable="false" text="Timestamp"> 
      <cellValueFactory> 
       <PropertyValueFactory property="timestamp"/> 
      </cellValueFactory> 
     </TableColumn> 
     <TableColumn fx:id="actionColumn" editable="false" text="Action"> 
      <cellValueFactory> 
       <PropertyValueFactory property="action"/> 
      </cellValueFactory> 
     </TableColumn> 
    </columns> 
</TableView> 

Ich habe dann ein Objekt wie folgt definiert:

private ObservableList<LogEntry> log = FXCollections.observableArrayList(); 

, die für die Tableview als das Modell festgelegt ist:

logTable.setItems(log); 

Die LogEntries wie folgt aussehen:

import javafx.beans.property.SimpleObjectProperty; 
import javafx.beans.property.SimpleStringProperty; 
import org.joda.time.DateTime; 

public class LogEntry { 
    private SimpleObjectProperty<DateTime> timestamp = new SimpleObjectProperty<>(); 
    private SimpleStringProperty action = new SimpleStringProperty(); 

    public LogEntry(String format, Object... args) { 
     this.timestamp.setValue(new DateTime()); 
     String s = String.format(format, args); 
     System.out.println(s); 
     this.action.setValue(s); 
    } 

    public DateTime getTimestamp() { 
     return timestamp.getValue(); 
    } 

    public String getAction() { 
     return action.getValue(); 
    } 
} 

Meine Frage ist, wie kann ich angeben, wie die Jodatime DateTimes in Zeichenfolgen für die Anzeige konvertiert werden? Ich möchte sie mit dem aktuellen Gebietsschema konvertieren (aber ich möchte, dass die Spalte noch funktioniert).

+1

OT zu aktualisieren: Sind Sie gebunden zu Java 7 oder gezwungen Joda Zeit aus einem anderen Grund hier zu benutzen? Die Java 8 Time API macht Joda Time grundsätzlich überflüssig (es basiert sehr stark auf Joda Time und die API ist sehr ähnlich). Die [Joda Time-Homepage] (http://www.joda.org/joda-time/) sagt eigentlich: ** "Beachten Sie, dass Benutzer ab Java SE 8 aufgefordert werden, zu java.time (JSR-310) - ein Kernteil des JDK, der dieses Projekt ersetzt. "** –

+0

@James_D: Ich benutze tatsächlich Java 8. Ich wusste nicht, dass Java 8 es redundant macht. Ich muss mich darum kümmern. Vielen Dank. – Pablo

+0

@Pablo Das Projekt [JSR 310] (https://jcp.org/en/jsr/detail?id=310), das * java.time * definiert, wird von demselben Mann geleitet, der * Joda-Time *, [Stephen Colebourne] (https://stackoverflow.com/users/38896/jodastephen). Die * java.time * -Klassen sind eine komplette Neuschreibung von * Joda-Time * mit den gelernten Lektionen. –

Antwort

1

Ich habe nicht mit Joda Time gearbeitet, aber mit LocalDateTime ähnlich gemacht.

Hier ist ein Beispiel, wie das funktionieren könnte.

Zunächst müssten Sie die Eigenschaften aussetzen ::

public class LogEntry { 
    private SimpleObjectProperty<LocalDateTime> timestamp = new SimpleObjectProperty<>(); 
    private SimpleStringProperty action = new SimpleStringProperty(); 
    public final SimpleObjectProperty<LocalDateTime> timestampProperty() { 
     return this.timestamp; 
    } 

    public final java.time.LocalDateTime getTimestamp() { 
     return this.timestampProperty().get(); 
    } 

    public final void setTimestamp(final java.time.LocalDateTime timestamp) { 
     this.timestampProperty().set(timestamp); 
    } 

    public final SimpleStringProperty actionProperty() { 
     return this.action; 
    } 

    public final java.lang.String getAction() { 
     return this.actionProperty().get(); 
    } 

    public final void setAction(final java.lang.String action) { 
     this.actionProperty().set(action); 
    } 
} 

Dann Sie die Zellfabrik und Zellenwert Werkseinstellung:

dateTimeColumn.setCellFactory(tc -> new LocalDateTimeTableCell<LogEntry>(true)); 
dateTimeColumn.setCellValueFactory(data -> data.getValue().timestampProperty()); 

eine Tabellenzelle wie folgt erstellen:

public class LocalDateTimeTableCell<S> extends TableCell<S, LocalDateTime> { 
    private final DateTimeFormatter myDateFormatter = DateTimeFormatter.ofPattern("MM/dd/yyyy"); 
    private final DateTimeFormatter myDateTimeFormatter = DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm:ss a"); 
    private final boolean showTime; 

    public LocalDateTimeTableCell(boolean showTime){ 
     this.showTime = showTime; 
    } 
    @Override 
    protected void updateItem(LocalDateTime item, boolean empty) { 
     super.updateItem(item, empty); 
     if (item == null || empty) { 
      setText(null); 
      setStyle(""); 
     } else { 
      // Format date. 
      if(showTime) { 
       setText(myDateTimeFormatter.format(item)); 
      }else { 
       setText(myDateFormatter.format(item)); 
      } 
     } 
    } 
} 

Ich weiß, das ist nicht genau das, was Sie mit Joda Zeit gefragt - aber sollte dir die Richtung geben.

+0

Ich empfehle, die Formatierer an die Zelle im Konstruktor übergeben zu können. Sie könnten immer noch einen Konstruktor ohne Argumente bereitstellen, der die Werte verwendet, die Sie derzeit verwenden. Wenn Sie jedoch einen Konstruktor übergeben, der diese Werte übergibt, können Sie die Formatierer für die gesamte Spalte wiederverwenden, anstatt für jede einzelne Zelleninstanz einen zu erstellen ... – fabian

+0

Wie wäre es, wenn Sie sie statisch final machen würden? Dann ist die interne Implementierung versteckt und sie würden auf Klassenebene sein? –

+0

Möglich, aber sie an den Konstruktor zu übergeben, ist flexibler, da Sie verschiedene Formate übergeben können (z. B. für die Verwendung des "europäischen" Datumsformats). Persönlich würde ich das bevorzugen und statische "forTableColumn" -Methoden erstellen, um Zellfabriken zu erstellen (wie es bei anderen 'TableCell'-Implementierungen gemacht wird).In einer solchen Methode wäre es einfach, die Formatierer als lokale Variablen zu deklarieren und sie in einer von der Methode zurückgegebenen Lambda-Ausdruck/Anomymus-Klasse zu verwenden. – fabian

-1

Zell-Fabrik unter Verwendung der Zellen

private TableColumn<Customer, LocalDateTime> Col_date; 
    Col_date.setCellFactory((TableColumn<LogEntry, LocalDateTime> param) -> { 
     TableCell<LogEntry, LocalDateTime> cell = new TableCell<LogEntry, LocalDateTime>() { 
      @Override 
      public void updateItem(LocalDateTime item, boolean empty) { 
       if (item != null) { 
        setText(getDateTimeFormat(item,"yyyy/MM/dd HH:mm")); 

       } else { 
        setText(null); 
       } 
      } 
     }; 
     return cell; 
    }); 


public static String getDateTimeFormat(LocalDateTime dateTime,String format) throws DateTimeParseException { 
    return dateTime.format(DateTimeFormatter.ofPattern(format)); 
} 
Verwandte Themen