I'm implementing the component of this topic along with the following instruction:
PromptSupport.setPrompt("Digite..", field);
This command is from biblioteca swingx-core-1.6.2
and adds a kind of placeholder
. But using it together with the FocusListener
event of a IconTextField
it gives me the following error:
Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError at javax.swing.text.DefaultCaret$Handler.propertyChange(DefaultCaret.java:1846) at java.beans.PropertyChangeSupport.fire(PropertyChangeSupport.java:335) at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:327) at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:263) at java.awt.Component.firePropertyChange(Component.java:8428) at javax.swing.JComponent.setBorder(JComponent.java:1796) at geral.IconTextField.setBorder(IconTextField.java:45) at org.jdesktop.swingx.plaf.BuddyLayoutAndBorder.replaceBorderIfNecessary(BuddyLayoutAndBorder.java:56) at org.jdesktop.swingx.plaf.BuddyLayoutAndBorder.propertyChange(BuddyLayoutAndBorder.java:245) at java.beans.PropertyChangeSupport.fire(PropertyChangeSupport.java:335) at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:328) at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:263) at java.awt.Component.firePropertyChange(Component.java:8428) at javax.swing.JComponent.setBorder(JComponent.java:1796) at geral.IconTextField.setBorder(IconTextField.java:45) at org.jdesktop.swingx.plaf.BuddyLayoutAndBorder.replaceBorderIfNecessary(BuddyLayoutAndBorder.java:56) at org.jdesktop.swingx.plaf.BuddyLayoutAndBorder.propertyChange(BuddyLayoutAndBorder.java:245) at java.beans.PropertyChangeSupport.fire(PropertyChangeSupport.java:335) at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:328) at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:263) at java.awt.Component.firePropertyChange(Component.java:8428) at javax.swing.JComponent.setBorder(JComponent.java:1796) at geral.IconTextField.setBorder(IconTextField.java:45)
What can I do to resolve?
Library Link (scroll down the page, and download the 1st link)
Below I'll leave the classes I'm using:
Main class:
public class JTextFieldDecoratedIcon {
public void start() throws IOException {
final JFrame frame = new JFrame();
frame.setPreferredSize(new Dimension(500, 350));
JTextField field2 = new JTextField();
IconTextField field = new IconTextField();
URL path = new URL("https://i.imgur.com/WKfl8uV.png");
Image icone = ImageIO.read(path);
field.setIcon(new ImageIcon(icone));
frame.add(field, BorderLayout.NORTH);
field.setPreferredSize(new Dimension(250, 30));
//bibilioteca swingx-core-1.6.2 ↓
PromptSupport.setPrompt("Digite..", field);
frame.add(field2, BorderLayout.SOUTH);
field2.setPreferredSize(new Dimension(100, 30));
field.addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
field.setBorder(new LineBorder(new Color(108, 85, 255)));
field.setBackground(Color.LIGHT_GRAY);
}
@Override
public void focusLost(FocusEvent e) {
field.setBorder(new LineBorder(Color.GRAY));
field.setBackground(new Color(255, 255, 255));
}
});
frame.pack();
frame.setVisible(true);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
EventQueue.invokeLater(() -> {
try {
new JTextFieldDecoratedIcon().start();
} catch (IOException ex) {
ex.printStackTrace();
}
});
}
}
Class IconTextComponentHelper:
class IconTextComponentHelper {
private static final int ICON_SPACING = 4;
private Border mBorder;
private Icon mIcon;
private Border mOrigBorder;
private JTextComponent mTextComponent;
IconTextComponentHelper(JTextComponent component) {
mTextComponent = component;
mOrigBorder = component.getBorder();
mBorder = mOrigBorder;
}
Border getBorder() {
return mBorder;
}
void onPaintComponent(Graphics g) {
if (mIcon != null) {
Insets iconInsets = mOrigBorder.getBorderInsets(mTextComponent);
mIcon.paintIcon(mTextComponent, g, iconInsets.left, iconInsets.top);
}
}
void onSetBorder(Border border) {
mOrigBorder = border;
if (mIcon == null) {
mBorder = border;
} else {
Border margin = BorderFactory.createEmptyBorder(0, mIcon.getIconWidth() + ICON_SPACING, 0, 0);
mBorder = BorderFactory.createCompoundBorder(border, margin);
}
}
void onSetIcon(Icon icon) {
mIcon = icon;
resetBorder();
}
private void resetBorder() {
mTextComponent.setBorder(mOrigBorder);
}
}
IconTextField class:
public class IconTextField extends JTextField {
private IconTextComponentHelper mHelper = new IconTextComponentHelper(this);
public IconTextField() {
super();
}
public IconTextField(int cols) {
super(cols);
}
private IconTextComponentHelper getHelper() {
if (mHelper == null) {
mHelper = new IconTextComponentHelper(this);
}
return mHelper;
}
@Override
protected void paintComponent(Graphics graphics) {
super.paintComponent(graphics);
getHelper().onPaintComponent(graphics);
}
public void setIcon(Icon icon) {
getHelper().onSetIcon(icon);
}
public void setIconSpacing(int spacing) {
//getHelper().onSetIconSpacing(spacing);
}
@Override
public void setBorder(Border border) {
getHelper().onSetBorder(border);
super.setBorder(getHelper().getBorder());
}
}