3

I have a large java program with a JFrame window where I need to make a transparent background, but this is only possible without my scroll pane (see the following test program and picture):

//TransparentWindow.java

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

public class TransparentWindow extends JFrame
{
    JMenuBar menuBar;
    TransparentCanvas canvas;
    JComponent pane;
    JScrollPane scrollPane;

    public TransparentWindow() 
    {
      setBackground(new Color(0,0,0,0));
      setSize(new Dimension(500,500));
      setLocationRelativeTo(null); //set location at the center
      setTitle("Transparency");
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      menuBar = new JMenuBar();
      setJMenuBar(menuBar);
      JMenu help = new JMenu("Help");
      menuBar.add(help);
      canvas = new TransparentCanvas();
      pane = (JComponent)this.getContentPane();
      pane.add(canvas);
      //scrollPane = new JScrollPane(canvas);
      //pane.add(scrollPane, BorderLayout.CENTER);
    }

    public static void main(String[] args) 
    {
      JFrame.setDefaultLookAndFeelDecorated(true);

      TransparentWindow transparentWindow = new TransparentWindow();
      transparentWindow.setVisible(true);
    }

    class TransparentCanvas extends JComponent 
    {
      public TransparentCanvas()
      {
        super();            
        setPreferredSize(new Dimension(500,500));
      }

      @Override
      public void paintComponent(Graphics g) 
      {
        super.paintComponent(g);
        Graphics2D g2D = (Graphics2D)g;
        g2D.setColor(new Color(240, 240, 240, 128));
        g2D.fillRect(0, 0, getWidth(), getHeight());
        g2D.setColor(Color.blue);
        g2D.fillOval(200, 150, 100, 100);
        g2D.dispose();
      }
    }
}

Transparent window

transparent window

With the JScrollPane (by un-commenting the two lines at the end of the constructor above) you get opaque colors (see the following picture):

Opaque window

opaque window

And calling setUndecorated(true) does not make it work either. (By the way, I need to use Java 7, because of some other application.)

Please help. Thanks in advance for your time!

RubioRic
  • 2,442
  • 4
  • 28
  • 35

2 Answers2

3

Most Swing components are opaque, but JScrollPane is a little different, it's actually a composite component, made up of a JScrollPane and a JViewPort (and scrollbars) which is used to display a portion of the viewComponent.

To make it work the way you want it to, you need to make the JScrollPane and the JViewPort transparent, for example

Transparent

scrollPane = new JScrollPane(canvas);
scrollPane.setOpaque(false);
scrollPane.getViewport().setOpaque(false);
pane.add(scrollPane, BorderLayout.CENTER);

Full runnable example...

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JScrollPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TransparentWindow extends JFrame {

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                TransparentWindow transparentWindow = new TransparentWindow();
                transparentWindow.setVisible(true);
                transparentWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                transparentWindow.setVisible(true);
            }
        });
    }

    JMenuBar menuBar;
    TransparentCanvas canvas;
    JComponent pane;
    JScrollPane scrollPane;

    public TransparentWindow() {
        setUndecorated(true);
        setBackground(new Color(0, 0, 0, 0));
        setSize(new Dimension(500, 500));
        setLocationRelativeTo(null); //set location at the center
        setTitle("Transparency");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        menuBar = new JMenuBar();
        setJMenuBar(menuBar);
        JMenu help = new JMenu("Help");
        menuBar.add(help);
        canvas = new TransparentCanvas();
        pane = (JComponent) this.getContentPane();
        pane.add(canvas);
        scrollPane = new JScrollPane(canvas);
        scrollPane.setOpaque(false);
        scrollPane.getViewport().setOpaque(false);
        pane.add(scrollPane, BorderLayout.CENTER);
    }

    class TransparentCanvas extends JComponent {

        public TransparentCanvas() {
            super();
            setPreferredSize(new Dimension(500, 500));
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2D = (Graphics2D) g;
            g2D.setColor(new Color(240, 240, 240, 128));
            g2D.fillRect(0, 0, getWidth(), getHeight());
            g2D.setColor(Color.blue);
            g2D.fillOval(200, 150, 100, 100);
            g2D.dispose();
        }
    }
}
Community
  • 1
  • 1
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • Wow, this is great! You have completely answered my question. Thanks a lot! By the way how can one paste the picture? I was only able to paste a link to it. – Brigit Ananya May 01 '16 at 06:48
  • I think you have to have over a certain amount of rep points before you can post them, the question has been edited, but is awaiting approval, so the images should show up soon – MadProgrammer May 01 '16 at 06:51
  • Thank you, MadProgrammer! Unfortunately, your solution only works for my test program; it does not yet work for my large program. I still get the message that the frame is decorated. I will have to find what the additional decorations are? One different thing is that in my large program the title looks a lot bigger (about 9mm high instead of 3mm high). I wonder why, because I think I just called setTitle("...")? – Brigit Ananya May 01 '16 at 07:27
  • Call setUndecortated(false) on the JFrame BEFORE you set its background – MadProgrammer May 01 '16 at 07:46
  • Unfortunately, as I mentioned in my original message, calling setUndecorated(true) does not make it work either: no transparency and a loss of my title border (which I need, because it also shows the zooming percentage). Is there way to call setOpaque(false) for the title border? – Brigit Ananya May 01 '16 at 08:04
  • *"Unfortunately, as I mentioned in my original message, calling setUndecorated(true) does not make it work either"* - Yeah it does, I pasted a full runnable example which works just fine. Remember, if you're using any look and feel which relies on the OS's frame decorations, you need to make it undecorated – MadProgrammer May 01 '16 at 08:05
  • Thanks, MadProgrammer, but my large program still does not work. And the test program even works without calling setUndecorated(true). Following your suggestion to make the scroll pane and its viewport opaque did the trick. I am not using any OS related look and feel. Does my large program have a problem with the title border? As I mentioned before, the title border is three times higher than in the test program. Why is that? I think I just called setTitle("..."). – Brigit Ananya May 01 '16 at 15:26
  • By the way, I like the three times higher title border, I don't want to make it smaller, I just like to solve any related problem with it. Stackoverflow gave me the message: Please avoid extended discussions in comments. Would you like to automatically move this discussion to chat? What does this mean, is this possible? – Brigit Ananya May 01 '16 at 16:18
  • I've never been able to make a transparent frame with a border, which means I've never used setTitle with one – MadProgrammer May 01 '16 at 20:10
  • Thanks for reponding, MadProgrammer. But even without setTitle, calling setUndecorated(true) still does not make my large program window transparent. Well, I am a mathematician, just wishing to get some programming help. – Brigit Ananya May 01 '16 at 20:37
  • With out the code to the "big program" it's hard to know what else to suggest, the only thing I can think of, is make sure that each and every container you use is set to transparent – MadProgrammer May 01 '16 at 20:43
0
panel.setBackground( new Color(r, g, b, a) );

the "a" is the alpha setting which is an opacity.

resource from this answer

Community
  • 1
  • 1
Sandun Chathuranga
  • 2,242
  • 2
  • 13
  • 27
  • Beware, Swing doesn't know how to deal with components which have an alpha based background, it only knows how to deal with opaque or transparent components – MadProgrammer May 01 '16 at 06:19
  • Yes, I have used the alpha setting in both, my JFrame (for making the window completely transparent) and my JComponent (for changing the amount of transparency chosen for the window). But this does not answer the problem that the JFrame cannot be made transparent if it has a scroll pane (which I need). – Brigit Ananya May 01 '16 at 06:35
  • Thanks a lot, MadProgrammer, for your suggestion to call setOpaque(false) for my JScrollPane and JViewport. This made my test program work completely. For my large program, the only other JComponents for which I had to call setOpaque(false) were my JScrollBars. And I did not have to make my canvas JComponent transparent or non-transparent, I just painted it with transparent or non-transparent background colors. – Brigit Ananya May 09 '16 at 06:16
  • But I had to make one more change for my large program, since there I am using BuffereImages with associated Graphics for painting. I had to make sure that if I paint transparent background colors, the BufferedImages need to be declared afresh with the associated Graphics, because one cannot paint transparency over transparency. Now also my large program works completely. – Brigit Ananya May 09 '16 at 06:17
  • And instead of calling setUndecorated(true) in the constructor of my JFrame I call setDefaultLookAndFeelDecorated(true) in my main method, and the program works and has a title bar. – Brigit Ananya May 09 '16 at 06:45
  • Actually, if I use transparent background colors, the BuffereImaged nees to be declared afresh with the associated Graphics, because the transparent background colors have to erase what was painted over before. – Brigit Ananya May 09 '16 at 15:17