Bonjour,

dans mon application, je souhaite changer la couleur de la bordure de mes JTextField lorsque ces derniers récupèrent le focus, comme sur le site de Siemens :
* champ ne disposant pas du focus : Nom : JTextField_sansFocus.png
Affichages : 1798
Taille : 993 octets
* champ ayant le focus : Nom : JTextField_avecFocus.png
Affichages : 1800
Taille : 1,1 Ko

Dès que le champ perd le focus, il doit revenir à l'état initial.

En cherchant sur Internet, j'ai trouvé deux classes : ColourissingBorder et ColourisingComposite qui me permettent de changer simplement la couleur de la bordure sans modifier la marge par défaut.

Voici la classe ColourisingBorder :

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
 
import java.awt.Color;
import java.awt.Component;
import java.awt.Composite;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.image.BufferedImage;
 
import javax.swing.border.Border;
 
public class ColourisingBorder implements Border {
	// Composite used to colourise the rendering
	private Composite composite;
 
	// The border that we're colourising
	private Border border;
 
	private BufferedImage image;
 
	public ColourisingBorder(Border border, Color color) {
		this.border = border;
		composite = new ColourisingComposite(color);
	}
 
	public boolean isBorderOpaque() {
		return border.isBorderOpaque();
	}
 
	public Insets getBorderInsets(Component comp) {
		return border.getBorderInsets(comp);
	}
 
	public void paintBorder(Component comp, Graphics g, int x, int y,
			int width, int height) {
		clearImage(width, height);
 
		// Change the graphics so that it colourises its output when drawing
		Graphics2D g2 = (Graphics2D) image.getGraphics();
		g2.setComposite(composite);
		// Paint the underlying border with the composite applied onto our
		// buffer image
		border.paintBorder(comp, g2, 0, 0, width, height);
		g2.dispose();
 
		// Paint our buffer image onto the "screen"
		g.drawImage(image, x, y, width, height, 0, 0, width, height, null);
	}
 
	private void clearImage(int width, int height) {
		// TODO - Optimise this so it just clears the image rather than creates
		// a new one!
		image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
	}
}

Voici la classe ColourisingComposite :

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
 
import java.awt.Color;
import java.awt.Composite;
import java.awt.CompositeContext;
import java.awt.RenderingHints;
import java.awt.image.ColorModel;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
 
public class ColourisingComposite implements Composite, CompositeContext {
 
	private Color color;
 
	public ColourisingComposite(Color color) {
		this.color = color;
	}
 
	public CompositeContext createContext(ColorModel srcColorModel,
			ColorModel dstColorModel, RenderingHints hints) {
		return this;
	}
 
	public void compose(Raster src, Raster dstIn, WritableRaster dstOut) {
		int[] srcPixel = new int[4];
		int[] dstPixel = new int[4];
 
		for (int y = dstIn.getMinY(); y < dstIn.getMinY() + dstIn.getHeight(); y++) {
			for (int x = dstIn.getMinX(); x < dstIn.getMinX()
					+ dstIn.getWidth(); x++) {
				srcPixel = src.getPixel(x, y, srcPixel);
				dstPixel[0] = ((srcPixel[0] * color.getRed()) >> 8) & 0xFF;
				dstPixel[1] = ((srcPixel[1] * color.getGreen()) >> 8) & 0xFF;
				dstPixel[2] = ((srcPixel[2] * color.getBlue()) >> 8) & 0xFF;
				dstPixel[3] = srcPixel[3];
 
				dstOut.setPixel(x, y, dstPixel);
			}
		}
	}
 
	public void dispose() {
	}
 
}
Dans une de mes classes créant l'interface graphique, j'ai écrit le code suivant :
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
 
private JTextField txtNom = new JTextField(20);
 
// Couleur du contour des champs et des champs proteges
private Color couleur_fond_champ = Color.WHITE;
private Color couleur_contour_champ = new Color(102, 153, 204);
private Color couleur_fond_champProtege = new Color(212, 231, 242);
private Color couleur_contour_champProtege = new Color(102, 153, 204);
private Color couleur_fond_champFocus = new Color(255, 255, 218);
private Color couleur_contour_champFocus = new Color(255, 153, 0);
 
....
.... puis dans la méthode init(), appelée par le constructeur, jai le code suivant :
....
 
// J'applique au JTextField txtNom, la couleur de la bordure « 
// couleur_contour_champ »
txtNom.setBackground(couleur_fond_champ);
txtNom.setBorder(new ColourisingBorder(txtNom.getBorder(), couleur_contour_champ));
..etc.
Pour faire évoluer la couleur de la bordure lorsque le champ gagne ou perd le focus, j'ai écrit le code suivant dans une méthode privée appelée également par le constructeur :
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
 
txtNom.addFocusListener( 
	new FocusListener() {
		public void focusGained(FocusEvent e) {
			txtNom.setBackground(couleur_fond_champFocus);
			//txtNom.setBorder(new ColourisingBorder(txtNom.getBorder(), couleur_contour_champFocus));
			txtNom.setBorder(new ColourisingBorder(txtNom.getBorder(), Color.RED));
		}
 
		public void focusLost(FocusEvent e) {
			txtNom.setBackground(couleur_fond_champ);
			txtNom.setBorder(new ColourisingBorder(txtNom.getBorder(), couleur_contour_champ));
		} 
	}
);
Le problème est que la couleur de ma bordure ne change pas et ce quel que soit la couleur que j'essaye d'affecter à mon composant.
J'ai essayé de faire redessiné mon composant (txtNom.repaint()), de lui signifier que les modifications sont terminées (txtNom.validate()) mais sans résultat.

Evidemment, si dans les attributs de ma classe, j'écrit :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
 
private Color couleur_contour_champ = Color.RED;
 
au lieu de :
 
private Color couleur_contour_champ = new Color(102, 153, 204);
le contour de mon champ JTextField apparaîtra en rouge.

Mon problème est que je n'arrive pas à changer la couleur de la bordure de mon champ de saisie dynamiquement, sur le déclenchement d'un événement.

Avez-vous une idée et une solution ?

Merci beaucoup pour votre aide,
Fabien.