2014-12-06 50 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