Pergunta

Um tempo contador mostra a idade em segundos de uma linha na tabela. Idealmente, seria atualizado uma vez por segundo. Eu sei que eu posso simplesmente incrementar os dados apropriados no modelo de mesa, disparar os eventos (um por linha), etc. Parece um exagero! Existe uma maneira melhor, mais leve?

Foi útil?

Solução

O que você precisa é:

  • uma maneira de modelar a 'idade' da linha em seu modelo de mesa. Este é o melhor feito implicitamente, para que apenas armazenar o tempo de criação da linha uma vez e calcular a idade em que o valor da célula é solicitado (Object getValueAt (linha, coluna)).
  • A (daemon) discussão que dispara o evento de alteração de tabela a cada segundo. Você não tem que fogo um evento por linha, mas em vez disso você pode disparar um evento que sinais de uma atualização de coluna inteira.

Eis alguns pseudocódigo para o modelo de tabela:

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 
}

O modelo de tabela deve, em seguida, também oferecem um método para o segmento, para que ele possa disparar um evento de alteração para a 'idade row' coluna:

classe pública MyTableModel implementos 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);
          }
   }

O fio teria então apenas desencadear o método updateColumn (..), cada segundo para o 'idade fileira' coluna. A invocação de este método deve ser feito no EventDispatchThread, isto é feito usando SwingUtilities.invokeAndWait (..) ou 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();

Enquanto a granularidade do TableModelEvent cobre apenas as células que precisam ser atualizados (no seu caso: apenas a coluna com a idade linha)., É a forma mais eficiente para realizar este

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top