Note that there are some explanatory texts on larger screens.

plurals
  1. PODecorating a JTextField with an image and hint
    text
    copied!<p>I'm trying to create some nicer looking JTextFields with an image and a hint. To do this I made a decorator that overrides the paintComponent method. The reason I used a decorator is that I wanted to apply it to other types of JTextField such as JPasswordField. </p> <p>Here is what I've made so far;</p> <p><img src="https://i.stack.imgur.com/MLeUs.png" alt="enter image description here"></p> <p>The problem as seen in the form on the left is that, even though I have used a JPasswordField the paintComponent seems to ignore what I assume is the passwords paintComponent which presumably does the password masking symbols.</p> <p>So the question is, how can I avoid duplicating the code for JTextFields and JPasswordFields but still have the different functionality such as password masking.</p> <p>This is the decorator code;</p> <pre><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(); } } </code></pre> <p>And this is where I create the fields;</p> <pre><code>JTextField usernameField = new JTextFieldHint(new JTextField(),"user_green","Username"); JTextField passwordField = new JTextFieldHint(new JPasswordField(),"bullet_key","Password"); </code></pre> <p>Hopefully i've not went completely off in the wrong direction here!</p> <p>Thanks!</p> <p>EDIT : Again the more I look at it, it is obvious that calling super.paintComponent(g) is going to call the JTextFields paintcomponent, but I can't see how to solve this without duplicating the code.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload