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 :

Temps de chargement long (JTable)


Sujet :

Composants Java

  1. #1
    Membre confirmé Avatar de docv266
    Profil pro
    Inscrit en
    Août 2007
    Messages
    85
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 85
    Par défaut Temps de chargement long (JTable)
    Bonjour,

    J'ai une JTable qui affiche des entiers dans chacunes de ses cases.

    Elle prend ses valeur dans un vecteur qui lui se rempli à partir d'un fichier xml.

    Lorsque la table contient peu de cases (environ 20), tout marche bien.

    Lorsque le nombre de case approche des 2000, le temps de chargement est trés long, voire ça ne charge pas du tout...

    Pourtant dans le cas de 2100 cases, j'ai 30 lignes et 70 colonnes, c'est quand même pas énorme ...

    Vous pensez que je doit utiliser la classe HugeTableModel ou c'est autre chose?

    Merci d'avance.

  2. #2
    Membre Expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Par défaut
    Montre nous quelques bouts de code

  3. #3
    Membre confirmé Avatar de docv266
    Profil pro
    Inscrit en
    Août 2007
    Messages
    85
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 85
    Par défaut
    Pas de souci, alors :

    Voici le code de la partie JDOM, création de mes objets.
    En fait ça me sert à définir deux vecteurs, qui contiennent chacun les titres des lignes et des colonnes.

    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
    57
    58
    59
    60
    61
     
    public void makeTableauLigneColonne(String famillePiece, String familleEvent)
    	{
    		tableauLigne.removeAllElements();
    		tableauColonne.removeAllElements();
     
     
    		Boolean present1 = false, present2 = false;
    		for (int i=0;i<VObjet.size();i++)
    		{
    			Objet o = VObjet.get(i);
    			StringTokenizer token = new StringTokenizer(o.getDate(), "/");
    			token.nextToken();
    			int mois = Integer.parseInt(token.nextToken());
     
    			if (mois == mois_selec || mois_selec == 0)
    			{
    			if (tableauLigne.isEmpty() && (o.getFamillePiece().equals(famillePiece) || famillePiece.equals("Tout")) && (o.getFamilleEvent().equals(familleEvent) || familleEvent.equals("Tout")))
    			{
    				tableauLigne.add(o.getPiece());
    			}
    			else
    			{
    				present1 = false;
    				for (int j=0;j<tableauLigne.size();j++)
    				{
    					if (o.getPiece().equals(tableauLigne.get(j)))
    					{
    						present1=true;
    						break;
    					}
    				}
    				if (!present1 && (o.getFamillePiece().equals(famillePiece) || famillePiece.equals("Tout")) && (o.getFamilleEvent().equals(familleEvent) || familleEvent.equals("Tout")))
    				{
    					tableauLigne.add(o.getPiece());
    				}
    			}
     
    			if (tableauColonne.isEmpty() && (o.getFamillePiece().equals(famillePiece) || famillePiece.equals("Tout")) && (o.getFamilleEvent().equals(familleEvent) || familleEvent.equals("Tout")))
    			{
    				tableauColonne.add(o.getEvent());
    			}
    			else
    			{
    				present2 = false;
    				for (int j=0;j<tableauColonne.size();j++)
    				{
    					if (o.getEvent().equals(tableauColonne.get(j)))
    					{
    						present2=true;
    						break;
    					}	
    				}
    				if (!present2 && (o.getFamillePiece().equals(famillePiece) || famillePiece.equals("Tout")) && (o.getFamilleEvent().equals(familleEvent) || familleEvent.equals("Tout")))
    				{
    					tableauColonne.add(o.getEvent());
    				}
    			}
    		}
    		}
    	}

    Ensuite voici la classe de mon JPanel qui contient ma JTable :

    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
     
    model = new Model(arbre, (String)fenetre.panelHaut.piece.getSelectedItem(), (String)fenetre.panelHaut.event.getSelectedItem(), fenetre.panelHaut.mois.getSelectedIndex());
     
    		TableColumnModel cm = new DefaultTableColumnModel()
    		{
    			private static final long serialVersionUID = 968242089331222569L;
     
    			public void addColumn(TableColumn tc)
    			{
    				super.addColumn(tc);
    			}
    		};
     
     
    		table = new JTable(model, cm);
     
     
    		table.setRowSelectionAllowed(true);
    		table.setColumnSelectionAllowed(true);
     
    		table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
     
    		table.setBackground(new Color(255, 255, 255));
     
    		// redéfinition du comportement à l'affichage des cellules
    		table.setDefaultRenderer(String.class, model);
     
    		table.setAutoCreateColumnsFromModel(true);
    		table.createDefaultColumnsFromModel();
     
     
    		spane = new JScrollPane();
    		spane.setPreferredSize(new Dimension(700, 500));
    		spane.getViewport().add(table);
     
    		add(spane);
     
    		table.addMouseListener(this);
    		table.setModel(model);
    		table.revalidate();
    		table.repaint();
    		table.setVisible(true);
    		spane.setVisible(true);
    		setVisible(true);

    Et enfin le model de ma table :

    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
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
     
    public class Model extends AbstractTableModel implements TableModelListener, TableCellRenderer 
    {
     
     
    	/**
             * 
             */
    	private static final long serialVersionUID = 3961249787453440907L;
     
    	public Xml arbre;
     
    	private static Color COULEUR_LIGNE_SELECTION_SIMPLE = new Color(10, 10, 100, 50);
     
    	private static Color COULEUR_LIGNE_TITRE = new Color(10, 120, 10, 50);
     
    	public Model(Xml arbre, String famillePiece, String familleEvent, int mois_sele)
    	{
    		this.arbre = arbre;
    		this.arbre.mois_selec = mois_sele;
    		this.arbre.makeTableauLigneColonne(famillePiece, familleEvent);
    		addTableModelListener(this);
    	}
     
    	public void tableChanged(TableModelEvent e)
    	{
     
    	}
     
    	public Component getComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
    	{
    		JLabel label = new JLabel("");
    		label.setHorizontalAlignment(JLabel.CENTER);
    		label.setFont(new Font("Arial", Font.BOLD, 12));
    		label.setBackground(new Color(220, 220, 220, 100));
     
    		Component compo = null;
    		// initialisation du composant
     
    		// Composant pour afficher du texte
    		label.setText(value == null ? "" : value.toString());
    		label.setOpaque(true);
    		compo = label;
     
    		if (isSelected || hasFocus)
    		{
    			compo.setBackground(COULEUR_LIGNE_SELECTION_SIMPLE);
    		}
    		else if (column == 0)
    		{
    			compo.setBackground(COULEUR_LIGNE_TITRE);
    		}
    		else 
    		{
    			int couleur = Integer.parseInt(arbre.getValue(row, column, true));
     
    			couleur = couleur*50;
     
    			if (couleur < 0)
    			{
    				couleur = 0;
    			}
    			if (couleur > 255)
    			{
    				couleur = 255;
    			}
    			compo.setForeground(new Color(couleur,0,0,255));
    		}
     
    		String message= arbre.getValue(row, column, false);
    		((JComponent)compo).setToolTipText(message);
     
    		return compo;
    	}
     
    	public Component getTableCellRendererComponent(JTable table, Object value,	boolean isSelected, boolean hasFocus, int row, int column)
    	{
    		return getComponent(table, value, isSelected, hasFocus, row, column);
    	}
     
    	public Class<?> getColumnClass(int col)
    	{
    		return String.class;
    	}
     
    	public boolean isCellEditable(int row, int col)
    	{
    		return false;
    	}
     
    	public int getColumnCount() 
    	{
    		return arbre.getTabEvent().size()+1;
    	}
     
    	public int getRowCount() 
    	{
    		return arbre.getTabPiece().size();
    	}
     
    	public Object getValueAt(int rowIndex, int columnIndex)
    	{
    		return arbre.getValue(rowIndex, columnIndex, true);
    	}
     
    	public String getColumnName(int col)
    	{
    		if (col == 0)
    		{
    			return "Lieu";
    		}
    		else
    		{
    			return arbre.getTabEvent().get(col-1);
    		}
    	}
    }
    Je me rend compte que ça fait beaucoup...

  4. #4
    Rédacteur
    Avatar de eclesia
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    2 114
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 114
    Par défaut
    le probleme doit venir de ta classe Xml et de l'appelle a la methode getValue :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    public Object getValueAt(int rowIndex, int columnIndex){
    return arbre.getValue(rowIndex, columnIndex, true);
    }
    cette methode doit etre assez longue a executer je pense. sinon il n'y a pas de raison que ca soit long a afficher. (j'ai fait des tables avec une 20 de colonnes et quelques milliers de lignes sans lenteur particulière)

  5. #5
    Membre confirmé Avatar de docv266
    Profil pro
    Inscrit en
    Août 2007
    Messages
    85
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 85
    Par défaut
    Merci, cependant c'est pas ça.

    J'ai testé ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    public Object getValueAt(int rowIndex, int columnIndex)
    {
    return "TEST";
    }
    Et ça mets toujours autant de temps.

  6. #6
    Membre confirmé
    Inscrit en
    Avril 2006
    Messages
    130
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 130
    Par défaut
    Je vais peut-être dire une bêtise mais on sait jamais !

    Dans mon application assez lourde en traitements je vois une différence en rapidité d'exécution quand je m'applique à déclarer certains objects en dehors des boucles (même pour une simple référence).

    Exemple :

    au lieu de :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    for (int i=0;i<VObjet.size();i++)
    		{
    			Objet o = VObjet.get(i);
    			StringTokenizer token = new StringTokenizer(o.getDate(), "/");
    			token.nextToken();
    			int mois = Integer.parseInt(token.nextToken());
     [...]
    }
    tu pourrais essayer ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    StringTokenizer token;
    Objet o;
    int mois;
    for (int i=0;i<VObjet.size();i++)
    		{
    			o = VObjet.get(i);
    			token = new StringTokenizer(o.getDate(), "/");
    			token.nextToken();
    			mois = Integer.parseInt(token.nextToken());
     [...]
    }
    C'est pas grand chose, mais ça peut jouer beaucoup au final sur de gros traitements.


    EDIT : fautes

  7. #7
    Membre confirmé Avatar de docv266
    Profil pro
    Inscrit en
    Août 2007
    Messages
    85
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 85
    Par défaut
    Pourquoi pas.

    Je teste ça de suite...
    Je te tiens au courant.

  8. #8
    Membre confirmé Avatar de docv266
    Profil pro
    Inscrit en
    Août 2007
    Messages
    85
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 85
    Par défaut
    Ca marche pas.

    Pourtant ça me semblait être une trés bonne idée, en tout cas ça ne fait pas de mal.

    Une petite remarque, c'est pas la mémoire qui a du mal, en fait c'est le processeur qui est à 100% constant!

    J'ai essayé de mettre des System.out.println(); un peu partout mais je n'arrive pas a repérer le point de blocage car ils s'affichent aléatoirement!!

    Pas d'autres idées d'optimisation?

  9. #9
    Membre confirmé Avatar de docv266
    Profil pro
    Inscrit en
    Août 2007
    Messages
    85
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 85
    Par défaut
    Ah oui et aussi j'utilise pas mal la déclaration de mon curseur au sein d'une boucle for :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    for (int i=0;i<max;i++)
    {
    //...
    }
    au lieu de :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    int i;
    for (i=0;i<max;i++)
    {
    //...
    }
    C'est mal ça?

  10. #10
    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,


    Dans la plupart des cas il est inutile de faire sortir les déclarations en dehors des boucles : le compilateur et la JVM savent très bien le faire ! De plus cela permet de limiter la porté des objets...


    Le seul cas où il faut sortir un objet de la boucle, c'est lorsqu'il s'agit d'une constante qui n'est pas modifié à chaque itération.

    Exemple avec ce code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for (int i=0; i<100; i++) {
        File file1 = new File("fichier.txt");
        File file2 = new File("fichier-" + i);
    }
    La première référence (file1) devrait être déclaré avant la boucle, car cela éviterait de la recréer à chaque passage alors qu'il s'agit toujours du même objet.
    Pour la seconde, comme l'objet sera différent à chaque itération il est inutile de la déclarer en dehors de la boucle (le couple compilateur/JVM sait très bien réutiliser la référence)


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    final File file1 = new File("fichier.txt");
    for (int i=0; i<100; i++) {
        File file2 = new File("fichier-" + i);
    }


    Pour en revenir à ton problème, si tu n'arrives pas à cibler un peu plus précisément l'origine du problème ca risque d'être très difficile de t'aider...

    a++

  11. #11
    Membre confirmé Avatar de docv266
    Profil pro
    Inscrit en
    Août 2007
    Messages
    85
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 85
    Par défaut
    J'ai!

    J'ai trouvé la fonction qui a du mal.

    Je m'en sert pour filtrer mon vecteur, en gros ça retourne un vecteur qui ne contient que certains éléments du vecteur initial :

    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
     
    public Vector<Objet> getVObjet()
    	{
    		Vector<Objet> vecteur = new Vector<Objet>();
    		Objet o;
    		StringTokenizer token;
    		int mois;
    		for (int i=0;i<VObjet.size();i++)
    		{
    			o = VObjet.get(i);
    			token = new StringTokenizer(o.getDate(), "/");
    			token.nextToken();
    			mois = Integer.parseInt(token.nextToken());
     
    			if (mois == mois_selec || mois_selec == 0)
    			{
    				vecteur.add(o);
    			}
    		}
     
    		return vecteur;
    	}
    Je coupe une chaîne de caractère (jj/mm/aaaa) et je récupère la valeur du mois.

    C'est ça qui est long... peut être le StringTokenizer est un processus qui demande de la ressource.

    Sinon il vaut mieux utiliser des Vector ou des tableaux en Java?

  12. #12
    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
    Citation Envoyé par docv266 Voir le message
    Je coupe une chaîne de caractère (jj/mm/aaaa) et je récupère la valeur du mois.
    Plutôt que de découper la chaine à chaque fois, il serait peut-être plus intéressant d'utiliser une structure de type Calendar pour récupérer cette info plus facilement, ou bien de la stocker dans la classe Objet et la récupérer via un getMois()...

    Citation Envoyé par docv266 Voir le message
    Sinon il vaut mieux utiliser des Vector ou des tableaux en Java?
    ArrayList
    Les ArrayList et les Vector font la même chose, sauf que cette dernière est synchronisé (et donc légèrement moins performante). Et comme ton model ne devrais être modifié que par l'EDT une ArrayList fait l'affaire.

    Les deux utilisent des tableaux en interne et limite donc l'intérêt de les utiliser directement (surtout si tu veux faire des traitements dessus).


    Enfin il semblerais que dans le cas mois_selec == 0 tu renvois tous les éléments. Dans ce cas autant retourner directement le Vector sans le dupliquer :
    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
    	public Vector<Objet> getVObjet() {
    		if (mois_selec == 0) {
    			// On retourne directement le vecteur
    			return VObjet;
    		}
     
    		Vector<Objet> vecteur = new Vector<Objet>();
    		for (int i = 0; i < VObjet.size(); i++) {
    			Objet o = VObjet.get(i);
     
    			if (o.getMois() == mois_selec) {
    				vecteur.add(o);
    			}
    		}
    		return vecteur;
    	}
    a++

  13. #13
    Membre confirmé Avatar de docv266
    Profil pro
    Inscrit en
    Août 2007
    Messages
    85
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 85
    Par défaut
    la stocker dans la classe Objet et la récupérer via un getMois()...
    C'est ce que je vais faire.

    Merci à tous pour ces infos, ça va aller maintenant.

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

Discussions similaires

  1. Temps de chargement trop long pour animation légère
    Par CharlyMops dans le forum Flash
    Réponses: 1
    Dernier message: 27/09/2006, 07h13
  2. Réponses: 5
    Dernier message: 15/09/2006, 16h58
  3. [mfc][ado][access] Temps de chargement très très long
    Par julien.nasser dans le forum MFC
    Réponses: 3
    Dernier message: 12/05/2006, 15h57
  4. [MFC][ADO][ACCESS] temps de chargement très très long
    Par julien.nasser dans le forum Access
    Réponses: 2
    Dernier message: 12/05/2006, 15h34
  5. [Javascript] temps de chargement long
    Par rdams dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 28/02/2006, 16h56

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