为什么我的 Java repaint() 方法不起作用?
Why does my Java repaint() method not work?
嘿哟,为了我的大学作业,我需要画一些图像并与它们比赛,但我什至连画图像(或者在这种情况下是图标)都卡住了。我现在想在许多 JPanel 之一上绘制任何东西(这就是为什么我有 drawLine 方法,只是为了测试它),但我的 repaint() 方法不调用我的 paintComponent 方法,为什么?
import java.awt.*;
import javax.swing.*;
import java.lang.Math;
public class Races{
private int numberOfRacers;
public Races(int numberOfRacers){
this.numberOfRacers = numberOfRacers;
JFrame frame = new JFrame("Races - Name Surname");
Icon icon = new ImageIcon("races.jpg");
frame.setLayout(new GridLayout(numberOfRacers, 1));
frame.setSize(icon.getIconWidth()*20, (icon.getIconWidth()*2)*numberOfRacers);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
try{
Thread.sleep(1000); // Sleeping 1 sec
System.out.println("Sleeping one second for the user!");
}catch(InterruptedException ie){
System.out.println(ie);
}
for(int i = 0; i < numberOfRacers; i++){
innerRacer racer = new innerRacer();
frame.add(racer.panel);
//JLabel iconLabel = new JLabel(icon);
//iconLabel.setHorizontalAlignment(JLabel.LEFT);
//panel.add(iconLabel);
Thread t = new Thread(racer);
t.start();
}
}
public static void main(String args[]){
if(args.length > 0 && Integer.parseInt(args[0]) > 0 && Integer.parseInt(args[0]) < 100){
Races races = new Races(Integer.parseInt(args[0])); // From command line number of racers
System.out.println("Number of racers: " + args[0]);
}else{
Races races = new Races(5); // Default number of racers
System.out.println("Number of racers: 5");
}
}
public class innerRacer extends JPanel implements Runnable{
JPanel panel;
Icon icon;
public innerRacer(){
panel = new JPanel();
panel.setBackground(Color.WHITE);
icon = new ImageIcon("races.jpg");
} //end of innerRacer constructor
@Override
public void run(){
repaint();
System.out.println("TEST");
}
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g.drawLine(10, 20, 30, 40);
System.out.println("Why is this one not called?");
icon.paintIcon(panel, g, 0, 0);
}
} // end of innerRacer class
} //end of Races class
提前致谢。
您添加了 innerRacer
包含的 JPanel
而不是 innerRacer
包含的 JPanel
。
变化:
frame.add(racer.panel);
至:
frame.add(racer);
我还看到您在将框架设置为可见后向框架添加组件。当您在 AWT/Swing 中执行此操作时,它们不会自动布局或绘制。您需要遵循以下行:
frame.revalidate();
或者,setVisible
行可以下移。
一般说明:
- 坚持 Java 命名约定是个好主意 - 类型的首字母始终大写。
innerRacer
中的JPanel panel;
可以删除
- 应始终从 AWT 事件调度线程 (EDT) 访问 Swing 组件。使用
java.awt.EventQueue.invokeLater
.
- 很多教程建议在不添加任何组件的情况下覆盖
JPanel
如果您想绘制任何东西。这似乎是因为默认情况下它是不透明的。 JPanel
的 API 文档甚至 OpenJDK 源代码都没有提到不透明性。事实上,这并不能保证。这只是一个黑客。首选 setOpaque(true)
使组件不透明。
- 让一个 class 扩展另一个并实现一个接口(或实现多个接口(不是标记、
Comparable
等))并不是很好。根据需要使用 lambda 方法、方法引用、内部 class 或另一个外部 class。
嘿哟,为了我的大学作业,我需要画一些图像并与它们比赛,但我什至连画图像(或者在这种情况下是图标)都卡住了。我现在想在许多 JPanel 之一上绘制任何东西(这就是为什么我有 drawLine 方法,只是为了测试它),但我的 repaint() 方法不调用我的 paintComponent 方法,为什么?
import java.awt.*;
import javax.swing.*;
import java.lang.Math;
public class Races{
private int numberOfRacers;
public Races(int numberOfRacers){
this.numberOfRacers = numberOfRacers;
JFrame frame = new JFrame("Races - Name Surname");
Icon icon = new ImageIcon("races.jpg");
frame.setLayout(new GridLayout(numberOfRacers, 1));
frame.setSize(icon.getIconWidth()*20, (icon.getIconWidth()*2)*numberOfRacers);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
try{
Thread.sleep(1000); // Sleeping 1 sec
System.out.println("Sleeping one second for the user!");
}catch(InterruptedException ie){
System.out.println(ie);
}
for(int i = 0; i < numberOfRacers; i++){
innerRacer racer = new innerRacer();
frame.add(racer.panel);
//JLabel iconLabel = new JLabel(icon);
//iconLabel.setHorizontalAlignment(JLabel.LEFT);
//panel.add(iconLabel);
Thread t = new Thread(racer);
t.start();
}
}
public static void main(String args[]){
if(args.length > 0 && Integer.parseInt(args[0]) > 0 && Integer.parseInt(args[0]) < 100){
Races races = new Races(Integer.parseInt(args[0])); // From command line number of racers
System.out.println("Number of racers: " + args[0]);
}else{
Races races = new Races(5); // Default number of racers
System.out.println("Number of racers: 5");
}
}
public class innerRacer extends JPanel implements Runnable{
JPanel panel;
Icon icon;
public innerRacer(){
panel = new JPanel();
panel.setBackground(Color.WHITE);
icon = new ImageIcon("races.jpg");
} //end of innerRacer constructor
@Override
public void run(){
repaint();
System.out.println("TEST");
}
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g.drawLine(10, 20, 30, 40);
System.out.println("Why is this one not called?");
icon.paintIcon(panel, g, 0, 0);
}
} // end of innerRacer class
} //end of Races class
提前致谢。
您添加了 innerRacer
包含的 JPanel
而不是 innerRacer
包含的 JPanel
。
变化:
frame.add(racer.panel);
至:
frame.add(racer);
我还看到您在将框架设置为可见后向框架添加组件。当您在 AWT/Swing 中执行此操作时,它们不会自动布局或绘制。您需要遵循以下行:
frame.revalidate();
或者,setVisible
行可以下移。
一般说明:
- 坚持 Java 命名约定是个好主意 - 类型的首字母始终大写。
JPanel panel;
可以删除- 应始终从 AWT 事件调度线程 (EDT) 访问 Swing 组件。使用
java.awt.EventQueue.invokeLater
. - 很多教程建议在不添加任何组件的情况下覆盖
JPanel
如果您想绘制任何东西。这似乎是因为默认情况下它是不透明的。JPanel
的 API 文档甚至 OpenJDK 源代码都没有提到不透明性。事实上,这并不能保证。这只是一个黑客。首选setOpaque(true)
使组件不透明。 - 让一个 class 扩展另一个并实现一个接口(或实现多个接口(不是标记、
Comparable
等))并不是很好。根据需要使用 lambda 方法、方法引用、内部 class 或另一个外部 class。
innerRacer
中的