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

AWT/Swing Java Discussion :

Problème de rafraichissement après un évènement


Sujet :

AWT/Swing Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre chevronné
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    299
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2009
    Messages : 299
    Par défaut Problème de rafraichissement après un évènement
    Bonjour à tous,

    je rencontre un problème de rafraichissement sur un petit test de gestion de presse-papier.

    Lorsque l'on lance l'application, et que l'on fait des copiers de texte depuis d'autres applications, les copiers sont stockés en mémoire dans une JList.

    Tout fonctionne visuellement très bien, jusqu'au moment ou j'effectue ma première sélection d'un élément de la JList.

    La sélection d'une ligne permet 2 choses :
    1. de renvoyer le contenu de la sélection dans le presse-papier
    2. de faire un drag&drop directement vers une application externe

    Une fois cette première sélection effectuée, les copiers suivants n'apparaissent plus dans ma JList. Il est nécessaire que je sélectionne ma Frame pour voir apparaitre le copier en cours, et seul ce copier en cours est ajouté à la JList.

    Voici le code :
    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
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    package fvt.myclipboard;
     
    import java.awt.Color;
    import java.awt.Component;
    import java.awt.Dimension;
    import java.awt.Toolkit;
    import java.awt.datatransfer.Clipboard;
    import java.awt.datatransfer.DataFlavor;
    import java.awt.datatransfer.StringSelection;
    import java.awt.datatransfer.Transferable;
     
    import javax.swing.DefaultListModel;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JList;
    import javax.swing.JScrollPane;
    import javax.swing.ListCellRenderer;
    import javax.swing.ListSelectionModel;
    import javax.swing.event.ListSelectionEvent;
    import javax.swing.event.ListSelectionListener;
     
    @SuppressWarnings("serial")
    public class MyClipBoard extends JFrame implements ListSelectionListener{
    	public static Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
     
    	private final static int TAILLE_MAX = 10;
    	private DefaultListModel mdl;
    	private JList list;	
     
    	public MyClipBoard() {
    		super("MyClipBoard");
     
    		mdl = new DefaultListModel();
    		list = new JList(mdl);
    			list.setDragEnabled(true);
    			list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    			list.setCellRenderer(new MyRenderer());
    			list.addListSelectionListener(this);
     
    		JScrollPane scroll = new JScrollPane(list);
    			scroll.setPreferredSize(new Dimension(300, (TAILLE_MAX*20)+10));
    			add(scroll);
     
    		pack();
    		setDefaultCloseOperation(EXIT_ON_CLOSE);
    		setAlwaysOnTop(true);
     
    		run();
    	}
     
    	private void run() {
    		Thread t = new Thread(new MyRunnable(this));
    		t.start();
    	}
     
    	public void addTxt(String txt){
    		if(!mdl.contains(txt)){
    			// Postion le txt en tête de liste
    			mdl.add(0, txt);
    			// Supprime le dernier élément si TAILLE_MAX dépassé
    			if(mdl.size()>TAILLE_MAX){
    				mdl.remove(TAILLE_MAX);
    			}
     
    			validate();
    		}
    	}
     
    	// Listeners
    	@Override
    	public void valueChanged(ListSelectionEvent arg0) {
    		try {
    			// Si la sélection de la list change, on réinjecte la nouvelle dans le presse-papier
    			if(!list.isSelectionEmpty()){				
    				StringSelection ss = new StringSelection((String)list.getSelectedValue());
    				clipboard.setContents(ss, null);
    			}
    		} catch(IllegalStateException e ) {e.printStackTrace();} 
    	}
     
    	// Main
    	public static void main(String[] args) {
    		new MyClipBoard().setVisible(true);
    	}
    }
     
     
    class MyRunnable implements Runnable {
    	private MyClipBoard parent;	
     
    	public MyRunnable(MyClipBoard parent) {
    		this.parent = parent;
    	}
     
    	public void run() {
    		Transferable t;
    		String txt;
     
    		while(true){			
    			try {
    				t = MyClipBoard.clipboard.getContents(null);
     
    				if(t.isDataFlavorSupported(DataFlavor.stringFlavor) ) {
    					txt = (String)t.getTransferData(DataFlavor.stringFlavor);
    					parent.addTxt(txt);
    				} 
    			} catch(Exception e) {e.printStackTrace();}
     
    			try {
    				Thread.sleep(1000);
    			} catch (InterruptedException e) {e.printStackTrace();}
    		}
    	}
    }
     
    class MyRenderer implements ListCellRenderer {
    	@Override
    	public Component getListCellRendererComponent(JList list, Object source, int index, boolean isselected, boolean hasfocus) {
    		JLabel label = new JLabel((String)source);
    		label.setOpaque(true);
    		label.setPreferredSize(new Dimension(290, 20));
     
    		if(index % 2 == 0){
    			label.setBackground(new Color(0xe0e0e0));
    		}else{
    			label.setBackground(new Color(0xf0f0f0));			
    		}
     
    		if(isselected){
    			label.setBackground(new Color(0xaaaaff));
    		}
     
    		return label;
    	}
    }

  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,



    Lorsque tu manipules l'interface graphique, tu dois toujours passer par le thread de l'EDT, sous peine d'avoir des comportements bizarre et aléatoire...

    En clair tu dois faire l'appel à addTxt() dans un SwingUtilities.invokeLater()...


    Au passage tu devrais définir ton thread en "daemon", afin qu'il s'arrête automatiquement lorsqu'il n'y a plus aucun autres threads actifs (sinon il pourrait continuer à tourner).


    Personnellement, j'aurais plutôt opter pour un SwingWorker qui facilite le passage d'élément du thread de travail vers l'EDT :
    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
    	new SwingWorker<Void, String>() {
    		/**
                     * La méthode doInBackground() sera exécuté en tâche de fond via un thread.
                     */
    		@Override
    		protected Void doInBackground() {
    			while (true) {
    				try {
    					Transferable t = MyClipBoard.clipboard.getContents(null);
    					if(t.isDataFlavorSupported(DataFlavor.stringFlavor) ) {
    						// On publie les données (voir la méthode process() ci-dessous)
    						publish( (String)t.getTransferData(DataFlavor.stringFlavor) );
    					}
    					Thread.sleep(1000);
    				} catch (Exception e) {
    					// Il faudrait peut-être géré cela différemment ?
    					e.printStackTrace();
    				}
    			}
    		}
     
    		/**
                     * Toutes les données envoyées à la méthode publish()
                     * seront transmises à cette méthode, qui sera exécuté dans l'EDT.
                     * On peut donc y modifier l'interface librement.
                     */
    		@Override
    		protected void process(List<String> chunks) {
    			// Même si on ne passe qu'un élément à la fois,
    			// Il est possible que plusieurs appels à publish()
    			// soit regroupé en un seul appel à process().
    			// Il faut donc traiter tous les éléments...
    			for (String str : chunks) {
    				addTxt(str);
    			}
    		}
    	}.execute();

    a++

  3. #3
    Membre chevronné
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    299
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2009
    Messages : 299
    Par défaut
    Merci beaucoup pour ces explications adiGuba.
    Je vais tester tout cela afin de prendre de meilleurs réflexes.

  4. #4
    Membre chevronné
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    299
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2009
    Messages : 299
    Par défaut
    J'avais déjà utilisé invokeLater(), mais uniquement lorsqu'un calcul me freezait l'interface (oui je sais, mais les bons réflexes sont toujours les plus durs à prendre )
    Le SwingWorker par contre, je n'avais pas encore testé. C'est vrai que ça semble très simple à utiliser.

    J'ai modifié mon code comme ci-dessous, mais malheureusement le problème est toujours là.
    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
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    package fvt.myclipboard;
     
    import java.awt.Color;
    import java.awt.Component;
    import java.awt.Dimension;
    import java.awt.Toolkit;
    import java.awt.datatransfer.Clipboard;
    import java.awt.datatransfer.DataFlavor;
    import java.awt.datatransfer.StringSelection;
    import java.awt.datatransfer.Transferable;
    import java.util.List;
     
    import javax.swing.DefaultListModel;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JList;
    import javax.swing.JScrollPane;
    import javax.swing.ListCellRenderer;
    import javax.swing.ListSelectionModel;
    import javax.swing.SwingWorker;
    import javax.swing.event.ListSelectionEvent;
    import javax.swing.event.ListSelectionListener;
     
    @SuppressWarnings("serial")
    public class MyClipBoard extends JFrame implements ListSelectionListener{
    	public static Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
     
    	private final static int TAILLE_MAX = 10;
    	private DefaultListModel mdl;
    	private JList list;	
     
    	public MyClipBoard() {
    		super("MyClipBoard");
     
    		mdl = new DefaultListModel();
    		list = new JList(mdl);
    			list.setDragEnabled(true);
    			list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    			list.setCellRenderer(new MyRenderer());
    			list.addListSelectionListener(this);
     
    		JScrollPane scroll = new JScrollPane(list);
    			scroll.setPreferredSize(new Dimension(300, (TAILLE_MAX*20)+10));
    			add(scroll);
     
    		pack();
    		setDefaultCloseOperation(EXIT_ON_CLOSE);
     
    		run();
    	}
     
    	private void run() {
    		new SwingWorker<Void, String>() {
     
    			@Override
    			protected Void doInBackground() {
    				while(true){
    					try{
    						Transferable t = MyClipBoard.clipboard.getContents(null);
    						if(t.isDataFlavorSupported(DataFlavor.stringFlavor)){
    							publish((String)t.getTransferData(DataFlavor.stringFlavor));
    						}
    						Thread.sleep(1000);
    					}catch(Exception e){e.printStackTrace();}
    				}
    			}
     
    			protected void process(List<String> liste) {
    				for(String s : liste){
    					addTxt(s);
    				}
    			};
     
    		}.execute();
    	}
     
    	public void addTxt(String txt){
    		if(!mdl.contains(txt)){
    			// Postion le txt en tête de liste
    			mdl.add(0, txt);
    			// Supprime le dernier élément si TAILLE_MAX dépassé
    			if(mdl.size()>TAILLE_MAX){
    				mdl.remove(TAILLE_MAX);
    			}
     
    			validate();
    		}
    	}
     
    	// Listeners
    	@Override
    	public void valueChanged(ListSelectionEvent arg0) {
    		try {
    			// Si la sélection de la list change, on réinjecte la nouvelle dans le presse-papier
    			if(!list.isSelectionEmpty()){				
    				StringSelection ss = new StringSelection((String)list.getSelectedValue());
    				clipboard.setContents(ss, null);
    			}
    		} catch(IllegalStateException e ) {e.printStackTrace();} 
    	}
     
    	// Main
    	public static void main(String[] args) {
    		MyClipBoard myclipboard = new MyClipBoard();
    		myclipboard.setVisible(true);
    		myclipboard.setAlwaysOnTop(true);
    	}
    }
     
     
    class MyRenderer implements ListCellRenderer {
    	@Override
    	public Component getListCellRendererComponent(JList list, Object source, int index, boolean isselected, boolean hasfocus) {
    		JLabel label = new JLabel((String)source);
    		label.setOpaque(true);
    		label.setPreferredSize(new Dimension(290, 20));
     
    		if(index % 2 == 0){
    			label.setBackground(new Color(0xe0e0e0));
    		}else{
    			label.setBackground(new Color(0xf0f0f0));			
    		}
     
    		if(isselected){
    			label.setBackground(new Color(0xaaaaff));
    		}
     
    		return label;
    	}
    }
    Pour ce qui est de la gestion des Exceptions, je n'ai pour le moment laissé qu'un affichage console. A vrai dire, je ne pense pas amener ce projet plus loin que des tests dans l'EDI.

    Merci !

Discussions similaires

  1. JScrollPane problème de rafraichissement après un changement de dimension
    Par Gouyon dans le forum Agents de placement/Fenêtres
    Réponses: 3
    Dernier message: 14/11/2013, 09h54
  2. Réponses: 4
    Dernier message: 31/01/2012, 14h56
  3. Réponses: 0
    Dernier message: 14/09/2010, 10h17
  4. [AJAX] Rafraichissement après insertion dans la base
    Par xave dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 15/05/2007, 10h56
  5. Toujours un problème de rafraichissement de DBGrid
    Par tripper.dim dans le forum C++Builder
    Réponses: 4
    Dernier message: 09/12/2002, 13h15

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