FAQ Java GUIConsultez toutes les FAQ

Nombre d'auteurs : 35, nombre de questions : 153, dernière mise à jour : 2 juin 2015  Ajouter une question

 

Cette FAQ a été réalisée à partir des questions fréquemment posées sur les forums de http://www.developpez.com et de l'expérience personnelle des auteurs.

Nous tenons à souligner que cette FAQ ne garantit en aucun cas que les informations qu'elle propose sont correctes. Les auteurs font leur maximum, mais l'erreur est humaine. Cette FAQ ne prétend pas non plus être complète. Si vous trouvez une erreur, ou que vous souhaitez nous aider en devenant rédacteur, lisez ceci.


SommaireAWT et SwingGénéralités (27)
précédent sommaire suivant
 

Tout d'abord, il faut rappeler que la librairie AWT a été développée pour la première sortie de Java version 1.0 du JDK alors que Swing n'est apparue qu'à la version 1.2 du JDK (soit Java 2). Il en résulte donc des différences fondamentales de conception entre les deux librairies.

Composant AWT : un composant AWT, lors de sa création, est associé à une fenêtre distincte (un homologue, peer en anglais) gérée par le système d'exploitation sous-jacent. Et c'est cet homologue qui est responsable de son apparence. Cette "manière" de faire, bien qu'elle ait fait ses preuves et qu'elle ait permis au langage Java de s'imposer, est très lourde (perte de performances et consommation excessive de mémoire). C'est pour cette raison que l'on qualifie les composants AWT par heavyweight (littéralement, poids lourds).

Composant Swing : par opposition, les composants Swing sont simplement dessinés à l'intérieur de leur conteneur comme s'il s'agissait d'une image, et aucun homologue du système sous-jacent ne leur est affecté. C'est pourquoi ils sont qualifiés de lightweight (composants allégés).

Nous noterons également que lors du développement avec AWT, il suffit d'ajouter les composants directement au Top-Level Container (Conteneur de Haut Niveau) tel que Frame, Applet, ..., alors que sous Swing il est nécessaire de les ajouter à un volet de contenu (cf : javax.swing.JRootPane). De manière plus explicite, je veux parler du :

Code java : Sélectionner tout
jframe.getContentPane().add(monComposant);
Voilà, ces quelques différences ne sont bien sûr pas exhaustives, Swing possède bien d'autres avantages, je ne citerai que : la gestion de bordure, les info-bulles, le défilement, les Look And Feel, de nouveaux LayoutManager, ainsi que l'architecture MVC (Model-View-Control). Maintenant que l'on a conscience de ces différences, une question reste tout-de-même en suspens... Peut-on mélanger Awt et Swing ?

Mis à jour le 9 mai 2002 Johann.Heymes

NON ! Il est impossible d'obtenir un rendu graphique correct dans une application qui mélange AWT et SWING. Des problèmes de superposition empêchent toute collaboration.

Explication : avant toute chose, il faut bien comprendre les différences entre Awt et Swing : Quelles sont les différences entre Awt et Swing ? .

Le composant JFrame comprend un objet fils qui prend en charge tout ce qui concerne le graphique, il s'agit d'une instance de JRootPane. Le composant JRootPane est lui-même structuré. Il contient un volet structuré en couches (instance de JLayeredPane) et un volet structuré en pellicules (GlassPane).



  • Le composant LayeredPane permet d'insérer une barre de menus ainsi que tout autre composant (cela fait référence au fameux contentPane de jframe.getContentPane ()). il est également chargé du Z-ordering (algorithme permettant de ne dessiner que les parties non cachées, suite aux superpositions de composants).
  • Le composant GlassPane représente une pellicule qui recouvre tout et qui, par exemple, peut intercepter tous les événements souris de l'interface graphique.

Démonstration :

Code java : Sélectionner tout
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
import javax.swing.*; 
import java.awt.*; 
  
public class AWTSwing { 
        private JComboBox combo; // Composant Swing 
        private Button bouton; // Composant AWT 
  
