0

I'm using this method to convert minutes into time (hh:mm:ss)

public static String time(double m){


    double t = m;
    int hours = (int)t / 60;
    int minutes = (int)t % 60;
    double seconds = (t - Math.floor(t)) * 60;
    System.out.println(seconds);
    if (seconds > 59){
        seconds = 00;
        minutes++;
    }
    String myFormat = seconds >= 10 ? "%d:%02d:%.0f" : "%d:%02d:%.0f";
    String time = String.format(myFormat, hours, minutes, seconds);

    return time;

}

the time will return as a string, then I will post it into a jTable, the jTable has more than 100 timers that should countdown too, I am thinking about if the system time increased 1 second all timers should decreased 1 second.

any help? thank you

abdulla-alajmi
  • 491
  • 1
  • 9
  • 17
  • Look at http://stackoverflow.com/questions/14393423/how-to-make-a-countdown-timer-in-java – pmverma Dec 09 '14 at 11:50
  • I don't think you can use this function, since you have to decrement the seconds by 0.1 and that won't give a proper result – MihaiC Dec 09 '14 at 12:06

1 Answers1

2

EDIT Shows example of how to color cells based on the time, if time remaining is less or equal to five minutes, the cell becomes red.


First, you need to create a custom renderer class, which will be used by your table. This class will contain the logic for coloring of cells, eighter red, or default white:

static class CustomRenderer extends DefaultTableCellRenderer {

    @SuppressWarnings("compatibility:-3065188367147843914")
    private static final long serialVersionUID = 1L;

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
            boolean hasFocus, int row, int column) {
        Component cellComponent
                = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); //get the current cell component
        //get the time as String from the current cell at position (row,column)
        //if the string value of time is less than the string representing 5 minutes color it red, else white. 
        //Because of lexicographic alphabet sorting, we can compare the strings correctly like this
        String time = (String) table.getValueAt(row, column);
        if (time!=null && time.compareTo("00:05:00") <= 0) {
            cellComponent.setBackground(Color.RED);
        } else {
            cellComponent.setBackground(Color.WHITE);
        }
        return cellComponent;
    }
}

Next, you need to tell your table to use this new custom renderer:

    tableModel = new DefaultTableModel(rowData, columnNames);
    table = new JTable(tableModel);
    int columnCount = table.getColumnModel().getColumnCount(); //get number of columns
    //for each column apply the custom rendered
    for (int i = 0; i < columnCount; i++) {
        table.getColumnModel().getColumn(i).setCellRenderer(new CustomRenderer());
    }

And that's it! Now the cells will be red or not depending on the time.

I edited the original answer with this modification, you can test and run the code below:


Adapt this to your needs.

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;

public class Timer {

    static class CustomRenderer extends DefaultTableCellRenderer {

