首页 文章

为什么Canvas as contentPane不会绘制添加到JFrame glasspane的不透明组件

提问于
浏览
1

好吧,我有 Canvas (我正在使用它,因为它可以实现 BufferedStrategy ) .

我将 Canvas 添加到我的 JFrame contentPane,然后添加 HUDPanel (这是一个 JPanel 由另外两个 JPanel s组成 - 带有 JProgressBar s和 JLabel s - 显示 Health 和chakara条形图)到我的 JFrame 的glassPane .

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

现在当我将 HUDPanel 添加到我的 JFrame 的glassPane中,其中 Canvas 作为其contentPane时,保存组件的2 JPanel 不会被涂成不透明:

enter image description here

但是,如果我添加一个 JPanel 而不是 CanvasJFrame contentPane一切正常:

enter image description here

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

先感谢您

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

1 回答

  • 2
    • GlassPane 是轻量级的,然后总是落后 AWT Canvas

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

    • 同样的问题将是使用 JLayer (轻量级容器),但你可以从 Native OS 和/或其资源中测试 isLightWe....() for peer

相关问题