java 为什么我的JLabel被绘制了两次,但是当我最小化并打开框架时,它是正确的?

hc8w905p  于 2023-01-04  发布在  Java
关注(0)|答案(1)|浏览(115)

我必须为学校编写一个Java游戏。我想创建一个框架,在其中我简要地解释了机制。然而,应该这样做的JLabel被绘制了两次。当我关闭框架并再次打开它时,它正确地显示了。我真的不知道这是为什么。

int panelWidth = 16*16*3 + 300 + 3;
int panelHeight = 16*13*3;
        
JPanel textPanel = new JPanel();
textPanel.setLayout(null);
textPanel.setBounds(0, 0, 2*panelWidth/5, panelHeight);
textPanel.setOpaque(true);
textPanel.setBackground(new Color(0,0,0,0));
        
        JPanel bilderPanel = new JPanel(null){
            /**
             * 
             */
            private static final long serialVersionUID = 1L;

            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                BufferedImage background = null;
                BufferedImage image1 = null;
                BufferedImage image2 = null;
                try {
                    background = ImageIO.read(getClass().getResource("/Screens/ShovelKnightSplash.png"));
                    image1 = ImageIO.read(getClass().getResource("/Screens/ShovelKnightSplash.png"));
                    image2 = ImageIO.read(getClass().getResource("/Screens/ShovelKnightSplash.png"));
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                
                int margin = 15;
                int withPicture =  3*panelWidth/5 - 2*margin;
                int heightPicture = panelHeight /2 - 2*margin;
                
                //g.drawImage(background, -3*panelWidth/5, 0, panelWidth + 300, panelHeight, null);
                
                g.drawImage(image1, margin/2, 0*heightPicture + 1*margin/2, withPicture, heightPicture, null);
                g.drawImage(image2, margin/2, 1*heightPicture + 2*margin/2, withPicture, heightPicture, null);
            }
        };
        bilderPanel.setBounds(2*panelWidth/5, 0, 3*panelWidth/5, panelHeight);
        bilderPanel.setOpaque(true);
        bilderPanel.setBackground(new Color(0,0,0,0));
        //bilderPanel.setBackground(Color.blue);
        
        panel.add(textPanel);
        panel.add(bilderPanel);
        
        JLabel Uberschrift = new JLabel();
        Uberschrift.setText("Das Spiel");
        Uberschrift.setBounds(25, 20, 200, 50);
        Uberschrift.setFont(new Font("Arial", Font.PLAIN, 25));
        
        
        JLabel Controls = new JLabel();
        Controls.setText("<html><body>"
                + "Controls:<br>"
                + "W,A,S,D -> Bewegen<br>"
                + "Leertaste -> Menü Öffnen<br>"
                + "</body></html>");
        Controls.setBounds(25, panelHeight - 250, 2*panelWidth/5 - 50, 150);
        Controls.setFont(new Font("Arial", Font.PLAIN, 18));
        
        JLabel text = new JLabel();
        text.setText("<html><main>"
                + "Die Geschichte spielt in einer offenen Welt, "
                + "doch neben Ruinen gibt es auch mehrere intakte und bewohnte Städte. Die Welt "
                + "umfasst verschiedene Landschaftstypen wie zum Beispiel weite Wiesen, Wälder, "
                + "Berge und Wüsten."
                + "Von Monstern befallen, ist es die Aufgabe von dir"
                + "und deinem Partner die einzelnen Städte zurückzu erobern"
                + ""
                + ""
                + "Es gibt 5 MiniBosse und einen Endboss, welcher sich in der Mitte der Welt befindet"
                + "Man kann ihn bekämpfen, wann man will. Man ist frei in seinem tun."
                + "Allerdings erleichtert es einem das Spielgeschehen, wenn man sich zuvor mit Items aufrüstet"
                + "und LVL sammelt. Für jeden besiegten MiniBoss wird der Endeboss zunehmend geschwächt."
                + "</main></html>");
        text.setBounds(25, 10, 2*panelWidth/5 - 50, 400);
        text.setFont(new Font("Arial", Font.PLAIN, 15));
        
        textPanel.add(Uberschrift);
        textPanel.add(Controls);
        textPanel.add(text);

右边的图片看起来有点奇怪,但那是因为我还没有用实际的图片来替换它们。
我想创建3个JLabel:

  • 一个给头条
  • 一个用于文本块
  • 一个解释控制

因为我希望文本在某些点上断开,所以我使用了HTML代码。这可能是问题所在,但我不确定,也不知道如何开始找到问题。

bkhjykvo

bkhjykvo1#

