2014-12-06 100 views
0

我用这个方法来分钟转换成时间(HH:MM:SS)的Java定时器倒计时的JTable

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; 

} 

的时候会返回一个字符串,然后我将它张贴到一个JTable中, jTable有超过100个应该倒计时的定时器,我想如果系统时间增加1秒,所有定时器应该减少1秒。

有帮助吗?谢谢

+0

看http://stackoverflow.com/questions/14393423/how-to-make-a-countdown-timer-in-java – pmverma 2014-12-09 11:50:46

+0

我不认为你可以使用这个功能,既然你有把秒递减0.1并且不会给出正确的结果 – MihaiC 2014-12-09 12:06:16

回答

2

编辑显示如何根据时间为单元着色的示例,如果剩余时间少于或等于五分钟,则单元格变为红色。


首先,您需要创建一个自定义渲染器类,它将被您的表使用。这个类将包含逻辑单元的着色,eighter红色,或默认的白色:

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; 
    } 
} 

接下来,你需要告诉你的表使用这个新的自定义渲染:

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()); 
    } 

就是这样!现在单元格会变红或不取决于时间。

我编辑了原来的答复与此修改,您可以测试并运行下面的代码:


适应这个您的需求。

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(); 
      } 
     }); 
    } 
} 
+0

非常感谢你MihaiC,这是正确和最简单的答案,但是我遇到了很多问题,因为我使用了2个jtable(1-选择时间。 2)显示计时器),我正在使用行监听器,点击行然后显示计时器。 – 2014-12-12 11:13:03

+0

我正在使用(ListSelectionListener),问题在这里,timer.PassTheTime(row,col,(int)time); 一切都很好,直到我到该行则显示很像错误, 异常在线程“AWT-EventQueue的-0”显示java.lang.NullPointerException \t在test.RowListener.displayTime(NewJFrame.java:662) \t at test.RowListener.valueChanged(NewJFrame.java:456) 有太多错误 – 2014-12-12 20:42:42

+0

通过使用此代码修复了该问题,而不是使用“while(initialSeconds> = 0)”我使用此代码“while(index == MainApp.jTable.getSelectedRow()&& initialSeconds> = 0)“我在开始时通过了选定的索引,因此对我有用,仍然修复了一些问题,非常感谢 – 2014-12-13 05:09:04