JavaFX Tableview Clock Column update

blazingblade

Mitglied
Hi,
ich schreibe grade an einer Termin Verwaltung. Dazu hab ich eine Tabelle die die Termine auflistet. In der letzten Spalte soll eine "Uhr" laufen. D.h. dort sollen die Minuten, Stunden, Tage, Monate und Jahre angegeben werden die es noch braucht bis der Termin fällig ist. Diese Spalte ist quasi ein Countdown. Ich hab versucht die entsprechende Spalte in der Observablelist die zum einfügen eines Termins in die Tableview an ein selbst entworfenes "Clockbinding"(Ink. TaskThread) zu binden aber die Table wird nicht upgedatet wenn man die List verändert und irgendwie wird auch nicht die ComputeValue methode mehr als einmal aufgerufen. Ich habe Versucht ein direkt ein property von dem Tableview zu bekommen und dieses dann an mein Clockbinding(Low Level API) zu binden wieder mit dem Problem das das Clockbinding nur einmal ComputeValue aufruft. Also startete ich meinen letzten versuch in dem ich eine ClockCell versucht zu entwerfen aber das ist auch nur halbgar.

Wie macht man das richtig?
Code:
package Alarm;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;

import javafx.beans.binding.StringBinding;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.concurrent.Task;

public class ClockBinding extends StringBinding
{
   
    private ObjectProperty<LocalDateTime> when;
   
    public ClockBinding(SimpleStringProperty property)
    {
        super.bind(property);
        DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
        when = new SimpleObjectProperty(LocalDateTime.parse(property.get(), formatter));
        new Thread(countDown).start();
        System.out.println("End of ClockBinding Construcktor parameter Time when = "+when.toString());
    }
   
    //Task runtime is here to show the actual DateTime
    Task countDown = new Task<Void>()
    {
   
        @Override public Void call()
        {
            while(true)
            {

                // @Author Thomas code from Stackoverflow
                //*************************************************************************
                LocalDateTime tempDateTime = LocalDateTime.from(LocalDateTime.now());

                long years = tempDateTime.until(when.get(), ChronoUnit.YEARS);
                tempDateTime = tempDateTime.plusYears(years);

                long months = tempDateTime.until(when.get(), ChronoUnit.MONTHS);
                tempDateTime = tempDateTime.plusMonths(months);

                long days = tempDateTime.until(when.get(), ChronoUnit.DAYS);
                tempDateTime = tempDateTime.plusDays(days);

                long hours = tempDateTime.until(when.get(), ChronoUnit.HOURS);
                tempDateTime = tempDateTime.plusHours(hours);

                long minutes = tempDateTime.until(when.get(), ChronoUnit.MINUTES);
                tempDateTime = tempDateTime.plusMinutes(minutes);

                String distance = years + " years " +
                        months + " months " +
                        days + " days " +
                        hours + " hours " +
                        minutes + " minutes";
                //******************************************************************************
                updateMessage(distance);
                System.out.println("After updateMessage");
               
                //computeValue();
                //System.out.println("After manual Computing Value");
               
                try
                {
                    Thread.sleep(20000);
                }
                catch(InterruptedException e)
                {
                    e.printStackTrace();
                }
               
                System.out.println("ClockBinding Task Loop End Message = " + distance);
            }
        }
    };

    @Override
    protected String computeValue()
    {
       
        System.out.println("Computed Value: "+countDown.getMessage()+"!!!!");
        return countDown.getMessage();
    }
}
 
Das einfachste wäre: Dein Modell verwendet eine Property (String oder was auch immer). Dann machst du eine Custom-Cell, in der du die Text-Property an die Property des Modells bindest.
Dan brauchst du einen Task, der z.B. alle Minute, oder so, über das Modell rennt und diese Property anpasst. Die Anzeige sollte sich - dank des Databinding - von selbst updaten.
In etwa klar, was ich meine?
 
Ja, aber dann würde ich ja quasi schon alles machen. ;-)
Ausserdem habe ich gerade kein passendes Beispiel zum umwandeln zur Hand.
 
Hm. Sollte eigentlich kein Problem sein: Du musst eh einen separaten Task haben, der über das gesamte Modell geht und diese ominöse Property anpasst. Da sollte er natürlich immer den gegenwärtigen Wert aus dem jeweiligen Modellobjekt nutzen...
 

Zurück
Oben