我有三个文件,这里是主要的一个,标题为 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); }现在我只希望 StartScreen.java 中的绘制函数显示在我的 JFrame 上。我希望你好在屏幕上移动。我做了线程 t 以便屏幕可以关闭。如果我摆脱了线程 t,或者在 Display.java 中创建它(在 if 语句中,在我设置默认关闭操作并将启动屏幕添加到容器 c 的位置)程序绘制我想要的东西,但 Jframe 赢了不关闭。我查看了很多其他网站和问题,但我无法弄清楚这一点。我是 Java 多线程和图形的新手,
2 回答
智慧大石
TA贡献1946条经验 获得超3个赞
很多问题:
不要扩展Applet。小程序死了。对于自定义绘画,您只需扩展
JPanel
面板并将其添加到框架中即可。您将
paintComponent()
在 JPanel 中覆盖,而不是在paint() 中进行覆盖。绘画方法仅用于绘画,您不应该:
读取方法中的图像。绘画方法被多次调用。您希望绘画速度快,不应该进行 I/O。读取类的构造函数中的图像
正在创建线程。同样,由于无法控制多次调用绘画方法,因此您不想继续创建线程。如果您想要某种动画,那么您应该使用 Swing Timer。
我建议您阅读有关自定义绘画的 Swing 教程中的部分。它包含的工作示例将向您展示如何更好地构建代码。
还有一个关于 的部分How to Use Swing Timers
。
慕运维8079593
TA贡献1876条经验 获得超5个赞
如果我们在 Java 中谈论图形,我们只有一个线程负责 EDT([1][事件调度线程])。换句话说,无论您想对视图做什么,都将由 EDT 处理并且必须由 EDT 处理,是的,您的视图也包含所有挫折、框架...
但请注意,它只是一个线程,当这个线程忙于做一些计算时,无法对用户事件做出反应,因此您的视图将冻结。您可以在另一个线程中做的是准备数据(在您的情况下读取文件图像)
要在 EDT 中工作,您可以使用 SwingInvoker.invokelater() 或使用 swingutilities.isEventDispatchThread() 检查您是否已经在 EDT
[1] https://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html
添加回答
举报
0/150
提交
取消