【问题标题】:Why does Canvas as contentPane not paint opaque components that are added to the JFrame glasspane为什么 Canvas as contentPane 不绘制添加到 JFrame glasspane 的不透明组件
【发布时间】:2013-04-16 08:26:18
【问题描述】:

好的,我有一个Canvas(我使用它是因为它可以实现BufferedStrategy)。

我将我的Canvas 添加到我的JFrame contentPane,然后添加HUDPanel(这是一个JPanel,由另外两个JPanels 组成-JProgressBars 和JLabels - 向我的JFrames glassPane 显示健康和 chakara 条)。

HUD 上的所有组件都是不透明的。

现在,当我将 HUDPanel 添加到我的 JFrames glassPane 中时,以 Canvas 作为其 contentPane 的 2 个 JPanels 包含组件是不涂不透明:

但如果我在JFrame 中添加JPanel 而不是Canvas contentPane 一切正常:

这是为什么? 我该如何解决?

提前谢谢你

HUDPanelTest.java

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class HUDPanelTest {

    public HUDPanelTest() {
        initComponents();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new HUDPanelTest();
            }
        });
    }

    private void initComponents() {
        JFrame frame = new JFrame() {
            @Override
            public Dimension getPreferredSize() {//testing only
                return new Dimension(800, 600);
            }
        };
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        HUDPanel hudPanel = new HUDPanel();
        frame.setGlassPane(hudPanel);
        JPanel p = new JPanel() {
            @Override
            protected void paintComponent(Graphics grphcs) {
                super.paintComponent(grphcs);
                grphcs.setColor(Color.yellow);
                grphcs.fillRect(0, 0, getWidth(), getHeight());
            }
        };
        Canvas c = new Canvas() {
            @Override
            public void paint(Graphics grphcs) {//for testing ONLY I actually use a BufferStrategy
                super.paint(grphcs);

                grphcs.setColor(Color.yellow);
                grphcs.fillRect(0, 0, getWidth(), getHeight());
            }
        };

        frame.add(c);
        //frame.add(p);//this works as expected

        frame.pack();
        frame.setVisible(true);
        hudPanel.setVisible(true);

    }
}

HUDPanel.java

import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;

public class HUDPanel extends JPanel {

    HUDPanel.HealthPanel healthPanel;
    HUDPanel.ChakaraPanel chakaraPanel;

    public HUDPanel() {
        super(new BorderLayout(), true);
        setOpaque(false);

        healthPanel = new HUDPanel.HealthPanel();
        chakaraPanel = new HUDPanel.ChakaraPanel();

        initComponents();

        setHealthPlayer1(100);
        setHealthPlayer2(100);
        setChakaraPlayer1(0);
        setChakaraPlayer2(0);
        setLabelTextHealthPlayer1("Player 1 (Health):");
        setLabelTextHealthPlayer2("Player 2 (Health):");
        setLabelTextChakaraPlayer1("Player 1 (Chakara):");
        setLabelTextChakaraPlayer2("Player 2 (Chakara):");
    }

    private void initComponents() {
        add(healthPanel, BorderLayout.NORTH);
        add(chakaraPanel, BorderLayout.SOUTH);
    }

    public void setHealthPlayer1(int health) {
        healthPanel.setPlayer1ProgressBarValue(health);
    }

    public void setHealthPlayer2(int health) {
        healthPanel.setPlayer2ProgressBarValue(health);
    }

    public void setChakaraPlayer1(int chakara) {
        chakaraPanel.setPlayer1ProgressBarValue(chakara);
    }

    public void setChakaraPlayer2(int chakara) {
        chakaraPanel.setPlayer2ProgressBarValue(chakara);
    }

    public void setLabelTextHealthPlayer1(String text) {
        healthPanel.setPlayer1LabelText(text);
    }

    public void setLabelTextHealthPlayer2(String text) {
        healthPanel.setPlayer2LabelText(text);
    }

    public void setLabelTextChakaraPlayer1(String text) {
        chakaraPanel.setPlayer1LabelText(text);
    }

    public void setLabelTextChakaraPlayer2(String text) {
        chakaraPanel.setPlayer2LabelText(text);
    }

    private class HealthPanel extends JPanel {

        JProgressBar player1ProgressBar = new JProgressBar();
        JProgressBar player2ProgressBar = new JProgressBar();
        JLabel player1Label = new JLabel();
        JLabel player2Label = new JLabel();

        public HealthPanel() {
            super(new GridBagLayout(), true);
            setOpaque(false);

            initComponents();
        }