        @SuppressWarnings("compatibility:-3065188367147843914")
        private static final long serialVersionUID = 1L;

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
                boolean hasFocus, int row, int column) {
            Component cellComponent
                    = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
            String time = (String) table.getValueAt(row, column);
            if (time!=null && time.compareTo("00:05:00") <= 0) {
                cellComponent.setBackground(Color.RED);
            } else {
                cellComponent.setBackground(Color.WHITE);
            }
            return cellComponent;
        }
    }

    class PassTime extends Thread {

        private int initialSeconds;
        private final int row;
        private final int column;

        public PassTime(int row, int column, int initialSeconds) {
            this.initialSeconds = initialSeconds;
            this.row = row;
            this.column = column;
        }

        @Override
        @SuppressWarnings("SleepWhileInLoop")
        public void run() {
            while (initialSeconds >= 0) { //while we can countdown
                try {
                    //set the new value in the row/column position in the matrix
                    ((DefaultTableModel) table.getModel()).setValueAt(getTime(initialSeconds), row, column);
                    //let the table know it's data has been modified
                    ((DefaultTableModel) table.getModel()).fireTableDataChanged();
                    Thread.sleep(1000); //wait 1 second
                    initialSeconds--; //decrement seconds by 1
                } catch (InterruptedException e) {
                    System.out.println(e.getMessage());
                }
            }
        }
    }

    public void PassTheTime(int row, int column, int time) {
        PassTime timer = new PassTime(row, column, time);
        timer.start();
    }

    static Object[] columnNames = new Object[]{"Time 1", "Time 2"}; //table header
    static String[][] rowData = new String[2][2]; //only a 2 by 2 matrix in this example
    private final JPanel mainPanel = new JPanel();
    private final DefaultTableModel tableModel;
    private final JTable table;

    //method to get time from seconds as hh:mm:ss
    public static String getTime(int totalSecs) {
        int hours = totalSecs / 3600;
        int minutes = (totalSecs % 3600) / 60;
        int seconds = totalSecs % 60;
        String timeString = String.format("%02d:%02d:%02d", hours, minutes, seconds);
        return timeString;
    }

    public Timer() {
        tableModel = new DefaultTableModel(rowData, columnNames);
        table = new JTable(tableModel);
        int columnCount = table.getColumnModel().getColumnCount();
        for (int i = 0; i < columnCount; i++) {
            table.getColumnModel().getColumn(i).setCellRenderer(new CustomRenderer());
        }
        mainPanel.setLayout(new BorderLayout());
        mainPanel.add(new JScrollPane(table), BorderLayout.CENTER);
    }

    public JPanel getMainPanel() {
        return mainPanel;
    }

    private static void createAndShowGui() {
        final Timer timer = new Timer();

        JFrame frame = new JFrame("Timer");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(timer.getMainPanel());
        frame.pack();
        frame.setSize(200, 200);
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowOpened(WindowEvent e) {
                //start each timer
                //pass row,column position in the matrix for each Time and the seconds value
                timer.PassTheTime(0, 0, 302);
                timer.PassTheTime(0, 1, 320);
                timer.PassTheTime(1, 0, 310);
                timer.PassTheTime(1, 1, 420);

            }
        });
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                createAndShowGui();
            }
        });
    }
}
MihaiC
  • 1,618
  • 1
  • 10
  • 14
  • thank you so much MihaiC, this is the correct and easiest answer but I got a lot of problems because I'm using 2 jtables ( 1- pick the time. 2- display the timers ) and I am getting the time using the row listener, by clicking on the row then display timers. – abdulla-alajmi Dec 12 '14 at 11:13
  • I am using (ListSelectionListener) and the problem is here, timer.PassTheTime(row, col, (int) time); everything is good until I get to that line then display a lot of errors like, Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException at test.RowListener.displayTime(NewJFrame.java:662) at test.RowListener.valueChanged(NewJFrame.java:456) there are too many errors – abdulla-alajmi Dec 12 '14 at 20:42
  • fixed that problem by using this code, instead of using " while (initialSeconds >= 0)" I used this code "while ( index == MainApp.jTable.getSelectedRow() && initialSeconds >= 0)" I passed the selected index at the beginning so that worked for me, still fixing some problems, thanks a lot – abdulla-alajmi Dec 13 '14 at 05:09
  • another simple question, how can I change the cell color to red if the time is less than 5 minutes? – abdulla-alajmi Dec 13 '14 at 11:27
  • thank you so much, I don't know how to use it so I would like to get an example please, thank you MihaiC – abdulla-alajmi Dec 14 '14 at 05:22
  • @user2564147 i edited the answer with an example. hope it helps – MihaiC Dec 15 '14 at 07:36
  • I made some editing and it's working, thank you so much MihaiC you are awesome, I wish I have like your experience :) – abdulla-alajmi Dec 15 '14 at 22:21
  • @user2564147 no problem. Glad you got your project working! Keep working and learning and you will one day have same experience. It's all up to you :) – MihaiC Dec 16 '14 at 09:29