【问题标题】:Paint function defined in separate thread not drawing (Java)在单独的线程中定义的绘制函数而不是绘图(Java)
【发布时间】:2018-10-06 17:15:58
【问题描述】:

我有三个文件,这里是主要的,标题为 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中的多线程和图形新手,

【问题讨论】:

  • 如果您希望 AWT 事件线程正常运行,所有与 GUI 组件的交互都需要发生。
  • 你确定图片正在加载,否则你的线程不会做任何事情。我会在你的调试器中单步调试代码。
  • 所有交互都需要在 EDT 上进行,这意味着:1)您的启动错误。这些 Swing 对象是在“主”线程上创建的,并且需要在 EDT 上。 2) 你在paint() 中生成的线程是错误的,它与之交互的那些 Swing 对象也需要在 EDT 上。这些可能不是问题的直接来源,但任何查看此问题的人都会标记这些错误并要求修复它们,因为它们可能会导致非常不可预测的交互。基本上,该程序几乎可以像现在这样以任何方式出错。

标签: java multithreading graphics jframe paint


【解决方案1】:

很多问题:

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

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

  3. 绘画方法仅供绘画,你不应该:

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

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

我建议您阅读 Custom Painting 上的 Swing 教程中的部分。它包含工作示例,将向您展示如何更好地构建代码。

How to Use Swing Timers上还有一个板块。

【讨论】:

    【解决方案2】:

    如果我们谈论 java 中的图形,我们只有一个负责 EDT 的线程([1][Event Dispatch Thread])。换句话说,无论您想对视图做什么,都将由 EDT 处理,并且必须由 EDT 处理,是的,您的视图也包含所有挫折、框架......

    但是请注意,它只是一个线程,当这个线程忙于进行一些计算时无法对用户事件做出反应,因此您的视图将冻结。您可以在另一个线程中做的是准备数据(在您的情况下读取文件图像)

    要在 EDT 中工作,请使用 SwingInvoker.invokelater() 或使用 swingutilities.isEventDispatchThread() 检查您是否已经在 EDT 中

    [1] https://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html
    

    【讨论】:

      猜你喜欢
      • 2022-01-05
      • 2012-06-27
      • 1970-01-01
      • 2020-01-02
      • 1970-01-01
      • 1970-01-01
      • 2012-05-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多