La décoration d'une component swing jtextfield avec une image et un soupçon

Je suis en train de créer certains plus agréable à la recherche JTextFields avec une image et un soupçon. Pour ce faire, j'ai fait un décorateur qui remplace la méthode paintComponent. La raison, j'ai utilisé un décorateur, c'est que j'ai voulu l'appliquer à d'autres types de component swing jtextfield comme JPasswordField.

Voici ce que j'ai fait jusqu'à présent;

La décoration d'une component swing jtextfield avec une image et un soupçon

Le problème comme on le voit dans le formulaire sur la gauche, c'est que, même si j'ai utilisé un JPasswordField le paintComponent semble ignorer ce que je suppose est le mots de passe paintComponent qui est sans doute le mot de passe de masquage des symboles.

La question est donc, comment puis-je éviter de dupliquer le code pour JTextFields et JPasswordFields, mais encore les différentes fonctionnalités telles que le mot de passe de masquage.

C'est le décorateur code;

public class JTextFieldHint extends JTextField implements FocusListener{
private JTextField jtf;
private Icon icon;
private String hint;
private Insets dummyInsets;
public JTextFieldHint(JTextField jtf, String icon, String hint){
this.jtf = jtf;
setIcon(createImageIcon("icons/"+icon+".png",icon));
this.hint = hint;
Border border = UIManager.getBorder("TextField.border");
JTextField dummy = new JTextField();
this.dummyInsets = border.getBorderInsets(dummy);
addFocusListener(this);
}
public void setIcon(Icon newIcon){
this.icon = newIcon;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int textX = 2;
if(this.icon!=null){
int iconWidth = icon.getIconWidth();
int iconHeight = icon.getIconHeight();
int x = dummyInsets.left + 5;
textX = x+iconWidth+2;
int y = (this.getHeight() - iconHeight)/2;
icon.paintIcon(this, g, x, y);
}
setMargin(new Insets(2, textX, 2, 2));
if ( this.getText().equals("")) {
int width = this.getWidth();
int height = this.getHeight();
Font prev = g.getFont();
Font italic = prev.deriveFont(Font.ITALIC);
Color prevColor = g.getColor();
g.setFont(italic);
g.setColor(UIManager.getColor("textInactiveText"));
int h = g.getFontMetrics().getHeight();
int textBottom = (height - h) / 2 + h - 4;
int x = this.getInsets().left;
Graphics2D g2d = (Graphics2D) g;
RenderingHints hints = g2d.getRenderingHints();
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d.drawString(hint, x, textBottom);
g2d.setRenderingHints(hints);
g.setFont(prev);
g.setColor(prevColor);
}
}
protected ImageIcon createImageIcon(String path, String description) {
java.net.URL imgURL = getClass().getResource(path);
if (imgURL != null) {
return new ImageIcon(imgURL, description);
} else {
System.err.println("Couldn't find file: " + path);
return null;
}
}
@Override
public void focusGained(FocusEvent arg0) {
this.repaint();
}
@Override
public void focusLost(FocusEvent arg0) {
this.repaint();
}
}

Et c'est là que je créer les champs;

JTextField usernameField = new JTextFieldHint(new JTextField(),"user_green","Username");
JTextField passwordField = new JTextFieldHint(new JPasswordField(),"bullet_key","Password");

J'espère que je n'ai pas allés complètement dans la mauvaise direction ici!

Merci!

EDIT : Encore plus je le regarde, il est évident qu'un appel à super.paintComponent(g) va appeler la JTextFields paintcomponent, mais je ne vois pas comment résoudre ce problème sans dupliquer le code.

OriginalL'auteur Aidan | 2011-05-22