0

I need to set a specific time in JTextfield format (HH:mm:ss). And I need to set the initialDelay which will be the time after I pressed the button "Start" and time specified in JTextField. After the time is passed, it will be opened a new JFrame.

I have tied to parse the String into date (HH:mm:ss) and calculate the difference between specified time and local time.

 private void startButtonActionPerformed(java.awt.event.ActionEvent evt) {                                            
       if(evt.getActionCommand().equals("Start")){

          if(onTime.isSelected()){

                  String time1= onTimeTextfiled.getText();
                  LocalTime localTime = LocalTime.parse(time1, DateTimeFormatter.ofPattern("HH:mm:ss"));

                  LocalTime loc = LocalTime.now();
                  if(localTime.compareTo(loc)==0){
                        frame2.setSize(600,800);
                        frame2.setVisible(true);

                  }

          }
Bartosz Konieczny
  • 1,985
  • 12
  • 27
  • I need some clarifications. Do you want a button which opens a new window ? Or do you want the second window only after a delay ? What do you want to show on the second window ? Post [mre] and not just a snippet. – c0der Aug 17 '19 at 12:10
  • I want to set the timer at a specific time (HH:mm:ss) format. Yes a second window after a delay between pressing the button start and specified time. – Marcel Gaina Aug 17 '19 at 12:34
  • 1. To get time input consider using 3 [JSpinner](http://download.oracle.com/javase/6/docs/api/javax/swing/JSpinner.html) objects (hours, minutes, seconds) each wirh with a [SpinnerNumberModel](http://docs.oracle.com/javase/6/docs/api/javax/swing/SpinnerNumberModel.html) 2. To fire an action after a delay use a [swing timer](https://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html) 3. As second window use [JDialog](https://stackoverflow.com/questions/9554636/the-use-of-multiple-jframes-good-or-bad-practice) 4. For more help post mre. – c0der Aug 17 '19 at 12:51

2 Answers2

1

Using a JTextField to parse a date format doesn't sound great because the risk of a parse exception will be high. I suggest you to use another component(s), or try to find some external date/time pickers. However, nothing stops you from using java.time API in order to parse the date, calculate the delay and create the timer.

I have created an example:

public class Example extends JFrame {
    private static final long serialVersionUID = 1L;
    private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss");
    private Timer timer;

    public Example() {
        super("test");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLayout(new FlowLayout());

        JTextField field = new JTextField(10);
        add(field);

        JButton startTimer = new JButton("Start");
        startTimer.addActionListener(e -> {
            try {
                LocalTime selectedTime = LocalTime.parse(field.getText(), formatter);
                LocalDateTime selectedDate = LocalDateTime.now().toLocalDate().atStartOfDay();
                selectedDate = selectedDate.plusHours(selectedTime.getHour()).plusMinutes(selectedTime.getMinute())
                        .plusSeconds(selectedTime.getSecond());
                // Check if time has passed and should be scheduled for tomorrow
                if (selectedDate.isBefore(LocalDateTime.now())) {
                    selectedDate = selectedDate.plusDays(1);
                }
                long date = Timestamp.valueOf(selectedDate).getTime();
                long delay = date - System.currentTimeMillis();
                timer = new Timer((int) delay, e1 -> {
                    JOptionPane.showMessageDialog(null, "Time passed.");
                });
                timer.setRepeats(false);
                timer.start();
                System.out.println("Timer started and scheduled at: " + selectedDate);
            } catch (DateTimeParseException e1) {
                JOptionPane.showMessageDialog(null, "Cannot parse date.");
                System.out.println(e1);
            }
        });
        add(startTimer);

        setSize(300, 300);
        setLocationRelativeTo(null);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            new Example().setVisible(true);
        });
    }
}
George Z.
  • 6,643
  • 4
  • 27
  • 47
0

Using JSpinners for time input is simple enough and makes the implementation more robust.
The following example is a one-file MRE (copy and paste the entire code into SwingTest.java and run):

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.Timer;

public class SwingTest extends JFrame {

    public SwingTest()  {
        getContentPane().add(new MainPanel());
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        pack();
        setVisible(true);
    }

    public static void main(String[] args) {
        new SwingTest();
    }
}

class MainPanel extends JPanel{

    private final Timer timer;

    MainPanel() {
        setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
        setLayout(new BorderLayout(10,10));
        TimePanel tp = new TimePanel();
        add(tp);
        JButton btn = new JButton("Open a window at selected time");
        btn.addActionListener(e -> processTime(tp.getTime()));
        add(btn, BorderLayout.PAGE_END);
        timer = new Timer(0, e->openNewWindow());
        timer.setRepeats(false);
    }

    private void processTime(LocalTime time) {

        if(time == null || timer.isRunning()) return;
        LocalTime now = LocalTime.now();

        long delayInSeconds = ChronoUnit.SECONDS.between(now, time);

        if (delayInSeconds < 0) {   //if time is before now
            delayInSeconds += 1440; //add 24X60 seconds
        }

        System.out.println("opening a window in "+ delayInSeconds + " seconds");
        timer.setInitialDelay((int) (delayInSeconds * 1000));
        timer.start();
    }

    private void openNewWindow() {
        timer.stop();
        JOptionPane.showMessageDialog(this, "New Window Opened !");
    }
}

class TimePanel extends JPanel {

    JSpinner hours, minutes, secconds;

    TimePanel() {

        hours = new JSpinner(new SpinnerNumberModel(12, 0, 24, 01));
        minutes = new JSpinner(new SpinnerNumberModel(0, 0, 60, 01));
        secconds = new JSpinner(new SpinnerNumberModel(0, 0, 60, 01));

        setLayout(new GridLayout(1, 3, 10, 10));
        add(hours);
        add(minutes);
        add(secconds);
    }

    LocalTime getTime(){

        String h = String.valueOf(hours.getValue());
        String m = String.valueOf(minutes.getValue());
        String s = String.valueOf(secconds.getValue());
       StringBuilder time = new StringBuilder();
       time.append(h.length() < 2 ? 0+h: h).append(":")
           .append(m.length() < 2 ? 0+m: m).append(":")
           .append(s.length() < 2 ? 0+s: s);
       System.out.println(time.toString());
       return LocalTime.parse(time.toString(), DateTimeFormatter.ofPattern("HH:mm:ss"));
    }
}

enter image description here

c0der
  • 18,467
  • 6
  • 33
  • 65