为了账号安全,请及时绑定邮箱和手机立即绑定

在不绘制的单独线程中定义的绘制函数(Java)

在不绘制的单独线程中定义的绘制函数(Java)

www说 2021-11-03 10:53:52
我有三个文件,这里是主要的一个,标题为 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个赞

很多问题:

  1. 不要扩展Applet。小程序死了。对于自定义绘画,您只需扩展JPanel面板并将其添加到框架中即可。

  2. 您将paintComponent()在 JPanel 中覆盖,而不是在paint() 中进行覆盖。

  3. 绘画方法仅用于绘画,您不应该:

    1. 读取方法中的图像。绘画方法被多次调用。您希望绘画速度快,不应该进行 I/O。读取类的构造函数中的图像

    2. 正在创建线程。同样,由于无法控制多次调用绘画方法,因此您不想继续创建线程。如果您想要某种动画,那么您应该使用 Swing Timer。

我建议您阅读有关自定义绘画的 Swing 教程中的部分。它包含的工作示例将向您展示如何更好地构建代码。

还有一个关于 的部分How to Use Swing Timers


查看完整回答
反对 回复 2021-11-03
?
慕运维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


查看完整回答
反对 回复 2021-11-03
  • 2 回答
  • 0 关注
  • 164 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信