Message Box soll bei bestimmter Zeit angezeigt werden

Jacl

Aktives Mitglied
Ich probiere seit Tagen eine Lösung zu finden, nichts funktioniert. Ich hoffe hier kann mir wer helfen.
Ich habe einen JSpinner mit einer Liste fix vorgegebener Zeiten (07:00, 07:05, 07:10,… usw. bis 17:00). Nach betätigen eines Buttons soll die Zeit ausgelesen werden und ein in einer Schleife über die aktuelle Uhrzeit immer wieder abgefragt werden ob diese Zeit schon erreicht ist. Wenn sie erreicht ist, soll eine Dialogbox erscheinen.
Die selektierte Zeit aus dem jSpinner wird mit Variable = jSpinner.getValue(); ausgelesen, die aktuelle Zeit wird mit long AktuelleZeit = System.currentTimeMillis(); ermittelt.
Die Auswahl des jSpinner konnte ich in einen String umwandeln, den String wiederum habe ich in eine long variable konvertiert (oder gecastet wie auch immer). Der Vergleich ist aber nicht möglich, denn der Inhalt der long Variable vom JSpinner ist viel kürzer…
Ich scheitere immer wieder mit dem Vergleich der aktuellen Zeiten in Millisekunden und der jSpinner Eingabe um mit einer Schleife bei Zeitgleichheit eine Dialogbox aufzurufen .

Gibt’s hier ne einfache Lösung und vielleicht ein Beispiel wie ich’s lösen kann? Ein Codesnippet wäre ideal, bin noch nicht so erfahren…

Bin für jede Hilfe dankbar... 🙁


regards Jacl
 
Konvertiere doch die ms einfach in Minuten / Stunden und vergleich diese miteinander.
Java:
int minutes = (int) ((milliseconds / (1000*60)) % 60);
int hours   = (int) ((milliseconds / (1000*60*60)) % 24);
Entweder extrahierst du dann die Stunde / Minute aus dem String und schaust ob die gleich sind
Java:
String spinnerValue = spinner.getValue();
String[] splits = spinnerValue.split(":");
int spinnerMinutes = Integer.parseInt(splits[1]);
int spinnerHours = Integer.parseInt(splits[0]);

