【问题标题】:Cant paint on JFrame无法在 JFrame 上绘画
【发布时间】:2018-05-30 09:31:09
【问题描述】:

在我的 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);
        });
    }
}

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

提前致谢

【问题讨论】:

  • 我将 Board 添加到 JFrame 中,同时将背景涂成灰色

标签: java swing jframe jpanel jlabel


【解决方案1】:

暂时摆脱所有“有趣”的东西,你的基本问题归结为......

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

Java/Swing 绘制是 LIFO 顺序的组件,所以最后添加的组件是第一个绘制的组件。

可能最合乎逻辑的解决方法是将title 添加到Board,但您可能需要先解决一些其他问题...

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

如果我们将所有这些都考虑在内,您最终可能会遇到类似...

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

}

【讨论】:

  • 因为我刚刚开始学习 Java 及其 UI 组件,我非常感谢您的回答和对我的代码的改进。这对我帮助很大。
猜你喜欢
  • 1970-01-01
  • 2013-07-29
  • 2012-05-05
  • 2012-06-20
  • 2014-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多