多线程没有紧密耦合的对象

时间:2016-03-07 10:21:55

标签: java multithreading swing

我正在尝试用Java构建一个简单的游戏。在游戏循环终止之前,直到JTextPanel没有更新的问题,这当然对玩家来说不是一个好的体验。

我不熟悉多线程,但试图解决这个问题。我现在可以在多个线程中运行单独的代码,但是我无法理解如何让线程进行交互。很可能我错过了一些简单的东西,但是我找不到它,所以我把自己放在你的怜悯之中。我挂了一个帖子......

控制器类和主线程。我需要gamePanel和游戏分开运行。我试图在一个单独的线程中运行Game类,但游戏代码没有在gamePanel中运行。

控制器:

import javax.swing.JFrame;
import javax.swing.SwingUtilities;



public class Controller_LetterFall{
public static void main(String[] args){
    SwingUtilities.invokeLater(new Runnable(){
        public void run(){
            new MainFrame();
        }
    });

  }
}

和MainFrame类。我尝试在一个新线程中运行gameplay()。

package wordFall;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextArea;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class MainFrame extends JFrame implements Runnable {

private GamePlay game;
private TextPanel gamePanel;
private Header header;
private Player player;
private Dictionary dictionary;
private GamePlay game;

public MainFrame(){
super("Game");
    // Set the size of the frame.
setSize(400,600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);


// Establish default player. 
player = new Player();
dictionary = new Dictionary();
game = new GamePlay();
header = new Header();
gamePanel = new TextPanel();
add(header, BorderLayout.NORTH);
add(gamePanel, BorderLayout.CENTER);

this.game.setBoardInterface( 
        new BoardInterface(){
            @Override
            public void redraw(String text) {
                gamePanel.appendText(text);
            }
        });
    }
    @Override
    public void run() {
        game.play();
        System.out.println("The game is over.");
    }
}

任何帮助都将不胜感激。

2 个答案:

答案 0 :(得分:2)

您需要类似线程安全数据容器的东西。让我们称之为GameData。 您的GamePlay对象需要知道GameData对象,并且UI也需要知道这一点,因为用户所做的更改必须传播到GameData对象。

GamePlay对象中,您可以每隔一秒左右查找GameData对象的更改。如果有变化而不是你有什么事情要做..

但最好使用类似方法的事件,即Observer Pattern。如果UI进行了更改,则GamePlay对象将通知GameData。 此外,当数据发生变化时,也可以通知UI。

这非常清楚地分离了关注点并遵循模型视图控制器模式。

答案 1 :(得分:2)

嗯,在这种情况下,您的MainFrame对象是从swing调度程序线程构造的。正如你所说,你必须在某处开始一个新线程来处理游戏。假设您将在MainFrame对象的实例方法中使用此代码,那将是:

Thread thr = new Thread(this);
thr.start();

然后,每当您的单独游戏线程想要更​​新ui对象时,它不应该直接执行,而是使用SwingUtilities.invokeLater:

SwingUtilities.invokeLater(new Runnable() {
    @Override
    public void run() {
        /* Update the ui element... */
}});

当runnable有时间时,它将在swing调度程序线程中执行。