if(minutes == spinnerMinutes && ... ) {... }
oder du wandelst die Minuten/Stunden in einen String um und vergleichst die Strings
Java:
String timeString = String.format("%02d:%02d", hours, minutes);
if(timeString.equals(spinner.getValue()) { .. }
 
Vielen Dank für die Beispiele, ich werde sie sobald ich wieder zu Haus bin (bin gerade in der Arbeit) ausprobieren. Ich denke, mein Problem gehört zu den trivialen Problemen, so schwer kann's nicht sein - bin halt noch am lernen...
Gebe bescheid...
Jacl
 
Sorry, hat ein bischen gedauer (Stress in der Arbeit), egal...
Also ich habe die Vorschläge ausprobiert und hänge nun beim Problem, dass die aktuelle Uhrzeit die ich mir mit
Java:
long Zeit = System.currentTimeMillis();
hole und anschließend mit
Java:
int Shours = (int)  (Zeit /  (1000*60*60) % 24);
int Sminutes = (int)  (Zeit /  (1000*60) % 60);
für den Stunden- und Minutenvergleich herrichte um 1 Stunde falsch (1 Stunde früher) angezeigt wird. Eigenartigerweise wird die Zeit mit
Java:
SimpleDateFormat Uhrzeitaktuell = new SimpleDateFormat("HH:mm");
String Uhrzeitaktuell = sdf.format(new Date());
völlig richtig angezeigt.
Die Frage ist nun, wie kriege ich die korrekte Zeit mit
Java:
long Zeit = System.currentTimeMillis();
und der obigen beschriebenen Umwandlung nach int?
Ich stehe wiedereinmal an, dass dürfte doch kein triviales Problem sein, anscheinend...
Jacl
 
Vielleicht ist's mit einem Beispiel besser: Wenn ich um 14:40 Uhr
Java:
long Zeit = System.currentTimeMillis();
int hours = (int)  (Zeit /  (1000*60*60) % 24);
int minutes = (int)  (Zeit /  (1000*60) % 60);
System.out.println("hours: " + hours + " minutes: " + minutes);
eingebe, wird hours: 13 minutes: 40 augegeben. Wie bekommt man die Stunde in den Griff?
 
System.currentTimeMillis() liefert die Anzahl der Millisekunden, die seit 1. Januar 1970, 00:00 Uhr in UTC vergangen sind. Date berücksichtigt die Zeitzone.

Java:
import java.util.*;
import java.time.ZonedDateTime;
import java.time.ZoneId;

public class Test {
    public static void main(String[] args) {

        System.out.printf("currentTimeMillis: %d\n",System.currentTimeMillis());
        System.out.printf("Date#getTime(): %d\n", new Date().getTime());

        Calendar c = Calendar.getInstance();
        c.setTimeInMillis(System.currentTimeMillis());
        System.out.printf("Calendar: %02d:%02d:%02d\n",
            c.get(Calendar.HOUR_OF_DAY),
            c.get(Calendar.MINUTE),
            c.get(Calendar.SECOND));

        ZonedDateTime zdt = ZonedDateTime.now();
        System.out.printf("Zeit in aktueller Zeitzone: %02d:%02d:%02d\n",
            zdt.getHour(), zdt.getMinute(), zdt.getSecond());

        zdt = ZonedDateTime.now(ZoneId.of("Z"));
        System.out.printf("Zeit in UTC: %02d:%02d:%02d\n",
            zdt.getHour(), zdt.getMinute(), zdt.getSecond());

    }
}
 
Date berücksichtigt die Zeitzone.
Wenn ich um 15:30 Uhr folgendes eingebe:
Java:
long Uhrzeitaktuell = new Date().getTime();
int hours = (int)  (Uhrzeitaktuell /  (1000*60*60) % 24);
int minutes = (int)  (Uhrzeitaktuell /  (1000*60) % 60);
System.out.println("hours: " + hours + " minutes: " + minutes);
bekomme ich wieder hours: 14 Sminutes: 30 heraus.
Irgendwie versteh ich's nicht. Wie bekomme ich die Millisekunden der aktuellen Zeit die meine Zeitzone berücksichtigt? Ich bin echt verwirrt.
Ich will bzw. brauche die Millisekunden die auch die Zeitzone berücksichtigen in einer long Variable. 😱
 
Also ich hab's jetzt mit einem Stringvergleich gelöst. Das mit dem Datum bzw. der Zeit ist ein Mysterium...
Wie auch immer, danke jedenfalls für die Tipps...
regards Jacl 🙂
 
Es soll über einen Spinner (die Auswahl ist eine Liste mit Zeiten) ein Zeit angegeben werden, zu der eine Meldung erscheint. Die Problemstellung ist nun eine Schleife die die eingegebene Zeit überprüft bis sie erreicht ist und anschließend die Meldung ausgibt.
 
...aber ich komme eh nicht weiter (zu wenig Erfahrung)! Den Vergleich habe ich hinbekommen, aber die Schleife will nicht. Hier mein Versuch:
Java:
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
boolean Reminder = false;
            jLabel.setText("Erinnerung läuft...");
            while (!Reminder){
                Uhrzeitaktuell = sdf.format(new Date();
                if (Uhrzeitaktuell.equals(Eingabe)){
                    Reminder = true;
                }
            }
        JOptionPane.showMessageDialog(null, "Erinnerung...", "ErinnerungsAlert!", JOptionPane.WARNING_MESSAGE);
jLabel.setText("");
Die Liste im Spinner zur Auswahl: 07:00, 07:05, 07:10 usw. usf...
Bevor die Schleife aufgerufen wird prüfe ich noch ob die Eingabe kleiner als die aktuelle Uhrzeit ist (die Erinnerung soll immer in der Zukunft liegen!)...
Irgendwie läuft die Schleife aber nicht. Suche nach einer einfachen Lösung, bin da noch am Werken...
Jacl
 
Bitte halte Dich an die Java-Konvention, Bezeichner für Variablen, Parameter und Methoden in lowerCamelCase zu schreiben.

So etwas:
Java:
if (Uhrzeitaktuell.equals(Eingabe)){
    Reminder = true;
}
ist unsinnig, denn equals liefert bereits true/false. Du brauchst also nur
Java:
Reminder = Uhrzeitaktuell.equals(Eingabe);
zu verwenden.

Warum sollte die Schleife nicht "laufen"? Liegt es evtl. daran:

Bevor die Schleife aufgerufen wird prüfe ich noch ob die Eingabe kleiner als die aktuelle Uhrzeit ist (die Erinnerung soll immer in der Zukunft liegen!)

Wie prüfst Du das denn ab?

Nachtrag: stell Dich schon mal darauf ein, dass es komplizierter wird 🙂
 
...also vor der obigen Schleife mach ich die Abfrage:
Java:
if(eingabeminuten <= aktuellZeitminuten){
            jLabel.setText("Erinnerungszeit liegt in der Vergangenheit!");
        }
        else{
          boolean reminder = false;
            jLabel.setText("Erinnerung läuft...");
            while (!reminder){
                uhrzeitaktuell = sdf.format(new Date());
                reminder = uhrzeitaktuell.equals(eingabe);
            }
            JOptionPane.showMessageDialog(null, "Erinnerung...", "ErinnerungsAlert!", JOptionPane.WARNING_MESSAGE);
            jLabel.setText("");
        }
Die eingabeminuten und aktuellZeitminuten werden mit
Java:
//Auswahl vom Spinner holen
String eingabe = jSpinner.getValue().toString();
        String [] eingabesplit = eingabe.split(":");
        int ehours = Integer.parseInt(eingabesplit[0]);
        int eminutes = Integer.parseInt(eingabesplit[1]);     
        //Eingabe in Minuten umwandeln
        int eingabeminuten = (ehours * 60) + eminutes;
und
Java:
//Aktuelle Uhrzeit einlesen
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
        String uhrzeitaktuell = sdf.format(new Date());
        String [] zeitsplit = uhrzeitaktuell.split(":");
        int zhours = Integer.parseInt(zeitsplit[0]);
        int zminutes = Integer.parseInt(zeitsplit[1]);
        //Aktuelle Zeit in Minuten umwandeln
        int aktuellZeitminuten = (zhours * 60) + zminutes;
Die Umwandlung in Minuten erleichtert die if-else Abfrage, jedoch kommt meine Schleife immer nur bis zum if, den else-Zweig mag sie nicht, keine Ahnung wieso...
Jacl
 
...ich hab's geschafft. Folgender Code war die Lösung bei der auch noch andere Eingaben gemacht werden können da ein eigener Thread:
Java:
new Thread() {
  @Override public void run() {
    try {
      Thread.sleep( eingabezeit - aktuellezeit in Millisekunden );
      JOptionPane.showMessageDialog(null, "Erinnerung...", "ErinnerungsAlert!", JOptionPane.WARNING_MESSAGE);
    } catch ( InterruptedException e ) { e.printStackTrace(); }
  }
}.start();
Beharrlichkeit zahlt sich aus - noch einmal vielen Dank für die Tipps und Verbesserungsvorschläge.
Jacl 😀
 
Schön, dass Du die Sache mit dem Thread gleich gefunden hast 🙂

Du kannst auch einen Timer oder einen ExecutorService verwenden.
 
Yep, aber soweit bin ich noch nicht. Habe noch nicht soviel Erfahrung...
Freue mich mal über den ersten Erfolg, Habe eh schon wieder eine Idee, mal schauen. Werde mich sicher wieder melden und euch nerven...
Jacl 😉
 
Java:
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import java.util.Calendar;
import java.util.Date;
import java.util.Optional;
import java.util.concurrent.*;
import java.time.LocalTime;
import java.time.temporal.ChronoUnit;

import javax.swing.*;
import javax.swing.text.DateFormatter;


public class Test {
    private final ScheduledExecutorService scheduler =
            Executors.newScheduledThreadPool(1);

    private Optional<ScheduledFuture<?>> future = Optional.empty();

    private Runnable action = new Runnable() {
        @Override
        public void run() {
            JOptionPane.showMessageDialog(null, "Alarm!");
        }
    };

    // s. https://stackoverflow.com/questions/21960236/jspinner-time-picker-model-editing
    private JSpinner withTimeEditor(JSpinner spinner) {
        JSpinner.DateEditor editor = new JSpinner.DateEditor(spinner, "HH:mm");
        DateFormatter formatter = (DateFormatter)
                editor.getTextField().getFormatter();
        formatter.setAllowsInvalid(false);
        formatter.setOverwriteMode(true);
        spinner.setEditor(editor);
        return spinner;
    }

    private LocalTime toLocalTime(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return LocalTime.of(cal.get(Calendar.HOUR_OF_DAY),
                cal.get(Calendar.MINUTE));
    }

    private void setAlarm(Date date, Runnable action) {
        if (future.filter(f -> !f.isDone()).isPresent()) {
            JOptionPane.showMessageDialog(null, "Alarm bereits gesetzt");
            return;
        }

        LocalTime time = toLocalTime(date);
        LocalTime now = LocalTime.now();

        if (!time.isAfter(now)) {
            JOptionPane.showMessageDialog(null, "Zeit muss in Zukunft liegen");
            return;
        }

        long seconds = now.until(time, ChronoUnit.SECONDS) + 1;
        future = Optional.of(scheduler
            .schedule(action, seconds, TimeUnit.SECONDS));
        JOptionPane.showMessageDialog(null, "Alarm gesetzt");
    }

    public void run() {
        final SpinnerDateModel model = new SpinnerDateModel();
        JSpinner time = withTimeEditor(new JSpinner(model));
        JButton button = new JButton("Set alarm");
        button.addActionListener(e -> setAlarm(model.getDate(), action));
        JPanel panel = new JPanel();
        panel.add(time);
        panel.add(button);
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosed(WindowEvent e) {
                scheduler.shutdownNow();
            }
        });
        frame.add(panel);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new Test().run());
    }
}
 

Zurück
Oben