Search code examples
javaswingjpaneljtextfieldtransparent

Make JPanel background transparent without text overlapping


I am making something that resembles a subtitle player that will go over a video.

I would like to make the background transparent so that the box that the text is in will not interfere with the movie/TV show playing behind it. I have tried 2 ways to do this and each way results in the same problem. The text does not disappear when the next sentence appears. If the background is a color (Eg: Color.red), then this works fine. After a certain time, I call text.setText("next sentence"), but this does not work with a transparent background. The relevant code is as follows. text is a JTextField

I should mention the video is not in this program. This program is ONLY subtitles.

First way:

text.setBackground(new Color(0,0,0,0));

Second way: (using a transparent image)

Graphics c = myPicture.getGraphics();
text.paintAll(c); 

I update the text like this.

Thread.sleep(Graphix.subtitles.get(counter).getStart());
text.setText(Graphix.subtitles.get(counter).getText());

This also makes it overlap.

text.setForeground(Color.blue);
text.setBackground(new Color(0,0,0,0));
text.setOpaque(false);

The relevant code from Main is as follows.

final JFrame JFwindow = new JFrame("Subtitles");
JFwindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);    
JFwindow.getContentPane().add(new Subtitles()); 
JFwindow.setSize(1300, 150);
JFwindow.setUndecorated(true);
JFwindow.setBackground(new Color(0,0,0,0f));
JFwindow.pack();
JFwindow.setVisible(true);

Solution

    • Transparency is achieved by calling JPanel#setOpaque and passing it false.
    • You should NEVER be calling getGraphics. getGraphics and return null and is, at best, only as snap shot. Once the RepaintManager starts a new paint cycle, the results of painting to it will be overridden.
    • Using a tarnsparent color will only confuse the RepaintManager as it won't know that it needs to paint under the component
    • Sleeping within the Event Dispatching Thread (EDT) will stop Swing from performing any updates (as well as process any events). Instead I'd recommend using a javax.swing.Timer. See Concurrency in Swing for more details.
    • If you're using the VLC bindings, then it can't be achieved
    • Don't forget to make all the parent containers that the sub titles are contained in transparent as well