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;
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
Vous devez vous connecter pour publier un commentaire.
Texte De L'Invite fonctionne avec un JPasswordField.
Une différence, c'est que de l'affichage de l'icône disparaît lorsque le texte est entré. Si vous voulez l'icône d'être permanente, alors je vous suggère de créer un personnalisé "IconBorder* classe de peindre une Icône, plutôt que de faire de la peinture custom dans le paintComponent() de la méthode.
Vous approche ne fonctionnera pas à moins que vous dupliquer le code pour les deux component swing jtextfield et JPasswordField.
Edit:
Fait, vous n'avez pas besoin de créer un personnalisé IconBorder. Le MatteBorder prend en charge la peinture de l'Icône dans une Bordure.
Vous pouvez créer un CompoundBorder. Utilisation de l'original de la frontière, la Frontière extérieure et d'utiliser ensuite un MatteBorder avec une Icône comme l'intérieur des Frontières
claire et straightforwardm, merci
OriginalL'auteur camickr
Afin de peindre une icône à l'intérieur d'un champ de texte, vous devez ajouter des encarts.
Vous ne voulez pas coder en dur des encarts dans votre composant, mais juste ajouter un petit peu d'espace pour l'icône, laissant les clients et les sous-classes afin de définir leurs propres.
Dans la figure ci-dessus, j'ai peint d'origine des encarts dans le vert et supplémentaires des encarts dans le rouge. La première chose que vous voulez étendre component swing jtextfield. Nous gardons la trace de deux choses: l'origine des encarts (les verts)
mBorder
, et l'icône.Alors vous avez besoin pour remplacer
setBorder()
méthode.Ici, si nous avons une icône (le champ
mIcon
n'est pasnull
), nous ajoutons nos autres encarts à l'aide d'un composé de la frontière. Ensuite, vous devriez également de remplacer lepaintComponent()
méthode.Enfin, vous avez besoin d'un
setIcon()
méthode.Ce que nous faisons ici est de sauver de l'icône et de recalculer les frontières.
Si vous voulez faire la même chose même chose avec
JPasswordField
, le plus élégant chose est probablement de créer une classe d'assistance avec toutes les méthodes décrites ci-dessus.Et de l'utiliser comme ça.
OriginalL'auteur mneri