Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Transparent border of JTextField in Swing

I have a searchfield in a JPanel. The JPanel has a background image. I want to place a JTextField in this panel, but the JTextField should have a tranparent border, so it has some padding to the top and bottom where you should see the background image of the panel.

I have a SSCCE here, where the panel has a blue background instead of a background image. I want the textfield to be white, but with a border around it, which let's you see the blue panel below it. A transparent border would be great, but EmptyBorder doesn't work. Here is the SSCCE:

import java.awt.BorderLayout;
import java.awt.Color;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class TransparentBorder
{

    public TransparentBorder()
    {
        //Create and set up the window.
        final JFrame frame = new JFrame("Transparent Border");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(600, 100);

        // set window size
        frame.setUndecorated(false);

        //P1
        final JPanel panel = new JPanel(new BorderLayout());
        panel.setBackground(Color.BLUE);

        final JButton btn = new JButton("Search");
        btn.setOpaque(false);
        panel.add(btn, BorderLayout.EAST);

        final JTextField field = new JTextField();

        field.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        //        field.setOpaque(false);
        panel.add(field);

        frame.add(panel);
        //Display the window.
        //        frame.pack();
        frame.setVisible(true);

    }

    public static void main(final String[] args)
    {
        //Schedule a job for the event-dispatching thread:
        //creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                new TransparentBorder();
            }
        });
    }
}

thanks a lot.


Thanks for your answer Guillaume. My JTextfield is inside a JPanel with Borderlayout but the NORTH and SOUTH part were not occupied. So I used Box.createVerticalStrut(10) and added it to NORTH and SOUTH. This also worked for me. But I keep your suggestion in mind, so I have another solution in case I use the NORTH and SOUTH for other components.

like image 682
haferblues Avatar asked Sep 17 '12 09:09

haferblues


1 Answers

The problem is the the TextUI automatically paints the whole background of the textfield, including the insets, if it is set to opaque (which is the default).

One simple trick is to wrap your textfield in another JPanel, set that JPanel to be non-opaque and set the border on that JPanel.

Your code updated with those infos:

import java.awt.BorderLayout;
import java.awt.Color;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class TransparentBorder {

    public TransparentBorder() {
        // Create and set up the window.
        final JFrame frame = new JFrame("Transparent Border");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(600, 100);

        // set window size
        frame.setUndecorated(false);

        // P1
        final JPanel panel = new JPanel(new BorderLayout());
        panel.setBackground(Color.BLUE);

        final JButton btn = new JButton("Search");
        btn.setOpaque(false);
        panel.add(btn, BorderLayout.EAST);
        JPanel wrappingPanel = new JPanel(new BorderLayout());
        wrappingPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        wrappingPanel.setOpaque(false);
        final JTextField field = new JTextField();
        field.setBorder(null);
        wrappingPanel.add(field);
        panel.add(wrappingPanel);

        frame.add(panel);
        frame.revalidate();
        // Display the window.
        // frame.pack();
        frame.setVisible(true);

    }

    public static void main(final String[] args) {
        // Schedule a job for the event-dispatching thread:
        // creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new TransparentBorder();
            }
        });
    }
}
like image 111
Guillaume Polet Avatar answered Nov 16 '22 01:11

Guillaume Polet