0

I experimented with MatteBorder in order to display an icon at the start of a JTextField (similiar to search icons being displayed in a textfield).

This is my current implementation:

JTextField textField = new JTextField("Filter", 8);
textField.setPreferredSize(new Dimension(getPreferredSize().width, 24));
Border outer = textField.getBorder();
// ugly workaround
Border padding = BorderFactory.createEmptyBorder(2, 2, 2, 2);
Border search = new MatteBorder(0, 16, 0, 0, icon);
textField.setBorder(new CompoundBorder(new CompoundBorder(outer, padding), search));

The icon is a 16x16px icon with no whitespace around it. The textfield is 24px high. I introduced a padding Border to have some whitespace around the icon (otherwise it would display a full icon and the first 4px of the icon under it). My problem is that there is no whitespace to the right of the icon (where the user enters text).

Question: Is there a way to have a defined amount of whitespace around the image, so it does not tile? Can I somehow add "padding" around the icon before I add it to the MatteBorder?

P.S. I know that I could add whitespace around the image file, but it is used in other instances where there should not be any whitespace around it.

Nash
  • 452
  • 1
  • 4
  • 16
  • 1) For better help sooner, post a [MCVE] or [Short, Self Contained, Correct Example](http://www.sscce.org/). 2) One way to get image(s) for an example is to hot link to images seen in [this Q&A](http://stackoverflow.com/q/19209650/418556). – Andrew Thompson Jun 15 '18 at 12:42

2 Answers2

2

Since a MatteBorder always tiles the icon, I would not use it. I would just write a custom border:

static void updateBorder(JTextField textField,
                         Icon icon) {

    Border iconBorder = new AbstractBorder() {
        private static final long serialVersionUID = 1;

        @Override
        public Insets getBorderInsets(Component c,
                                      Insets insets)
        {
            insets.left = icon.getIconWidth() + 4;
            insets.right = insets.top = insets.bottom = 0;
            return insets;
        }

        @Override
        public void paintBorder(Component c,
                                Graphics g,
                                int x,
                                int y,
                                int width,
                                int height)
        {
            icon.paintIcon(c, g,
                x, y + (height - icon.getIconHeight()) / 2);
        }
    };

    Border oldBorder = textField.getBorder();

    // Inside text field's original border, place icon border
    // with a little empty space around it.
    textField.setBorder(BorderFactory.createCompoundBorder(
        oldBorder,
        BorderFactory.createCompoundBorder(
            BorderFactory.createEmptyBorder(2, 2, 2, 2),
            iconBorder)));
}
VGR
  • 40,506
  • 4
  • 48
  • 63
1

My problem is that there is no whitespace to the right of the icon (where the user enters text).

How about using a second CompoundBorder to add extra space on the inside of the Border?

Another possiblility is to use the Component Border which allows you to add a component to a Border. So you could add a JLabel with an Icon.

camickr
  • 321,443
  • 19
  • 166
  • 288