在单独的线程中定义的绘画函数不绘制(Java)
Paint function defined in separate thread not drawing (Java)
我有三个文件,这里是主要的,标题为 Display.java:
import java.awt.*;
import javax.swing.*;
public class Display{
static JFrame main = new JFrame("hello");
static Container c = main.getContentPane();
static StartScreen start = new StartScreen();
static screenTracker track = new screenTracker();
public static void main(String[] args) {
main.setSize(new Dimension(1920,1080));
main.setVisible(true);
if(track.screen==1) {
main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
c.add(start, BorderLayout.CENTER);
}
}
}
我的第二个文件的标题是:StartScreen.java。它包含我的绘画功能:
import java.applet.Applet;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class StartScreen extends Applet{
private static final long serialVersionUID = 1L;
int x = 0;
static Container c = Display.c;
static Color gray = new Color(128,128,128);
public void paint(Graphics g) {
Thread t = new Thread() {
@Override
public void run() {
while(true) {
c.setBackground(gray);
g.clearRect( 0 , 0 , getWidth() , getHeight() );
BufferedImage img1 = null;
BufferedImage img2 = null;
BufferedImage img3 = null;
try {
img1 = ImageIO.read(new File("images/img1.png"));
img2 = ImageIO.read(new File("images/img2.png"));
img3 = ImageIO.read(new File("images/img3.png"));
}
catch(IOException e) {
g.drawString("bad", 200, 200);
}
String title1 = "hello: ";
String title2 = "Gamee ";
String title3 = "people";
Color pink = new Color(244,66,182);
Color black = new Color(0,0,0);
g.setColor(black);
g.setFont(new Font("TimesRoman", Font.PLAIN, 50));
g.drawString(title1, x+600, 200);
g.setColor(pink);
g.setFont(new Font("TimesRoman", Font.ITALIC, 50));
g.drawString(title2, 860, 200);
g.setFont(new Font("TimesRoman", Font.PLAIN, 50));
g.setColor(black);
g.drawString(title3, 960, 200);
g.drawImage(img1, 200, 250, null);
g.drawImage(img2, 700, 150, 1000, 750, null);
g.drawImage(img3, 500, 250, null);
x++;
try {
sleep(10); // milliseconds
} catch (InterruptedException ex) {}
}
}
};
t.start();
}
}
我的第三个文件很短:
public class screenTracker {
int screen = 1;
}
现在我只想 StartScreen.java 中的绘画功能显示在我的 JFrame 上。我想让你好在屏幕上移动。我制作了线程 t 以便屏幕可以关闭。如果我摆脱线程 t,或在 Display.java 中创建它(在 if 语句内,在我设置默认关闭操作并将启动屏幕添加到容器 c 的位置周围),程序会绘制我想要的内容,但是Jframe 不会关闭。我已经查看了很多其他网站和问题,但我一直无法弄清楚。我是 java、
中多线程和图形的新手
如果我们在 java 中谈论图形,我们只有一个线程负责 EDT([1][事件调度线程])。换句话说,无论您想对视图做什么,都将由 EDT 处理,并且必须由 EDT 处理,是的,您的视图还包含所有 setbackroungs、框架...
但要注意,它只是一个线程,当这个线程忙于做一些计算时无法对用户事件做出反应,所以你的视图会冻结。您可以在另一个线程中做的是准备数据(在您的情况下读取文件图像)
要在美国东部时间工作,您可以使用 SwingInvoker.invokelater() 或使用 swingutilities.isEventDispatchThread()
检查您是否已经在美国东部时间
[1] https://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html
很多问题:
不要扩展 Applet。小程序已经死了。对于自定义绘画,您只需扩展 JPanel
并将面板添加到框架。
您将在 JPanel 中覆盖 paintComponent()
,而不是 paint()。
一种绘画方法只是为了绘画你不应该:
读取方法中的图像。绘画方法被多次调用。你要画的快,不应该做I/O。阅读 class
的构造函数中的图像
正在创建线程。同样,由于绘制方法被多次调用,您无法控制您不想继续创建线程。如果你想要某种动画,那么你应该使用 Swing Timer。
我建议您阅读 Custom Painting 上的 Swing 教程部分。它包含工作示例,将向您展示如何更好地构建代码。
How to Use Swing Timers
上还有一节。
我有三个文件,这里是主要的,标题为 Display.java:
import java.awt.*;
import javax.swing.*;
public class Display{
static JFrame main = new JFrame("hello");
static Container c = main.getContentPane();
static StartScreen start = new StartScreen();
static screenTracker track = new screenTracker();
public static void main(String[] args) {
main.setSize(new Dimension(1920,1080));
main.setVisible(true);
if(track.screen==1) {
main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
c.add(start, BorderLayout.CENTER);
}
}
}
我的第二个文件的标题是:StartScreen.java。它包含我的绘画功能:
import java.applet.Applet;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class StartScreen extends Applet{
private static final long serialVersionUID = 1L;
int x = 0;
static Container c = Display.c;
static Color gray = new Color(128,128,128);
public void paint(Graphics g) {
Thread t = new Thread() {
@Override
public void run() {
while(true) {
c.setBackground(gray);
g.clearRect( 0 , 0 , getWidth() , getHeight() );
BufferedImage img1 = null;
BufferedImage img2 = null;
BufferedImage img3 = null;
try {
img1 = ImageIO.read(new File("images/img1.png"));
img2 = ImageIO.read(new File("images/img2.png"));
img3 = ImageIO.read(new File("images/img3.png"));
}
catch(IOException e) {
g.drawString("bad", 200, 200);
}
String title1 = "hello: ";
String title2 = "Gamee ";
String title3 = "people";
Color pink = new Color(244,66,182);
Color black = new Color(0,0,0);
g.setColor(black);
g.setFont(new Font("TimesRoman", Font.PLAIN, 50));
g.drawString(title1, x+600, 200);
g.setColor(pink);
g.setFont(new Font("TimesRoman", Font.ITALIC, 50));
g.drawString(title2, 860, 200);
g.setFont(new Font("TimesRoman", Font.PLAIN, 50));
g.setColor(black);
g.drawString(title3, 960, 200);
g.drawImage(img1, 200, 250, null);
g.drawImage(img2, 700, 150, 1000, 750, null);
g.drawImage(img3, 500, 250, null);
x++;
try {
sleep(10); // milliseconds
} catch (InterruptedException ex) {}
}
}
};
t.start();
}
}
我的第三个文件很短:
public class screenTracker {
int screen = 1;
}
现在我只想 StartScreen.java 中的绘画功能显示在我的 JFrame 上。我想让你好在屏幕上移动。我制作了线程 t 以便屏幕可以关闭。如果我摆脱线程 t,或在 Display.java 中创建它(在 if 语句内,在我设置默认关闭操作并将启动屏幕添加到容器 c 的位置周围),程序会绘制我想要的内容,但是Jframe 不会关闭。我已经查看了很多其他网站和问题,但我一直无法弄清楚。我是 java、
中多线程和图形的新手如果我们在 java 中谈论图形,我们只有一个线程负责 EDT([1][事件调度线程])。换句话说,无论您想对视图做什么,都将由 EDT 处理,并且必须由 EDT 处理,是的,您的视图还包含所有 setbackroungs、框架...
但要注意,它只是一个线程,当这个线程忙于做一些计算时无法对用户事件做出反应,所以你的视图会冻结。您可以在另一个线程中做的是准备数据(在您的情况下读取文件图像)
要在美国东部时间工作,您可以使用 SwingInvoker.invokelater() 或使用 swingutilities.isEventDispatchThread()
检查您是否已经在美国东部时间[1] https://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html
很多问题:
不要扩展 Applet。小程序已经死了。对于自定义绘画,您只需扩展
JPanel
并将面板添加到框架。您将在 JPanel 中覆盖
paintComponent()
,而不是 paint()。一种绘画方法只是为了绘画你不应该:
读取方法中的图像。绘画方法被多次调用。你要画的快,不应该做I/O。阅读 class
的构造函数中的图像
正在创建线程。同样,由于绘制方法被多次调用,您无法控制您不想继续创建线程。如果你想要某种动画,那么你应该使用 Swing Timer。
我建议您阅读 Custom Painting 上的 Swing 教程部分。它包含工作示例,将向您展示如何更好地构建代码。
How to Use Swing Timers
上还有一节。