        private void initComponents() {
            GridBagConstraints gc = new GridBagConstraints();
            gc.fill = GridBagConstraints.NONE;
            gc.anchor = GridBagConstraints.WEST;
            gc.insets = new Insets(10, 10, 10, 10);
            //or else the anchoring wont work
            gc.weightx = 1;

            //gc.gridx = 0;//does not seem to make a difference
            //gc.gridy = 0;
            add(player1Label, gc);

            //gc.gridx = 1;
            //gc.gridy = 0;
            add(player1ProgressBar, gc);

            gc.anchor = GridBagConstraints.EAST;

            //gc.gridx = 2;
            //gc.gridy = 0;
            add(player2Label, gc);

            //gc.gridx = 3;
            //gc.gridy = 0;
            add(player2ProgressBar, gc);
        }

        public void setPlayer1ProgressBarValue(int val) {
            player1ProgressBar.setValue(val);
        }

        public void setPlayer2ProgressBarValue(int val) {
            player2ProgressBar.setValue(val);
        }

        public void setPlayer2LabelText(String text) {
            player2Label.setText(text);
        }

        public void setPlayer1LabelText(String text) {
            player1Label.setText(text);
        }
    }

    private class ChakaraPanel extends JPanel {

        JProgressBar player1ProgressBar = new JProgressBar();
        JProgressBar player2ProgressBar = new JProgressBar();
        JLabel player1Label = new JLabel();
        JLabel player2Label = new JLabel();

        public ChakaraPanel() {
            super(new GridBagLayout(), true);
            setOpaque(false);

            initComponents();
        }

        private void initComponents() {
            GridBagConstraints gc = new GridBagConstraints();
            gc.fill = GridBagConstraints.NONE;
            gc.anchor = GridBagConstraints.WEST;
            gc.insets = new Insets(10, 10, 10, 10);
            //or else the anchoring wont work
            gc.weightx = 1;
            gc.weighty = 1;

            //gc.gridx = 0;
            //gc.gridy = 0;
            add(player1Label, gc);

            //gc.gridx = 1;
            //gc.gridy = 0;
            add(player1ProgressBar, gc);

            gc.anchor = GridBagConstraints.EAST;

            //gc.gridx = 2;
            //gc.gridy = 0;
            add(player2Label, gc);

            //gc.gridx = 3;
            //gc.gridy = 0;
            add(player2ProgressBar, gc);
        }

        public void setPlayer1ProgressBarValue(int val) {
            player1ProgressBar.setValue(val);
        }

        public void setPlayer2ProgressBarValue(int val) {
            player2ProgressBar.setValue(val);
        }

        public void setPlayer2LabelText(String text) {
            player2Label.setText(text);
        }

        public void setPlayer1LabelText(String text) {
            player1Label.setText(text);
        }
    }
}

【问题讨论】:

标签: java swing opacity glasspane java-canvas


【解决方案1】:
  • GlassPane是轻量级的,那么总是在AWT Canvas之后,

  • 这对于JLayeredPaneGlassPane 和Java 和3DCAD/CAMOpen GL/Cl 来说是很常见的问题,这些API 基于AWT Containers

  • 使用 JLayer(轻量级容器)也会出现同样的问题,但您可以在 isLightWe....() 中测试来自 Native OS 和/或其资源的对等体

【讨论】:

  • +1 谢谢你的一些有趣的东西。所以 mKorbel 澄清一下我会使用 JLayeredPane 并添加我的 CanvasGlasspane 吗?或者我将如何解决这个问题(请我想为BufferedStrategy 使用Canvas,实现Window 将完全改变我的应用程序布局.....)因为它很糟糕多帧使用练习
  • 我从来没有尝试过 BufferedStrategy,我正在为 RepaintManager 烦恼,我也反对使用 JLayeredPane,很难描述一些建议,但 Swing 大师总是建议 Swing 容器更适合自定义绘画,确保有 3D、CAD/CAM、Open GL/CL 并且它们所需的资源来自 Native OS,那么只有使用 AWT 容器是一种可能的方式
  • 为什么不在JPanel 上使用默认的BufferStrategy?此外,构造函数不应调用可覆盖的方法。
  • @DavidKroukamp:引用了一些有启发性的对比示例here
  • 啊,我看到setIgnoreRepaint() 是“有用的……如果使用页面翻转作为缓冲策略。”
猜你喜欢
  • 2015-06-26
  • 1970-01-01
  • 2011-03-14
  • 2017-03-21
  • 2012-05-21
  • 1970-01-01
  • 2021-09-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多