Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 无紧耦合对象的多线程_Java_Multithreading_Swing - Fatal编程技术网

Java 无紧耦合对象的多线程

Java 无紧耦合对象的多线程,java,multithreading,swing,Java,Multithreading,Swing,我正在尝试用Java构建一个简单的游戏。遇到了JTextPanel直到游戏循环终止后才更新的问题,当然,这对玩家来说不是一个好的体验 我不熟悉多线程,但正在尝试解决它。我现在可以在多个线程中运行单独的代码,但我无法理解如何让线程交互。我很可能错过了一些简单的东西,但我无法通过搜索找到它,所以我只能听天由命。我被绞死了 控制器类和主线程。我需要游戏面板和游戏分别运行。我尝试在单独的线程中运行Game类,但是gamePanel中没有运行游戏代码 控制器: import javax.swing.JFr

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

我不熟悉多线程,但正在尝试解决它。我现在可以在多个线程中运行单独的代码,但我无法理解如何让线程交互。我很可能错过了一些简单的东西,但我无法通过搜索找到它,所以我只能听天由命。我被绞死了

控制器类和主线程。我需要游戏面板和游戏分别运行。我尝试在单独的线程中运行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();
        }
    });

  }
}
还有大型机类。我尝试在新线程中运行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.");
    }
}

任何帮助都将不胜感激。

您需要线程安全数据容器之类的东西。我们把它叫做
GameData
。 您的
GamePlay
对象需要知道
GameData
对象,用户界面也需要知道,因为用户所做的更改必须传播到
GameData
对象

GamePlay
对象中,您可以每隔一秒钟左右查找
GameData
对象的更改。如果有变化,你就有事情要做

但最好使用类似事件的方法,即。如果UI进行了更改,
游戏性
将由可观察的
游戏数据
对象通知。 此外,当数据更改时,还可以通知UI


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

您需要线程安全数据容器之类的东西。我们把它叫做
GameData
。 您的
GamePlay
对象需要知道
GameData
对象,用户界面也需要知道,因为用户所做的更改必须传播到
GameData
对象

GamePlay
对象中,您可以每隔一秒钟左右查找
GameData
对象的更改。如果有变化,你就有事情要做

但最好使用类似事件的方法,即。如果UI进行了更改,
游戏性
将由可观察的
游戏数据
对象通知。 此外,当数据更改时,还可以通知UI


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

在本例中,您的大型机对象是从swing dispatcher线程构建的。正如你所说,你必须在某个地方开始一个新的线程来处理游戏。假设您将在大型机对象的实例方法中包含此代码,即:

Thread thr = new Thread(this);
thr.start();
然后,当您的独立游戏线程想要更新ui对象时,它不应该直接更新,而应该使用SwingUtilities.invokeLater:

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

当swing dispatcher线程有时间时,该runnable将在swing dispatcher线程中执行。

在这种情况下,您的大型机对象是从swing dispatcher线程构造的。正如你所说,你必须在某个地方开始一个新的线程来处理游戏。假设您将在大型机对象的实例方法中包含此代码,即:

Thread thr = new Thread(this);
thr.start();
然后,当您的独立游戏线程想要更新ui对象时,它不应该直接更新,而应该使用SwingUtilities.invokeLater:

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

当swing dispatcher线程有时间时,该runnable将在该线程中执行。

我在您的示例中没有看到任何线程。我在您的示例中没有看到任何线程。只要更新不太频繁,而且更重要的是,runnable没有任何数据争用或同步问题,这将很好地工作(如果它访问游戏线程中修改的一些字段,这将很快带来麻烦)。如果过于频繁的更改依赖于游戏线程的操作,会有什么问题?啊,意外按下了add。我还想说关于数据竞争的事情是正确的,如果访问共享数据,同步/并发收集/任何需要的东西也可以通过复制更新所需的数据来防止数据竞争进入可运行状态(通过创建字段或捕获最终变量)。至于过于频繁的更改,想象一下如果状态每秒更新1000次会发生什么情况。您将得到延迟和非常高的CPU负载。在这种情况下,最好以压缩包的形式发送更新,或者,或者,创建一个GUI计时器,以每秒轮询状态,例如25次。这取决于详细信息,哪种方法更好。这将起作用只要更新不太频繁,更重要的是,runnable没有任何数据竞争或同步问题(如果它访问游戏线程中修改的某些字段,这将很快带来麻烦),就可以了。如果过于频繁的更改依赖于游戏线程的操作,会有什么问题?啊,意外按下了add。我还想说关于数据竞争的事情是正确的,如果访问共享数据,同步/并发收集/任何需要的东西也可以通过复制更新所需的数据来防止数据竞争进入可运行状态(通过创建字段或捕获最终变量)。至于过于频繁的更改,请想象一下如果状态每秒更新1000次会发生什么。您将得到延迟和非常高的CPU负载。在这种情况下,最好使用压缩包发送更新,或者创建GUI计时器,以每秒轮询状态25次。这取决于详细信息,哪种方法更好。