无法在 JFrame 上绘画
Cant paint on 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。它还在控制台上打印 "title should be printed" 。我已经做了一些研究,但找不到任何对我有帮助的东西。也许这只是一个微不足道的错误,有人可以很快帮助我。
提前致谢
暂时忽略所有 "interesting" 内容,您的基本问题归结为这个...
add(new Board());
//...
add(title);
Java/Swing 以 LIFO 顺序绘制它的组件,所以最后添加的组件是第一个绘制的组件。
可能最合乎逻辑的解决方法是将 title
添加到 Board
,但您可能想先解决几个其他问题...
- 避免从顶级容器扩展,如
JFrame
。有很多原因,但主要是,您没有向 class 添加新功能,而是将您锁定在一个可以通过其他 means/components 更好地管理的用例中
- 避免
setPreferred/Minimum/MaximumSize
。这些麻烦多于它们的价值。相反,根据需要覆盖 getPreferredSize
setDoubleBuffered(true);
毫无意义,因为 Swing 组件默认是双缓冲的
- 避免
null
布局,严重的是,这是人们 post 关于 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);
}
}
}
我在 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。它还在控制台上打印 "title should be printed" 。我已经做了一些研究,但找不到任何对我有帮助的东西。也许这只是一个微不足道的错误,有人可以很快帮助我。
提前致谢
暂时忽略所有 "interesting" 内容,您的基本问题归结为这个...
add(new Board());
//...
add(title);
Java/Swing 以 LIFO 顺序绘制它的组件,所以最后添加的组件是第一个绘制的组件。
可能最合乎逻辑的解决方法是将 title
添加到 Board
,但您可能想先解决几个其他问题...
- 避免从顶级容器扩展,如
JFrame
。有很多原因,但主要是,您没有向 class 添加新功能,而是将您锁定在一个可以通过其他 means/components 更好地管理的用例中
- 避免
setPreferred/Minimum/MaximumSize
。这些麻烦多于它们的价值。相反,根据需要覆盖getPreferredSize
setDoubleBuffered(true);
毫无意义,因为 Swing 组件默认是双缓冲的- 避免
null
布局,严重的是,这是人们 post 关于 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);
}
}
}