        public AWTSwing () { 
                JFrame frame = new JFrame ("Peut-on melanger Awt & Swing ?"); 
                frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); 
                frame.setBounds (300, 300, 200, 300); 
  
                String [] a = {"oui", "non", "peut etre"}; 
                combo = new JComboBox (a); 
                frame.getContentPane ().add (combo, BorderLayout.NORTH); 
                bouton = new Button ("Coucou"); 
                frame.getContentPane ().add (bouton, BorderLayout.CENTER); 
  
                frame.setVisible (true); 
        }  
  
        public static void main (String argv []) { 
                new AWTSwing (); 
        }  
}
Lorsque l'on ouvre le menu contextuel du JComboBox, ce dernier est caché par le composant bouton de type java.awt.Button.

  • Le rendu graphique du composant "bouton" issu de la librairie AWT est délégué à son homologue (peer), par conséquent la position Z est la même que celle de la Frame (soit de haut niveau).
  • Alors que le composant "combo" de type JComcoBox (Swing) n'est que "dessiné" comme une image sur le conteneur (soit de bas niveau).

La seule solution envisageable est d'uniformiser le code sur la librairie graphique utilisée, soit tout AWT, soit tout Swing !

Mis à jour le 9 mai 2002 Johann.Heymes

On peut utiliser la classe java.lang.Thread ou implémenter l'interface java.lang.Runnable, mais suivant les cas de figure cela représente beaucoup de code et de contraintes. En effet, les instructions qui affectent ou dépendent d'un composant graphique Swing doivent être effectuées par le processus d'évènement (the event-dispatching thread). Par conséquent, si l'on utilise la classe Thread ou l'interface Runnable, il est nécessaire d'utiliser les méthodes : invokeLater(java.lang.Runnable) ou invokeAndWait(java.lang.Runnable) javax.swing.SwingUtilities.

La classe Timer : la classe javax.swing.Timer remplace avantageusement l'utilisation directe de thread. Elle génère un événement à intervalles réguliers (à la milliseconde). C'est le "event-dispatching thread" qui exécute l'événement, donc on peut directement modifier des objets graphiques.

Méthodes importantes : le constructeur de javax.swing.Timer :

Code java : Sélectionner tout
1
2
3
4
public Timer (int delay, ActionListener listener); 
/** delay = l'intervalle de temps entre chaque événement. 
 * listener = l'objet écouteur de ces événements. 
 */
méthode permettant de lancer le processus :

Code java : Sélectionner tout
public void start();
méthode permettant de stopper le processus :

Code java : Sélectionner tout
public void stop();
Note : cette méthode est à utiliser uniquement si le traitement à faire est court en temps d'exécution sinon on aura une interface non réactive pendant le traitement...

Mis à jour le 24 mars 2002 Johann.Heymes

JDK 1.3 et inférieur : lorsque l'on utilise la méthode show(java.awt.Component, int, int) pour afficher un javax.swing.JPopupMenu, les coordonnées correspondent au coin haut-gauche du menu. Si ces coordonnées sont trop près du bord de l'écran, une partie du menu est alors cachée. Nous allons donc surcharger la méthode show() pour que les coordonnées soient corrigées si le message est trop proche du bord de l'écran.

Code java : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class MonPopupMenu extends JPopupMenu { 
        public void show(Component invoker, int x, int y) { 
                /**Dimension de l'écran */ 
                Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); 
                /** Dimension du Menu popup */ 
                Dimension popupSize = this.getPreferredSize(); 
                /** Position en x,y du popup à l'écran (pour le .show) */ 
                double xPopupEcran = invoker.getLocationOnScreen().getX() + x; 
                double yPopupEcran = invoker.getLocationOnScreen().getY() + y; 
  
                /** Si le popup déborde de l'écran sur la droite on décale sur x */ 
                if ((xPopupEcran + popupSize.getWidth()) > screenSize.getWidth()) { 
                        x = x - (int)popupSize.getWidth(); 
                }  
  
                /** Si le popup déborde de l'écran sur le bas on décale sur y */ 
                if ((yPopupEcran + popupSize.getHeight()) > screenSize.getHeight()) { 
                        y = y - (int)popupSize.getHeight(); 
                }  
  
                /** On affiche le popup à l'endroit judicieusement calculé :) */ 
                super.show(invoker, x, y); 
        }  
}
JDK 1.4 : ce bug a été résolu dans la version 1.4 de l'API. Le correctif n'est pas nécessaire.

