IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Composants Java Discussion :

Lag et performances de rafraichissement d'une JTable


Sujet :

Composants Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    9
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juin 2006
    Messages : 9
    Par défaut Lag et performances de rafraichissement d'une JTable
    Bonjour,

    J'ai actuellement des lags lorsque je rafraichit ma JTable et je ne trouve pas de solutions à ce problème.

    Contexte: J'ai une JTable de 12 colonnes et 10 lignes. Je souhaite updater certaines de ces lignes sur des évènements extérieurs. Donc pour ce faire j'appelle à partir de mon TableModel (et dans le thread graphique via SwingUtilities.invokeLater) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    log.debug("fireTableRowsUpdated("+row+")");
    fireTableRowsUpdated(row, row);
    Tout se passe bien et la JTable se met correctement à jour. L'inconvénient c'est que de temps en temps je reçoit beaucoup de notifications (environ 1000 à la seconde pendant une dizaine de minutes). C'est à ce moment que mon appli commence à lagger. La souris se déplace correctement à l'écran mais lorsque je clic sur une ligne il lui faut une seconde pour sélectionner la ligne (et beaucoup plus de temps au bout de 5 minutes).

    Ma première solution a été de remplacer le fireTableRowsUpdated par des fireTableCellUpdated car je n'ai pas toujours besoin d'updater les 12 colonnes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    log.debug("fireTableRowsUpdated("+row+")");
    fireTableCellUpdated(row, 7);
    fireTableCellUpdated(row, 8);
    fireTableCellUpdated(row, 9);
    fireTableCellUpdated(row, 11);
    Cette solution m'a l'air d'améliorer légèrement la situation mais ce n'est pas suffisant car le lag est toujours visible.

    Personnellement, c'est la première fois que j'ai besoin de rafraichir aussi souvent une JTable donc je ne sais pas vraiment comment faire ni même si une JTable peut supporter autant (1000 events par seconde).

    Avez-vous des solutions, idées ou piste à creuser?

  2. #2
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,


    Il faudrait plus d'info, notamment :
    • Comment tu reçois ces notifications ?
    • Comment tu passes les nouvelles données au TableModel ? Tu utilises le DefaultTableModel ou un modèle perso (dans ce cas il nous faudrait le code) ?



    Ensuite je pense qu'une solution serait de ne pas forcément mettre à jour immédiatement les données, en regroupant cela toutes les x millisecondes (ou secondes) selon tes besoins (je ne pense pas que tu ai réellement besoin d'avoir 1000 rafraichissement par seconde dans une JTable)


    a++

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    9
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juin 2006
    Messages : 9
    Par défaut
    Merci pour ta réponse adiGuba.

    En gros il s'agit d'une application client-serveur. Le serveur me notifie de changements sur mes données et je les updates dans la JTable.
    J'ai un manager (sur lequel s'enregistrent tous les TableModels de ce type) qui reçoit les données du serveur, les filtre si nécessaire et les envoie ensuite aux différents TableModel pour que ceux-ci updatent la JTable.

    Le TableModel est custom mais assez simpliste. En gros, cela donne:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
     
    public class MyTableModel extends AbstractTableModel implements ManagerListener {
     
     private static final Logger log = LoggerFactory.getLogger(MyTableModel.class);
     private List<Datar> orders = Lists.newArrayList();
     
      @Override
      public void updateData(final Data data, final DataUpdateEventType eventType) {
        // Should be done in EDT
        SwingUtilities.invokeLater(new Runnable() {
          @Override
          public void run() {
            int row = orders.indexOf(order);
            if (row < 0) {
              return;
            }
     
            log.debug("orderUpdated: fireTableRowsUpdated({}, {}) for data: {}", new Object[]{row, row, data});
            //        fireTableRowsUpdated(index, index);
     
            switch (eventType) {
              case Ack:
                fireTableCellUpdated(row, 7); 
                fireTableCellUpdated(row, 10); 
                break;
     
              case Deleted:
                fireTableCellUpdated(row, 7);
                break;
     
              case Nack:
                fireTableCellUpdated(row, 7);
                fireTableCellUpdated(row, 8);
                fireTableCellUpdated(row, 9);
                fireTableCellUpdated(row, 11);
                break;
     
              case Scheduled:
                fireTableCellUpdated(row, 7);
                fireTableCellUpdated(row, 8);
                fireTableCellUpdated(row, 9);
                break;
     
              case Update:
                fireTableCellUpdated(row, 5);
                fireTableCellUpdated(row, 6);
                break;
     
              default:
                log.error("orderUpdated: Can not update row[{}] because [{}] is an invalid event type", row, eventType);
                break;
            }
          }
        });
      }
    }
    Effectivement, je n'ai pas besoin de mettre à jour la JTable 1000 fois par seconde. L'utilisateur n'a pas le temps de percevoir autant de changements.
    J'imagine qu'en enregistrant les notifications d'update dans une map (rowIndex en clé et EventType en valeur) avec un timer qui la vide toutes les 100 ms cela devrait suffire. Qu'en pense-tu?

  4. #4
    Membre Expert Avatar de herve91
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    1 282
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 282
    Par défaut
    Tu peux utiliser une map en faisant en sorte de notifier une seule fois les mises à jour sur une même cellule :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    Map<Integer, Set<Integer>> mapUpdatedCells = new HashMap<Integer, Set<Integer>>();
     
    public void addCellUpdateEvent(int row, int column) {
    	Set<Integer> columns = mapUpdatedCells.get(row);
    	if (columns == null) {
    		columns = new HashSet<Integer>();
    		mapUpdatedCells.put(row, columns);
    	}
    	columns.add(column);
    }
     
    // ActionListener du timer 
    public void actionPerformed() {
    	for (Entry<Integer, Set<Integer>> entry : mapUpdatedCells.entrySet()) {
    		int row = entry.getKey();
    		for (int column : entry.getValue()) {
    			fireTableCellUpdated(row, column);
    		}
    	}
    	mapUpdatedCells.clear();
    }

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    9
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juin 2006
    Messages : 9
    Par défaut
    Merci pour vos réponses

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème de rafraichissement de JRadioButton dans une JTable
    Par domas_24 dans le forum Agents de placement/Fenêtres
    Réponses: 2
    Dernier message: 18/05/2012, 15h35
  2. Rafraichissement d'une JTable
    Par Dark_TeToN dans le forum Composants
    Réponses: 2
    Dernier message: 20/10/2010, 15h25
  3. focus dans une cellule d'une JTable
    Par coil dans le forum Composants
    Réponses: 5
    Dernier message: 07/07/2010, 17h15
  4. Réponses: 4
    Dernier message: 24/08/2007, 16h44
  5. Rafraichissement d'une JTable
    Par parano dans le forum Composants
    Réponses: 3
    Dernier message: 06/07/2007, 23h52

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo