有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java无法在JFrame上绘制

我在JFrame上绘制JLabel时遇到问题。我已经在另一个项目中这样做了,它工作正常,但这次我把某个地方搞砸了,不能再画画了。这是我的密码:

董事会:

import javax.swing.*;
import java.awt.*;

public class Board extends JPanel {

public Board() {
    initBoard();
}

private void initBoard() {
    setPreferredSize(new Dimension(Frame.GAME_WIDTH, Frame.GAME_HEIGHT));
    setMinimumSize(new Dimension(Frame.GAME_WIDTH, Frame.GAME_HEIGHT));
    setMaximumSize(new Dimension(Frame.GAME_WIDTH, Frame.GAME_HEIGHT));
    setBackground(Color.GRAY);
    setDoubleBuffered(true);
  }
}

框架:

import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.Border;
import java.awt.*;
import java.io.File;
import java.io.IOException;

public class Frame extends JFrame {

    public static final int GAME_WIDTH = 800;
    public static final int GAME_HEIGHT = 600;
    private final String title = "title here";

    private Image backgroundIMG;

    public Frame() {
        initUI();
    }

    private void initUI() {
        add(new Board());
        pack();
        setTitle(title);
        setSize(GAME_WIDTH, GAME_HEIGHT);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);

        setResizable(false);
        setLayout(null);


        /*
         * set background image
         */
        /*try {
            this.backgroundIMG = ImageIO.read(new File("src/to/image"));
        } catch (IOException e) {
            e.printStackTrace();
        }*/

        Border emptyBorder = BorderFactory.createEmptyBorder();

        int titleWidth = 270;
        int titleHeight = 55;
        int titleX = 24;
        int titleY = 30;
        int titleSize = 47;
        String titleFont = "Ravie";

        /*
         * Customize the startscreen
         */
        JLabel title = new JLabel("text");
        title.setBounds(0, 0, titleWidth, titleHeight);
        title.setFont(new Font(titleFont, Font.BOLD, titleSize));
        title.setForeground(new Color(251,102,8));
        title.setLocation(titleX, titleY);
        add(title);
        System.out.println("title should be printed");
    }
}

发射器:

import java.awt.*;

public class Launcher {

    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            Frame main = new Frame();
            main.setVisible(true);
        });
    }
}

启动程序时,帧正在加载,但不显示JLabel。它还在控制台上打印“应该打印标题”。我已经做了一些研究,但没有找到任何对我有帮助的东西。也许这只是个小错误,有人能很快帮我解决

提前谢谢


共 (1) 个答案

  1. # 1 楼答案

    暂时忘掉所有“有趣”的东西,你的基本问题归结到这

    add(new Board());
    //... 
    add(title);
    

    Java/Swing paint的组件是按后进先出顺序绘制的,所以最后添加的组件是第一个绘制的组件

    最合理的修复方法可能是将title添加到Board中,但您可能需要先修复几个其他问题

    • 避免从顶级容器(如JFrame)进行扩展。原因很多,但主要是,您没有向类添加新功能,而是将您锁定在一个用例中,通过其他方式/组件可以更好地管理该用例
    • 避免setPreferred/Minimum/MaximumSize。这些比它们的价值更麻烦。而是根据需要重写getPreferredSize
    • setDoubleBuffered(true);是没有意义的,因为Swing组件在默认情况下是双缓冲的
    • 避免null版面,说真的,这是人们发布的大多数问题的头号原因。布局管理API的存在是有原因的,请学习如何使用它

    如果我们把所有这些都考虑进去,你可能最终会陷入更像

    Possible solution

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.Font;
    import java.awt.Image;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    
    public class Test {
    
        public static void main(String[] args) {
            new Test();
        }
    
        private final String title = "title here";
    
        public Test() {
            EventQueue.invokeLater(() -> {
                JFrame main = new JFrame(title);
                main.add(new MainPane());
                main.pack();
                main.setLocationRelativeTo(null);
                main.setVisible(true);
            });
        }
    
        public static final int GAME_WIDTH = 800;
        public static final int GAME_HEIGHT = 600;
    
        public static class MainPane extends JPanel {
    
            private Image backgroundIMG;
    
            public MainPane() {
                setLayout(new BorderLayout());
    
                setBackground(Color.GRAY);
    
                add(new Board());
    
                String titleFont = "Ravie";
                int titleSize = 47;
                JLabel title = new JLabel("text");
                title.setHorizontalAlignment(JLabel.CENTER);
                title.setFont(new Font(titleFont, Font.BOLD, titleSize));
                title.setForeground(new Color(251, 102, 8));
                add(title, BorderLayout.NORTH);
            }
        }
    
        public static class Board extends JPanel {
    
            public Board() {
                initBoard();
            }
    
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(GAME_WIDTH, GAME_HEIGHT);
            }
    
            private void initBoard() {
                setBackground(Color.GRAY);
            }
        }
    
    }