Mis à jour le 1er janvier 2004 Clement Cunin

Ce n'est pas directement possible en AWT, il faut créer sa propre classe MyButton permettant de le faire en dérivant, par exemple, Component pour faire un lightweigth component.

Mis à jour le 1er avril 2002

Il y a un constructeur de JButton et une méthode qui permettent d'avoir le résultat voulu en donnant l'image en argument sous forme de Icon

Code sql : Sélectionner tout
JButton bouton = new JButton(new ImageIcon("images/bouton.gif"));
ou

Code sql : Sélectionner tout
bouton.setIcon(new ImageIcon("images/bouton.gif"));

Mis à jour le 3 février 2007 Strab

La classe AbstractButton définit un ensemble de méthodes permettant d'indiquer comment doit se dessiner le bouton. Ainsi, on peut indiquer, par exemple, si on désire dessiner les rebords ou le contenu. Voici un exemple.

Le code ci-dessous dessine un bouton transparent, seul le texte sera affiché en rouge.

Code java : Sélectionner tout
1
2
3
4
5
JButton printButton = new JButton("Imprimer"); 
printButton.setForeground(Color.red); 
printButton.setFocusPainted(false); 
printButton.setBorderPainted(false); 
printButton.setContentAreaFilled(false);

Mis à jour le 12 août 2004 bulbo

Voilà un début de code permettant d'imprimer un Container 'cont'.

Code java : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
/** Récupère le travail et affiche la boite de dialogue d'impression */ 
PrintJob job = getToolkit().getPrintJob(frame_parent_pour_le_dialogue,"essai", null); 
if (job != null) { 
        /** Récupère le Graphics dans lequel on va écrire */ 
        Graphics g = job.getGraphics(); 
        if (g != null) { 
                /** Sur le Container imprime l'ensemble de ses Components  */ 
                cont.printAll(g); 
                g.dispose(); 
        }  
        /** Finit le travail  */ 
        job.end(); 
}

Mis à jour le 2 avril 2002

Pour enregistrer un object de type Component en tant qu'image, il faut commencer par dessiner ce composant dans une BufferedImage puis on va écrire cette image dans un fichier.

Voici un exemple qui permet d'enregistrer un composant sous forme d'image JPeg :

Code java : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public void saveImage(Component component, File destination){ 
	BufferedImage image = new BufferedImage(component.getWidth(), component.getHeight(), BufferedImage.TYPE_INT_RGB); 
  
	Graphics2D g2d = image.createGraphics(); 
  
	if(!component.isOpaque()){ 
		Color bg = component.getBackground(); 
		bg = (bg.getAlpha() < 255) ? new Color(bg.getRed(), bg.getGreen(), bg.getBlue()) : bg; 
  
		Color color = g2d.getColor(); 
		g2d.setColor(bg); 
		g2d.fillRect(0, 0, component.getWidth(), component.getHeight()); 
		g2d.setColor(color); 
	} 
  
	component.paint(g2d); 
	g2d.dispose(); 
  
	try { 
		ImageIO.write(image, "jpeg", destination); 
	} catch (IOException e) {       
		e.printStackTrace(); 
	}  
}

Mis à jour le 26 mai 2007 Baptiste Wicht fxjtarga

Symptômes :
La fenêtre est vide, ou il est impossible de cliquer sur le moindre composant, ou les autres fenêtres du système d'exploitation laissent des traînées grises qui ne se redessinent par sur vos fenêtres, ou encore j'ai l'impression que mon application met du temps à réagir.

Cause :
Ce problème est très classique lors d'un long traitement dans une application graphique. En Java, un Thread est chargé de toutes les opérations liées à l'affichage et à la gestion des événements, le Thread "Event Dispatching Thread" (en abrégé EDT). Si une application utilise ce Thread pour faire un traitement de plusieurs minutes, c'est autant de temps où l'application ne sera plus réactive aux actions de l'utilisateur, ni aux mises à jour graphiques (d'une barre de progression par exemple). Typiquement, vous avez du code lié au clic sur un bouton ou un menu (un ActionListener par exemple) et vous y effectuez de gros calculs ou des Thread.sleep(). Vous ne pouvez pas faire ça, les traitements de l'EDT doivent être le plus bref possible !

Solution :
La solution est assez simple à comprendre : tout traitement long doit être effectué par un autre Thread. En Java 5 et supérieur, la classe SwingWorker est très utile pour vous aider à faire ça.

Mis à jour le 22 mars 2002 Clement Cunin tchize_

L'Event Dispatch Thread, également appelée EDT, est le Thread dans lequelle l'AWT et Swing font à la fois leur affichage et leur propagation d'événements. Les composants AWT et Swing doivent uniquement être utilisés dans l'EDT. Si un composant est instancié, appelé et manipulé depuis un autre Thread, il peut potentiellement provoquer une erreur dans le programme ou ne pas s'afficher correctement.

L'EDT alterne les cycles d'affichage et les cycles de propagation d'événements. Ainsi, quand on gère un événement clavier, souris ou de sélection dans un composant, on est assuré que :

  • On est bien dans l'EDT.
  • Le composant n'est pas en train de se redessiner. Il sera redessiné dans un cycle d'affichage ultérieur (pas forcément le cycle suivant) si on appelle sa méthode repaint() après le traitement de l'événement. Il existe cependant des manières d'avoir un rendu immédiat lorsque l'état d'un composant est modifié, mais généralement vous ne devriez pas avoir besoin de les utiliser.

Mis à jour le 6 juin 2009 bouye

Les deux manières de vérifier que le traitement actuel se déroule bien dans l'EDT sont :

  • pour l'AWT, d'invoquer la méthode statique isDispatchThread() de la classe java.awt.EventQueue.
  • Pour Swing, d'invoquer la méthode statique isEventDispatchThread() de la classe javax.swing.SwingUtilities.

Mis à jour le 6 juin 2009 bouye

Tout d'abord, il est bien important de comprendre que tout traitement d'événement, tels que des écouteurs pour le clavier, la souris ou de sélections dans des composants, et implémenté de manière standard se déroule déjà dans l'EDT.

Cependant, il peut parfois être nécessaire d'effectuer un traitement "plus tard" de manière à essayer d'attendre un moment où le niveau de charge de l'EDT est moins élevé ou pour laisser le temps à l'interface graphique de faire un affichage préliminaire par exemple. Pour ce faire, il faut appeler la méthode statique invokeLater() de la classe javax.swing.SwingUtilities. Cette méthode rend immédiatement la main après avoir été invoquée.

Code java : Sélectionner tout
1
2
3
4
5
6
7
8
9
// Cette méthode retourne immédiatement. 
SwingUtilities.invokeLater(new Runnable() { 
  /** 
   * {@inheritDoc} 
   */ 
  @Override public void run() { 
      myButton.setText("Salut le monde !") ; 
  } 
}) ;
Les traitements longs doivent, quant à eux, être exécutés dans un autre Thread, car ils sont susceptibles de bloquer l'EDT et de rendre votre application lente, voire de faire que votre interface graphique ne se ré-affiche plus.

Mis à jour le 6 juin 2009 bouye

Les traitements longs doivent être lancés hors de l'EDT, pour cela il est possible d'utiliser un autre Thread que l'on lance manuellement ou encore d'utiliser un java.util.Timer.

Attention cependant à penser à vérifier et au besoin à changer la priorité du nouveau Thread, car cette dernière hérite automatiquement sa priorité de celle de son Thread parent dans laquelle elle a été créée (le nouveau Thread a donc la même priorité que l'EDT).

Pour Java 6 ou plus, il est recommandé d'utiliser la classe javax.swing.SwingWorker qui offre un framework permettant d'exécuter une tâche hors de l'EDT, tout en récupérant ses résultats intermédiaires et finaux dans l'EDT. Une implémentation existe pour Java 5 qui est disponible chez SwingLabs.

Mis à jour le 6 juin 2009 bouye tchize_

Lien : Tutoriel sur les SwingWorker (Java SE 6)

Il existe deux façons de faire :

  • Utiliser la méthode statique invokeLater() de la classe javax.swing.SwingUtilities. Cette méthode prend en paramètre une instance de la classe Runnable qui sera exécutée ultérieurement. Cette méthode retourne immédiatement après avoir été invoquée.

Code java : Sélectionner tout
1
2
3
4
5
6
7
8
9
// Cette méthode retourne immédiatement. 
SwingUtilities.invokeLater(new Runnable() { 
/** 
 * {@inheritDoc} 
 */ 
@Override public void run() { 
    myButton.setText("Salut le monde !") ; 
} 
}) ;
  • Utiliser la méthode statique invokeAndWait() de la classe javax.swing.SwingUtilities. Cette méthode prend en paramètre une instance de la classe Runnable qui sera exécutée. Cette méthode bloque tant que l'action n'a pas été effectuée, ce qui permet, par exemple, de mettre à jour l'interface graphique quand on effectue un traitement depuis un autre Thread et de bloquer jusqu'à ce que la GUI ait été modifiée. Cette méthode ne DOIT PAS être appelée de l'EDT même.

Code java : Sélectionner tout
1
2
3
4
5
6
7
8
9
// Cette méthode bloque tant que le traitement EDT n'est pas effectué. 
SwingUtilities.invokeAndWait(new Runnable() { 
/** 
 * {@inheritDoc} 
 */ 
@Override public void run() { 
    myButton.setText("Salut le monde !") ; 
 } 
}) ;
Attention cependant, si elle est mal utilisée, invokeAndWait() peut provoquer des deadlocks ; il est donc recommandé d'utiliser la classe javax.swing.SwingWorker à la place.

Mis à jour le 6 juin 2009 bouye

Pour mieux comprendre le problème : Lors d'un traitement long, l'affichage se fige, que faire ?

Voici deux codes sources Java commentés.
JProgress : la mauvaise méthode (la vôtre ?)
JProgress2 = une solution

Mis à jour le 5 juin 2002 Johann.Heymes

Didacticiel de Sun sur les JProgressMonitor et les JProgressBars
JProgress.java
JProgress2.java

Pour faire cela, il faut utiliser la classe UIManager. Par exemple :

Code java : Sélectionner tout
1
2
3
4
5
6
7
8
try { 
   UIManager.setLookAndFeel("mon.look.and.Feel"); 
   //on passe au UIManager le nom complet de la classe du Look and Feel 
   //naturellement, celle-ci doit être disponible dans le CLASSPATH 
} catch (InstantiationException e) { 
} catch (ClassNotFoundException e) { 
} catch (UnsupportedLookAndFeelException e) { 
} catch (IllegalAccessException e) {}
Si vous changez le Look and Feel de votre application en cours d'exécution, vous devez la rafraîchir en utilisant SwingUtilities.updateComponentTreeUI. Voici un exemple changeant le Look and Feel de l'application pour le Look and Feel natif (celui naturellement utilisé par le système).

Code java : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
JFrame frame = new JFrame(); 
frame.setVisible(true); 
// etc. 
try { 
   UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
   SwingUtilities.updateComponentTreeUI(frame); 
   //force chaque composant de la fenêtre à appeler sa méthode updateUI 
} catch (InstantiationException e) { 
} catch (ClassNotFoundException e) { 
} catch (UnsupportedLookAndFeelException e) { 
} catch (IllegalAccessException e) {}

Mis à jour le 12 août 2004 Ioan

Comment lister les Look & Feel disponibles ?

Les Look and Feel enregistrés sont disponibles avec la méthode getInstalledLookAndFeels de la classe UIManager. Voici un exemple récupérant l'ensemble des Look and Feel sous forme de Map, dont les clefs sont les noms des L&F et les valeurs les noms des classes correspondantes.

Code java : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
public Map getLookAndFeelsMap(){ 
   UIManager.LookAndFeelInfo[] info = UIManager.getInstalledLookAndFeels(); 
   Map map = new TreeMap(); 
   for(int i=0; i<info.length;i++){ 
      String nomLF = info[i].getName(); 
      String nomClasse = info[i].getClassName(); 
      map.put(nomLF,nomClasse);  
   } 
   return map; 
}
Pour un exemple utilisant cette méthode, regardez le fichier ci-dessous.

Mis à jour le 12 août 2004 Ioan

Comment changer le Look & Feel de mon application ?
Menu Look and Feel

Avant tout affichage, il faut appeler la méthode put(Object, Object) de la classe UIManager. Le premier paramètre correspond à l'objet à modifier, et le second est la valeur à lui donner.

Par exemple, pour mettre en blanc le fond de tous les JPanels :

Code java : Sélectionner tout
UIManager.put("Panel.background", new ColorUIResource(Color.WHITE));

Mis à jour le 12 janvier 2008 CheryBen

Liste d'éléments modifiables d'un Look And Feel

Metal, le Look and Feel par défaut, utilise du texte en gras dans la plupart des composants Swing. Le résultat n'est pas forcément des plus esthétiques.

Heureusement, il est possible de remédier à cela en modifiant la propriété swing.boldMetal, soit directement via la classe UIManager :

Code java : Sélectionner tout
1
2
// Ne pas utiliser de texte en gras (LnF Metal) : 
UIManager.put("swing.boldMetal", Boolean.FALSE);

Soit en passant par les variables systèmes si l'on n'a pas accès au code source :

Code : Sélectionner tout
java -Dswing.boldMetal=false ... (les autres paramètres standards)

Mis à jour le 20 octobre 2006 adiGuba

Les look and Feel
Comment modifier un élément du Look and Feel ?

Vous souhaitez associer des boutons de votre interface graphique aux touches ENTER et ESCAPE, et ceci quel que soit le composant qui ait le focus lors de l'appui sur ces touches ?

Pour la touche ENTER, c'est très simple parce que c'est fait pour :

Code java : Sélectionner tout
1
2
3
4
  // - pour une JFrame 
  maFrame.getRootPane().setDefaultButton(monBouton) 
  // - pour une JDialog 
  monDialog.getRootPane().setDefaultButton(monBouton)
Pour la touche ESCAPE, c'est plus compliqué. Une solution est d'associer du code à l'événement (et non pas un bouton) :

Code java : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  private void configureRootPane(JRootPane rootPane) { 
    InputMap inputMap = rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); 
    inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "escPressed"); 
  
    rootPane.getActionMap().put( 
        "escPressed", 
        new AbstractAction("escPressed") { 
          public void actionPerformed(ActionEvent actionEvent) { 
            onKeyEscape(); 
          } 
        }); 
  } 
  
  ... 
  
  // - pour une JFrame 
  configureRootPane(maFrame.getRootPane()); 
  // - pour une JDialog 
  configureRootPane(monDialog.getRootPane());
La méthode "configureRootPane" ne devrait être appelée qu'une fois, par exemple juste après l'instanciation de votre conteneur. Il vous reste à implémenter la méthode "onKeyEscape", qui sera appelée lors de chaque appui sur ESCAPE.

Mis à jour le 3 avril 2005 laffreuxthomas

Il faut en fait ajouter le KeyListener au composant permettant l'édition de la combobox, en l'occurrence un JTextField :

Code java : Sélectionner tout
1
2
3
Component c = comboBox.getEditor().getEditorComponent() ; 
JTextField textField = (JTextField) c ; 
textField.addKeyListener( new KeyListener() ) ;

Mis à jour le 16 décembre 2006 wammaster

Il suffit d'utiliser la méthode setDefaultLocale de la classe JComponent.

Exemple, si j'ai un programme en français mais que je veux avoir tous mes JFileChooser en anglais :

Code java : Sélectionner tout
1
2
JFileChooser.setDefaultLocale(new Locale("en","US")); 
// ou JFileChooser.setDefaultLocale(Locale.US)

Mis à jour le 26 mai 2007 Jack Huser

Pour changer l'arrière-plan de certaines lignes d'une Jlist, il faut utiliser un ListCellRenderer personnalisé :

Code java : Sélectionner tout
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
class MyCellRenderer extends JLabel implements ListCellRenderer { 
  
	public Component getListCellRendererComponent( 
		JList list, 
		Object value,            // value to display 
		int index,               // cell index 
		boolean isSelected,      // is the cell selected 
		boolean cellHasFocus)    // the list and the cell have the focus 
	{ 
		setText(value.toString()); 
  
		if (isSelected) { 
			setBackground(list.getSelectionBackground()); 
			setForeground(list.getSelectionForeground()); 
		} 
		else { 
			setBackground(list.getBackground()); 
			setForeground(list.getForeground()); 
		} 
  
		// Ici, il faut tester si on veut changer la couleur et changer par la  
		// couleur de notre choix 
		if (taCondition == true){ 
			setBackground(couleur); 
		} 
  
		setEnabled(list.isEnabled()); 
		setFont(list.getFont()); 
		setOpaque(true); 
		return this; 
	} 
}

Après, il suffit d'appliquer ce renderer à la JList :

Code java : Sélectionner tout
1
2
JList list = new JList(); 
list.setCellRenderer(new MyCellRenderer());

et le tour est joué.

Mis à jour le 26 mai 2007 Baptiste Wicht seiryujay

Il suffit de changer le Locale de la JVM au démarrage.

Code java : Sélectionner tout
Locale.setDefault(Locale.US);// par exemple si on est en français et que l'on veut l'anglais (USA)
ou

Code java : Sélectionner tout
Locale.setDefault(new Locale("en", "US"));// par exemple si on est en français et que l'on veut de l'anglais  (USA)
En général:

Code : Sélectionner tout
Locale loc = new Locale(String langue, String pays)
Dans cet exemple, on aura donc les chiffres décimaux avec des points et non des virgules.

Mis à jour le 12 janvier 2008 Jack Huser

Classe java.util.Locale

Il y a deux manières de faire pour disposer ses composants en couches ou en niveaux :

  • En utilisant un JLayeredPane. Cette solution est utilisable avec Swing.
  • En utilisant le principe du ZOrder. Cette solution est valable pour AWT et Swing, pour toutes les classes descendant de Container.

Nous allons prendre comme exemple la disposition de deux JLabels l'un au dessus de l'autre.

Premièrement, avec un JLayeredPane :

Code java : Sélectionner tout
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
import javax.swing.JLabel; 
import javax.swing.JLayeredPane; 
  
public class CouchesAvecJLayer extends javax.swing.JFrame { 
    public CouchesAvecJLayer() { 
        initComponents(); 
    } 
  
    private void placeLesCouches(){ 
        JLayeredPane layered; 
        JLabel dessous; 
        JLabel dessus; 
  
        layered = new JLayeredPane(); 
        // Comme il n'y a pas vraiment de layout avec un JLayeredPane 
        // il faut gérer soi-même les tailles et positions. 
        layered.setPreferredSize(new java.awt.Dimension(400, 200)); 
        // (pour simplifier on ne gère pas les positions, tout ira les 
        // uns sur les autres). 
  
        dessous = new JLabel("en dessous ! (et en partie masqué)"); 
        dessous.setSize(dessous.getPreferredSize()); 
        layered.add(dessous, new Integer(0)); 
        dessus = new JLabel("au dessus !"); 
  
        // Inutile, pour jouer avec l'opacité de façon à mieux faire 
        // apparaître ce qui est dessus/dessous 
        dessus.setOpaque(true); 
  
        layered.add(dessus, new Integer(1)); 
        add(layered); 
        pack(); 
    } 
  
