Is there a way for a JTextField in an 11x11 grid to have a background object, such as a circle or square?

StackOverflow https://stackoverflow.com/questions/23306180

  •  09-07-2023
  •  | 
  •  

Question

Here's an 11x11 grid of JTextField objects I've made.

Here's a grid I've made

The colors are nice, but Shapes would be better (or both): enter image description here

I don't think there is any way to add an existing shape (e.g., .PNG) to a JTextField or a JPanel, is there? What should I do? I haven't yet ventured into Graphics class and I'd rather not, just now. But if that's the only way, OK.

Was it helpful?

Solution

I'm assuming that the user will be typing in the single character of each text field. There are a couple of possibilities:

1) Create an IconBorder. This would simply paint your supplied Icon on top of the text field. Simple proof of concept:

import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
import javax.swing.border.*;

public class IconBorder implements Border
{
    private Icon icon;
    private Insets borderInsets = new Insets(0, 0, 0, 0);

    public IconBorder(Icon icon)
    {
        this.icon = icon;
    }
//
//  Implement the Border interface
//
    @Override
    public Insets getBorderInsets(Component c)
    {
        return borderInsets;
    }

    @Override
    public boolean isBorderOpaque()
    {
        return false;
    }

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

    private static void createAndShowUI()
    {
        JPanel panel = new JPanel();
        panel.add( createTextField( new Ellipse2D.Double(0, 0, 30, 30) ) );

        JFrame frame = new JFrame("SSCCE");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add( panel );
        frame.setLocationByPlatform( true );
        frame.pack();
        frame.setVisible( true );
    }

    private static JTextField createTextField(Shape shape)
    {
        JTextField textField = new JTextField(1);
        textField.setFont( new Font("Serif", Font.PLAIN, 18) );

        OutlineIcon icon = new OutlineIcon(shape, Color.RED, 2);
        CompoundBorder inner = new CompoundBorder( textField.getBorder(), new EmptyBorder(5, 10, 5, 10) );
        CompoundBorder border = new CompoundBorder(new IconBorder(icon), inner);
        textField.setBorder( border );

        return textField;
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowUI();
            }
        });
    }
}

The above code uses the OutlineIcon class found in Playing With Shapes to provide the Icon for the Border. Or you can use any "transparent" Icon that you have lying around.

But as you can see there is a lot of playing around with insets to try to get the text aligned properly. If you want to go with the Border approach, it may be better to create a "CircleBorder" and a "SquareBorder", then you can just paint the shape directly in the paintBorder(...) method and do the painting based on the size of the parent component.

2) Another approach would be to use a JLabel with an Icon. You can set the properties of the JLabel such that the text is both horizontally and vertically centered so that it paints on top of the label. In order to support keyboard input, you would then need to make each label focusable and add a KeyListener to listen for the key pressed and then set the text of the label. (I like this approach as the sizing of the components will be done easily based on the size of the Icon that you use).

3) Or finally you could use a JLabel with an Icon like above. But then you could set the layout manager to a BorderLayout and then add your JTextField to the label. You would need to make the JTextField non-opaque.

OTHER TIPS

You can add an image to a JLabel. There is a constructor that takes an Icon as a parameter. This Icon could be something like an ImageIcon, which has a constructor that takes a filename to display.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top