【发布时间】:2021-05-14 20:23:59
【问题描述】:
我想知道为什么 JTextArea 会两次打印同一行。我使用多线程,我对这个概念很陌生。我想知道这是否是问题所在。在查看它时,我尝试查看是否有任何运行方法被调用两次来导致这样的事情。代码中也没有任何循环。显示“打印两次?”的行在 GameThread 类中是问题开始的地方。感谢您的帮助。
主菜单类
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JButton;
import java.awt.Font;
import java.awt.Color;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.awt.event.ActionEvent;
public class MainMenu {
private JFrame menu;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
MainMenu window = new MainMenu();
window.menu.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
* @throws IOException
*/
public MainMenu() throws IOException {
initialize();
}
/**
* Initialize the contents of the frame.
* @throws IOException
*/
private void initialize() throws IOException {
menu = new JFrame();
menu.getContentPane().setBackground(Color.BLACK);
menu.setTitle("Zombie Game");
menu.setBounds(100, 100, 574, 374);
menu.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
menu.getContentPane().setLayout(null);
JButton btnPlay = new JButton("Play");
// button action on click
btnPlay.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
GameScreen enterGame = new GameScreen();
menu.setVisible(false);
enterGame.run();
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
JLabel lblNewLabel = new JLabel("Zombie Survival");
lblNewLabel.setFont(new Font("Tahoma", Font.BOLD, 40));
lblNewLabel.setForeground(Color.WHITE);
lblNewLabel.setBounds(118, 34, 381, 73);
menu.getContentPane().add(lblNewLabel);
btnPlay.setBackground(Color.WHITE);
btnPlay.setForeground(Color.RED);
btnPlay.setFont(new Font("Tahoma", Font.BOLD, 17));
btnPlay.setToolTipText("Click to begin.");
btnPlay.setBounds(225, 190, 118, 54);
menu.getContentPane().add(btnPlay);
}
}
游戏板
import java.awt.EventQueue;
import java.io.PrintStream;
import javax.swing.JFrame;
import java.awt.Color;
import javax.swing.JLabel;
import javax.swing.ImageIcon;
import javax.swing.JTextArea;
import java.awt.Font;
import javax.swing.JScrollPane;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
public class GameScreen {
private JFrame gameFrm;
/**
* Launch the application.
*/
public void run() {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
GameScreen window = new GameScreen();
window.gameFrm.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
* @throws InterruptedException
*/
public GameScreen() throws InterruptedException {
initialize();
}
/**
* Initialize the contents of the frame.
* @throws InterruptedException
*/
private void initialize() throws InterruptedException {
gameFrm = new JFrame();
gameFrm.getContentPane().setBackground(Color.BLACK);
gameFrm.getContentPane().setLayout(null);
JScrollPane scrollPane = new JScrollPane();
scrollPane.setBounds(10, 478, 718, 134);
gameFrm.getContentPane().add(scrollPane);
JTextArea displayTextArea = new JTextArea();
displayTextArea.setLineWrap(true);
displayTextArea.setWrapStyleWord(true);
displayTextArea.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
}
}
});
scrollPane.setViewportView(displayTextArea);
displayTextArea.setFont(new Font("Monospaced", Font.PLAIN, 18));
displayTextArea.setForeground(Color.WHITE);
displayTextArea.setBackground(Color.BLACK);
PrintStream printStream = new PrintStream(new CustomOutputStream(displayTextArea));
System.setOut(printStream);
JLabel forestPicture = new JLabel("New label");
forestPicture.setIcon(new ImageIcon("C:\\Users\\fstal\\Documents\\Java Programs\\UpdatedZombieGame\\src\\gameForest.jpg"));
forestPicture.setBounds(0, 0, 738, 622);
gameFrm.getContentPane().add(forestPicture);
gameFrm.setBackground(Color.WHITE);
gameFrm.setTitle("Zombie Game");
gameFrm.setBounds(100, 100, 752, 659);
gameFrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Game work
GameThread gThread = new GameThread();
gThread.start();
}
}
线程类
public class GameThread extends Thread {
static String [] zombies = {"Zombie", "Fast Zombie", "Big Zombie", "Crawler"};
static String [] bag = {"Assault Rifle", "SMG", "Shotgun", "Sniper"};
static int [] zHealth = {100, 90, 200, 50};
static int [] damage = {90, 80, 100, 200};
static int playerHealth = 50;
public void run() {
try {
System.out.println("Zombies are coming!");
//Thread.sleep(2000);
System.out.println("Prints twice?");
}
catch (Exception e) {
e.printStackTrace();
}
}
}
TextArea 的 CustomOutputStream 类
import java.io.IOException;
import java.io.OutputStream;
import javax.swing.JTextArea;
public class CustomOutputStream extends OutputStream {
private JTextArea displayTextArea;
CustomOutputStream(JTextArea textArea) {
this.displayTextArea = textArea;
}
@Override
public void write(int b) throws IOException {
// redirects data to the text area
displayTextArea.append(String.valueOf((char)b));
// scrolls the text area to the end of data
displayTextArea.setCaretPosition(displayTextArea.getDocument().getLength());
}
}
【问题讨论】:
-
我的直接问题是您正在从事件调度线程的上下文之外修改 UI
标签: java multithreading swing output