0

I want to take the difference between the changed value and the curent date of the spinnerdatemodel as the delay for the timer. This is the JSpinner:

Calendar cal = Calendar.getInstance();
cal.add(Calendar.YEAR, 5);
Date max = cal.getTime();
SpinnerDateModel sdm = new SpinnerDateModel(cal.getTime(),null, max,Calendar.HOUR_OF_DAY);
jSpinner1 = new javax.swing.JSpinner(sdm);
jSpinner1 .setEditor(new JSpinner.DateEditor(jSpinner1 , "hh:mm:ss"));

This is the code that I tried but is not working:

jSpinner1.addChangeListener(new ChangeListener() {
                    @Override
                    public void stateChanged(ChangeEvent e) {
                    JSpinner jSpinner = (JSpinner)e.getSource();
                    Date time = (Date) jSpinner.getValue();

         if(jCheckBox1.isSelected())
         {     
                delay = 1000 * (int) time.getTime();

         }
         }
                                            });
 timer = new Timer(delay, new ActionListener() {

         @Override
         public void actionPerformed(ActionEvent evt) {

            f.getContentPane().setBackground(c);

                                                      }               

        });

All I want is to change the color of a frame background in a specific determined time. Any help will be extremely apreciated.

EDIT:

Image

I click the "on time" checkbox and I change the value from the SpinnerDateModel. After all this, when I press start the timer will fire with the delay from the SpinnerDateModel executing the task of changing a frame`s color.

My code just changes the color imediatly I press start, wtihout the delay.

trashgod
  • 203,806
  • 29
  • 246
  • 1,045
M. MaRiuS
  • 1
  • 2
  • 1
    For better help sooner, post a [MCVE] or [Short, Self Contained, Correct Example](http://www.sscce.org/). – Andrew Thompson Jun 30 '16 at 07:32
  • 1
    *".. is not working:"* How does it fail? Specifically? BTW - Use a logical and consistent form of indenting code lines and blocks. The indentation is intended to make the flow of the code easier to follow! – Andrew Thompson Jun 30 '16 at 07:33
  • 1
    Your initial delay is thousands of years in the future! – trashgod Jun 30 '16 at 10:09
  • I edited my question and added a picture, hopefully it will explain better what I exactly want :) – M. MaRiuS Jun 30 '16 at 15:44

1 Answers1

3

Your initial delay is thousands of years in the future. Instead,

  • Subtract the current time from spinner's value to get a delay.

  • Reset the timer's initial delay to the calculated delay value.

  • Invoke restart() to make the timer fire with the new initial delay.

The example below increments by Calendar.SECOND for easier to testing.

image

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Calendar;
import java.util.Date;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerDateModel;
import javax.swing.Timer;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

/**
 * @see http://stackoverflow.com/a/38120036/230513
 */
public class Test {

    private void display() {
        JFrame f = new JFrame("Test");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Calendar cal = Calendar.getInstance();
        SpinnerDateModel sdm = new SpinnerDateModel(cal.getTime(), null, null, Calendar.SECOND);
        JSpinner spinner = new JSpinner(sdm);
        spinner.setEditor(new JSpinner.DateEditor(spinner, "yyyy-MM-dd hh:mm:ss"));
        JPanel p = new JPanel();
        p.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
        p.add(spinner);
        f.add(p);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
        Timer timer = new Timer(Integer.MAX_VALUE, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent evt) {
                p.setBackground(Color.getHSBColor((float) Math.random(), 1, 1));
            }
        });
        spinner.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                JSpinner jSpinner = (JSpinner) e.getSource();
                Date date = (Date) jSpinner.getValue();
                long delay = date.getTime() - System.currentTimeMillis();
                if (delay > 0) {
                    timer.setInitialDelay((int) delay);
                    timer.restart();
                }
            }
        });
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Test()::display);
    }
}
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • I edited my question and added a picture, hopefully it will explain better what I exactly want :) – M. MaRiuS Jun 30 '16 at 15:43
  • Please edit your question to include a [mcve] that shows your current approach; use my example as a starting point. – trashgod Jun 30 '16 at 16:04