java - 具有透明背景的可滚动 JFrame

标签 java swing

我有一个带有 JFrame 窗口的大型 java 程序,我需要在其中制作透明背景,但这只有在没有滚动 Pane 的情况下才有可能(参见下面的测试程序和图片):

//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

使用 JScrollPane(通过取消注释上面构造函数末尾的两行),你会得到不透明的颜色(见下图):

不透明窗口

opaque window

并且调用 setUndecorated(true) 也不会使它工作。 (顺便说一句,由于一些其他应用程序,我需要使用 Java 7。)

请帮忙。提前感谢您的宝贵时间!

最佳答案

大多数Swing组件都是不透明的,但是JScrollPane有点不同,它实际上是一个复合组件,由一个JScrollPane和一个JViewPort组成>(和滚动条)用于显示 viewComponent 的一部分。

要使其按您希望的方式工作,您需要使 JScrollPaneJViewPort 透明,例如

Transparent

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

完整的可运行示例...

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();
        }
    }
}

关于java - 具有透明背景的可滚动 JFrame,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36963558/

相关文章:

java - 如何抑制 m2e 警告?

java - 如何使 JTextField 根据输入更改其他框

java - MigLayout 用法

java - 如何组织和共享实用程序库/类(不是代码片段)

java - 不将对象的实例分配给变量是不好的做法吗?

java - 如何使用 GridBagLayout 制作单列按钮?

java - 当 Java Swing Action Listener 类扩展另一个类时,避免无限循环

java - 如何将 hibernate 与 MS Access 一起使用?

java - Tomcat 安装目录无效。它缺少预期的文件或文件夹 tcruntime-ctl.sh

java - .setBounds() 不适用于嵌套 JLabels