事件分配线程与逻辑线程分开,防止阻塞UI [英] Event Dispatch Thread divided from logic thread,prevent blocking UI

查看:104
本文介绍了事件分配线程与逻辑线程分开,防止阻塞UI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我如何将逻辑与EDT分开,因为您可以看到逻辑和渲染与循环相关 以及如何以一种漂亮的方式分离代码,这让我很麻烦,试图找出方法.

how i can separate the logic from the EDT,because as you can see logic and render are related into loop and how i can separate code in a pretty way, i' m getting in trouble with this,trying to find out how to do.

有什么建议/帮助/建议吗?

Any suggestion/helps/advices?

主班

public class MainFrame {

    private static MainFrame mainFrame = null;
    private final JFrame frame;

    private MainFrame() {
    frame = new JFrame();
    frame.setUndecorated(true);
    frame.add(new GamePanel());
    frame.pack();
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
    }

    public static final MainFrame getMainFrameInstance() {
    if (mainFrame == null) {
        mainFrame = new MainFrame();
    }
    return mainFrame;
    }

    public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
        try {// set look and feel to nimbus
            for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
            if ("Nimbus".equals(info.getName())) {
                UIManager.setLookAndFeel(info.getClassName());
                break;
            }
            }
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
        }
        MainFrame.getMainFrameInstance();
        }
    });
    }

}

我在其上开始游戏循环的

gamePanel类

gamePanel class on which i start the game loop

public class MyPanel extends JPanel implements Runnable {

    private static final long serialVersionUID = 1L;

    // thread and loop
    private Thread thread;
    private boolean running;
    private int FPS = 60;
    private long targetTime = 1000 / FPS;
    private long start;
    private long elapsed;
    private long wait;

    // image
    public BufferedImage image;
    // foo
    private Foo foo;

    private Render render = Render.getRenderManagerInstance();

    public MyPanel() {
    setPreferredSize(new Dimension(700, 700));
    setFocusable(true);
    requestFocus();
    }

    public void addNotify() {
    super.addNotify();
    if (thread == null) {
        thread = new Thread(this);
        thread.start();
    }
    }


    private  void initGraphic() {
    image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
    foo = new Foo();
    running = true;

    }

    public void run() {
    initGraphic();

    // loop
    while (running) {
        start = System.nanoTime();
        foo.update();
        repaint();
        elapsed = System.nanoTime() - start;
        wait = (targetTime - elapsed / 1000000) - 8;
        if (wait <= 0)
        wait = 6;

        try {
        Thread.sleep(wait);
        } catch (Exception e) {
        e.printStackTrace();
        }

    }
    }

    @Override
    public void paintComponent(Graphics graphics) {
    super.paintComponent(graphics);
    graphics = (Graphics2D) image.getGraphics();
    ((Graphics2D) graphics).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    ((Graphics2D) graphics).setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
    render.setRenderState((Graphics2D) graphics);
    }

推荐答案

您的gamePanel不应进入无限循环.它应该初始化自身并定义一个 Swing timer .更一般而言,每当您定期执行某项操作时,您都不应尝试跟踪时间,而应定义应该在单个步骤中执行的操作并让计时器呼叫您.这样可以更好地利用系统资源,并且是一种好的工程实践.

Your gamePanel should not enter an infinite loop. It should initialize itself and define a method to be called periodically by a Swing timer. More generally, whenever you do something periodically, you should not try to keep track of time, but instead define what should be done during a single step and let a timer call you. This makes a much better use of system resources and is a good engineering practice.

这篇关于事件分配线程与逻辑线程分开,防止阻塞UI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