简体   繁体   中英

Scrollable JFrame with transparent background

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

透明的窗户

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

不透明的窗户

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!

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

透明

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();
        }
    }
}
panel.setBackground( new Color(r, g, b, a) );

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

resource from this answer

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM