【问题标题】:How contents are made translucent in a JPanel?如何在 JPanel 中使内容变为半透明?
【发布时间】:2012-12-21 12:25:41
【问题描述】:

我对 JPanel 中组件的显示感到困惑。

假设如果我创建一个自定义 JPanel,其半透明度为 0.8f,如下所示:-

JPanel panel=new JPanel(){
        @Override
        public void paint(Graphics g)
        {
            super.paint(g);
            BufferedImage img=(BufferedImage)createImage(getWidth(),getHeight());
            Graphics2D g2=(Graphics2D) g.create();
            g2.setComposite(AlphaComposite.SrcOver.derive(0.8f));
            g2.drawImage(img,0,0,null);
        }
        @Override
        public Dimension getPreferredSize()
        {
            return new Dimension(300,300);
        }
    };

现在我将它设置为框架的 contentPane。

frame.setContentPane(panel);

现在我给它添加一些按钮。

    frame.add(new JButton("Click Here"));
    frame.add(new JButton("Click Here"));
    frame.add(new JButton("Click Here"));
    frame.add(new JButton("Click Here"));

1)那么在输出中为什么我得到半透明按钮?由于 JPanel 是单层的,当我覆盖其paint方法然后添加按钮时,我首先绘制半透明图像,因此按钮不能像它们应该的那样半透明过来吧。

2)在这 4 个按钮中也只有 2 个是半透明的。为什么会有这样的偏颇?

3)如果我在添加这 4 个按钮之前还添加了一个表格,那么一切都会变成半透明的。为什么?

Object[] names = new Object[] {
             "Title", "Artist", "Album"
         };
         String[][] data = new String[][] {
             { "Los Angeles", "Sugarcult", "Lights Out" },
             { "Do It Alone", "Sugarcult", "Lights Out" },
             { "Made a Mistake", "Sugarcult", "Lights Out" },
             { "Kiss You Better", "Maximo Park", "A Certain Trigger" },
             { "All Over the Shop", "Maximo Park", "A Certain Trigger" },
             { "Going Missing", "Maximo Park", "A Certain Trigger" }
         };
         JTable table = new JTable(data, names);
         frame.add(table); 

4)如果我为 JPanel 使用paintComponent(Graphics g),那么无论我是否添加表格或添加了多少按钮,都不会是半透明的。为什么?

(我问的是应用程序运行时的即时输出。我知道当鼠标悬停在这些按钮上或单击表格中的任何行时,它会变得不透明,这是由于 Swing 的绘画机制造成的。)

【问题讨论】:

  • 1) JPanel panel=new JPanel(){ @Override public void paint(Graphics g) { super.paint(g); 应该是 JPanel panel=new JPanel(){ @Override public void paintComponent(Graphics g) { super.paintComponent(g); 2) 为了尽快获得更好的帮助,请发布 SSCCE
  • 另外,不要忘记dispose() 任何您创建的Graphics 对象。
  • @AndrewThompson :请查看我更新的问题。最后一点 4。
  • 我编译了你的源代码,所有的按钮都是半透明的。也许这个教程会帮助http://docs.oracle.com/javase/tutorial/uiswing/painting/index.html

标签: java swing graphics awt


【解决方案1】:

1) 那么在输出中为什么我得到半透明按钮?由于 JPanel 是单一的 分层,当我覆盖它时,我首先绘制了半透明图像 绘制方法,然后添加按钮,按钮不得 应该是半透明的。

实际上,您在按钮上绘制了半透明效果。 paint 来电

  • paintComponent
  • paintBorder
  • paintChildren

然后你将半透明效果画在已经画过的东西(孩子们)的顶部。添加组件时不会有任何区别,Swing 会在多种情况下绘制组件,第一次是在组件首次实现时(在屏幕上可见)以及响应脏区域的更改(以及很多其他人)...不要自欺欺人,您无法控制...

将绘画过程视为一种分层方法。首先你画背景,然后你画中间地面,最后,前地面,然后你去泼水......

public class TestTranslucentControls {

    public static void main(String[] args) {
        new TestTranslucentControls();
    }

    public TestTranslucentControls() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private BufferedImage background;

        public TestPane() {
            setLayout(new GridBagLayout());
            try {
                background = ImageIO.read(new File("C:/Users/shane/Dropbox/MegaTokyo/poster.jpg"));
            } catch (IOException ex) {
                ex.printStackTrace();
            }
            add(new JButton("1"));
            add(new JButton("2"));
            add(new JButton("3"));
            add(new JButton("4"));
            add(new JButton("5"));
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (background != null) {
                Graphics2D g2 = (Graphics2D) g.create();
                g2.setComposite(AlphaComposite.SrcOver.derive(0.25f));
                int x = (getWidth() - background.getWidth()) / 2;
                int y = (getHeight() - background.getHeight()) / 2;
                g2.drawImage(background, x, y, this);
                g2.dispose();
            }
        }

        @Override
        public Dimension getPreferredSize() {
            return background == null ? new Dimension(300, 300) : new Dimension(background.getWidth(), background.getHeight());
        }
    }
}

我想你可能会发现...

有用 ;)

【讨论】:

    【解决方案2】:

    通常,您希望覆盖 paintComponent() 而不是 paint()。这可能是您的透明度问题的原因。其次,您可能想要更改布局。默认情况下,面板使用 FlowLayout。您可能想要使用 BorderLayout 或 GridBagLayout 或两者的混合。

    【讨论】:

    • :布局无效,请参阅我更新的问题。我添加了另一点 4。
    猜你喜欢
    • 1970-01-01
    • 2015-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多