Swing组件不知道如何处理基于alpha的颜色(即new Color(0,0,0,0)),它们要么透明要么不透明。
相反,请使用JComponent#setOpaque
不要在绘制方法中执行阻塞或长时间运行的操作。绘制应该被优化以尽可能快地运行,否则你的程序可能会React迟钝和/或滞后。
不要使用null布局,这些布局只会继续给你带来问题。相反,使用布局管理API。更多细节请参见Laying Out Components Within a Container

可运行示例...

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;

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

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    JFrame frame = new JFrame();
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                } catch (IOException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() throws IOException {
            int panelWidth = 16 * 16 * 3 + 300 + 3;
            int panelHeight = 16 * 13 * 3;

            setLayout(new GridBagLayout());

            JPanel textPanel = new JPanel();
            textPanel.setLayout(new GridBagLayout());
            textPanel.setOpaque(false);

            JPanel bilderPanel = new BackgroundPane();
            bilderPanel.setOpaque(false);

            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 1;
            gbc.gridy = 0;
            gbc.gridheight = gbc.REMAINDER;
            gbc.weighty = 1;
            gbc.weightx = 1;
            gbc.fill = gbc.BOTH;

            add(bilderPanel, gbc);

            JLabel Uberschrift = new JLabel();
            Uberschrift.setText("Das Spiel");
            Uberschrift.setFont(new Font("Arial", Font.PLAIN, 25));

            JLabel Controls = new JLabel();
            Controls.setText("<html><body>"
                    + "Controls:<br>"
                    + "W,A,S,D -> Bewegen<br>"
                    + "Leertaste -> Menü Öffnen<br>"
                    + "</body></html>");
            Controls.setFont(new Font("Arial", Font.PLAIN, 18));

            JTextArea text = new JTextArea();
            text.setText(
                    "Die Geschichte spielt in einer offenen Welt, \n"
                    + "doch neben Ruinen gibt es auch mehrere intakte und bewohnte Städte. Die Welt \n"
                    + "umfasst verschiedene Landschaftstypen wie zum Beispiel weite Wiesen, Wälder, \n"
                    + "Berge und Wüsten.\n"
                    + "Von Monstern befallen, ist es die Aufgabe von dir\n"
                    + "und deinem Partner die einzelnen Städte zurückzu erobern\n"
                    + "\n"
                    + "\n"
                    + "Es gibt 5 MiniBosse und einen Endboss, welcher sich in der Mitte der Welt befindet\n"
                    + "Man kann ihn bekämpfen, wann man will. Man ist frei in seinem tun.\n"
                    + "Allerdings erleichtert es einem das Spielgeschehen, wenn man sich zuvor mit Items aufrüstet\n"
                    + "und LVL sammelt. Für jeden besiegten MiniBoss wird der Endeboss zunehmend geschwächt.\n");
            text.setFont(new Font("Arial", Font.PLAIN, 15));
            text.setEditable(false);
            text.setFocusable(false);
            text.setOpaque(false);

            gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            add(textPanel, gbc);

            gbc = new GridBagConstraints();
            gbc.anchor = GridBagConstraints.LINE_START;
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.insets = new Insets(32, 32, 16, 32);
            textPanel.add(Uberschrift, gbc);

            gbc.gridy = 1;
            gbc.insets = new Insets(16, 32, 16, 32);
            textPanel.add(text, gbc);

            gbc.gridy = 2;
            gbc.insets = new Insets(16, 32, 32, 32);
            textPanel.add(Controls, gbc);

        }

        protected class BackgroundPane extends JPanel {
            private BufferedImage background = null;
            private BufferedImage image1 = null;
            private BufferedImage image2 = null;

            public BackgroundPane() throws IOException {
                background = ImageIO.read(getClass().getResource("/images/Mando01.jpeg"));
                image1 = background;
                image2 = background;
            }

            @Override
            public Dimension getPreferredSize() {
                int panelWidth = 16 * 16 * 3 + 300 + 3;
                int panelHeight = 16 * 13 * 3;
                return new Dimension(panelWidth, panelHeight);
            }

            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);

                System.out.println(getPreferredSize());

                int margin = 15;
                int withPicture = 3 * getWidth() / 5 - 2 * margin;
                int heightPicture = getHeight() / 2 - 2 * margin;

                g.drawImage(background, -3 * getWidth() / 5, 0, getWidth() + 300, getHeight(), this);
                g.drawImage(image1, margin / 2, 0 * heightPicture + 1 * margin / 2, withPicture, heightPicture, this);
                g.drawImage(image2, margin / 2, 1 * heightPicture + 2 * margin / 2, withPicture, heightPicture, this);
            }

        }

    }
}

相关问题