Eine effiziente Möglichkeit, einen Zeitzähler in einer JTable Zelle anzuzeigen

StackOverflow https://stackoverflow.com/questions/609492

  •  03-07-2019
  •  | 
  •  

Frage

ein Zeitzähler zeigt die Zeit, in Sekunden, von einer Zeile in der Tabelle. Idealerweise wäre es einmal pro Sekunde aktualisiert. Ich weiß, ich kann nur die entsprechenden Daten in der Tabelle Modell erhöhen, feuert die Ereignisse (eine pro Zeile), etc. Es scheint übertrieben! Gibt es eine bessere, leichtere Art und Weise?

War es hilfreich?

Lösung

Was Sie brauchen, ist:

  • eine Möglichkeit, das ‚Alter‘ der Zeile in der Tabelle Modell Modell. Dies geschieht am besten implizit getan, so dass Sie nur einmal die Erstellungszeit der Zeile speichern und das Alter berechnen, wenn der Zellenwert angefordert wird (Objekt getValueAt (Zeile, Spalte)).
  • A (Daemon) Threads, das Tabellenänderungsereignis pro Sekunde abfeuert. Sie müssen nicht pro Zeile ein Ereignis ausgelöst haben, sondern können Sie ein Ereignis ausgelöst, die eine ganze Spalte Update signalisiert.

Hier einig Pseudo-Code für das Tischmodell:

public Object getValueAt (int rowIndex, int columnIndex) {

    // if it's the column with the 'row age', calculate the age and return it
    long rowAgeMs = System.currentTimeMs() - getCreationTime(rowIndex);

   // return the age in milliseconds, or a date, or a formatted time string 
}

Das Tischmodell sollte dann bieten auch ein Verfahren für den Faden, so kann es ein Änderungsereignis für die ‚Reihe Alter‘ Spalte Feuer:

public class MyTableModel implementiert Tablemodel {

   private final List<TableModelListener> listeners = new LinkedList<TableModelListener>();

   public void addTableModelListener (TableModelListener l) {
          listeners.add(l);
   }

   public void removeTableModelListener (TableModelListener l) {
          listeners.remove(l);
   }

   public void updateColumn (int column) {
          TableModelEvent evt = new TableModelEvent(this, 0, Math.max(0, getRowCount() - 1), column);
          for (TableModelListener listener : listeners) {
                 listener.tableChanged(evt);
          }
   }

Der Faden würde dann die gerade triggern updateColumn (..) Methode jede Sekunde für die Spalte ‚Zeilen Alter‘. Der Aufruf dieser Methode sollte in der EventDispatchThread erfolgen, wird dies mit SwingUtilities.invokeAndWait getan (..) oder SwingUtilities.invokeLater (..).

Thread rowAgeUpdater = new Thread() {

        @Override
        public void run () {
            while (isAlive()) {
                try {

                    long time = System.currentTimeMillis();
                    long sleepTime = (time / 1000 + 1) * 1000 - time;
                    Thread.sleep(sleepTime);

                    SwingUtilities.invokeAndWait(new Runnable() {
                        public void run () {
                            model.updateColumn(ROW_AGE_COLUMN_INDEX);
                        }
                    });

                } catch (Exception e) {
                    return;
                }

            }
        }
    };
    rowAgeUpdater.setDaemon(true);
    rowAgeUpdater.setPriority(Thread.MIN_PRIORITY);
    rowAgeUpdater.start();

Solange die Granularität des TableModelEvent nur die Zellen umfasst, die aktualisiert werden müssen (in Ihrem Fall: nur die Spalte mit der Reihe Alter). Es ist der effizienteste Weg, dies zu realisieren

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top