  	@SuppressWarnings("unchecked") 
  	private void initComponents() { 
    	setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); 
  
    	pack(); 
  	}                         
  
    public static void main(String args[]) { 
        java.awt.EventQueue.invokeLater(new Runnable() { 
            public void run() { 
                CouchesAvecJLayer couches; 
  
                couches = new CouchesAvecJLayer(); 
                couches.placeLesCouches(); 
                couches.setVisible(true); 
            } 
        }); 
    } 
}
Puis en jouant avec le ZOrder des composants :

Code java : Sélectionner tout
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
import javax.swing.JLabel; 
import javax.swing.JPanel; 
  
public class CouchesAvecZOrder extends javax.swing.JFrame { 
    public CouchesAvecZOrder() { 
        initComponents(); 
    } 
  
    private void placeLesCouches(){ 
        JPanel zpanel; 
        JLabel dessous; 
        JLabel dessus; 
  
        zpanel = new JPanel(); 
  
        // Le réglage du layout est particulier avec le ZOrder. 
        // Pour simplifier on le supprime. 
        zpanel.setLayout(null); 
  
        zpanel.setPreferredSize(new java.awt.Dimension(400, 200)); 
        dessus = new JLabel("au dessus !"); 
  
        // Comme il n'y a plus de layout on doit gérer les tailles. 
        dessus.setSize(dessus.getPreferredSize()); 
  
        // Inutile, pour jouer avec l'opacité de façon à mieux faire 
        // apparaître ce qui est dessus/dessous 
        dessus.setOpaque(true); 
  
        zpanel.setComponentZOrder(dessus, 0); 
        dessous = new JLabel("en dessous ! (et en partie masqué)"); 
        dessous.setSize(dessous.getPreferredSize()); 
        zpanel.setComponentZOrder(dessous, 1); 
        add(zpanel); 
        pack(); 
    } 
  
  	@SuppressWarnings("unchecked") 
  	private void initComponents() { 
    	setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); 
  
    	pack(); 
  	}                         
  
    public static void main(String args[]) { 
        java.awt.EventQueue.invokeLater(new Runnable() { 
            public void run() { 
                CouchesAvecZOrder couches; 
  
                couches = new CouchesAvecZOrder(); 
                couches.placeLesCouches(); 
                couches.setVisible(true); 
            } 
        }); 
    } 
}

Mis à jour le 15 novembre 2008 gifffftane

Ce n'est pas possible.

Pour obtenir un résultat similaire, il faut utiliser la notion de modèle, souvent attachée à un composant swing (JTable, JTree...). Le modèle Action est le plus simple, et permet de stipuler une même fonction à plusieurs boutons, ou autre composant. Il s'utilise simplement par l'AbstractAction.

Pour créer une AbstractAction :

Code java : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
class QuelleBelleAction extends javax.swing.AbstractAction 
  { 
    QuelleBelleAction() 
    { 
      putValue(NAME, "Merci, developpez.net"); 
    } 
  
    @Override 
    public void actionPerformed(ActionEvent e) 
    { 
      System.out.println("BINGO ! "); 
    } 
  }
Pour l'utiliser sur plusieurs boutons :

Code java : Sélectionner tout
1
2
3
4
5
QuelleBelleAction belle = new QuelleBelleAction(); 
JButton but1 = new JButton(belle); 
JButton but2 = new JButton(belle); 
paneau.add(but1); 
panneau.add(but2);
... les deux boutons réagiront de la même manière, et auront tous les deux le même label. Et si l'on fait :

Code java : Sélectionner tout
belle.setEnabled(false);
... les deux boutons seront rendus indisponibles simultanément.

On peut de la même façon mettre plusieurs JTable (ou JTree, ou...) apparemment identiques, parce qu'ils ont le même modèle, et non parce que le composant graphique est le même.

Mis à jour le 6 juin 2009 gifffftane

Proposer une nouvelle réponse sur la FAQ

Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour ça


Réponse à la question

Liens sous la question
précédent sommaire suivant
 

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2015 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

 
Responsable bénévole de la rubrique Java : Mickael Baron -