Java - JTextArea 拒绝打印只有空格的字符串

Java - JTextArea refuses to print strings that are just whitespace

我用Swing组件写了一个命令终端。下面的代码片段包含我认为可能是问题的一部分的所有内容。片段 #1 中发生的事情,当我调用 printBoard() 时,它忽略了 values[][] 数组中的空格。我尝试切换到 String[][] 而不是 char[][] 但它没有用。

如果您需要更多信息,请询问。感谢您的帮助!

编辑:https://github.com/GlitchGamer1459/Windows-Command-Prompt-Clone

片段#1:

package Application.play;

import Application.control.Controller;
import Application.control.IOEngine;
import Application.control.Terminal;

public class TicTacToe {

    private static final IOEngine stringMethods = new IOEngine();

    private static char charToPrint = 'X';

    @SuppressWarnings("FieldMayBeFinal")
    private static char[][] values = {
            { ' ', ' ', ' ' },
            { ' ', ' ', ' ' },
            { ' ', ' ', ' ' }
    };

    private static void printBoard() {
        Terminal.out.println(" " + values[0][0] + " | " + values[0][1] + " | " + values[0][2] + " ");
        Terminal.out.println("---+---+---");
        Terminal.out.println(" " + values[1][0] + " | " + values[1][1] + " | " + values[1][2] + " ");
        Terminal.out.println("---+---+---");
        Terminal.out.println(" " + values[2][0] + " | " + values[2][1] + " | " + values[2][2] + " ");
    }

    private static void parseChain(String chain) { // a chain looks like this: '1.1' or this: '0.2'
        try {
            int vertical = Integer.parseInt(stringMethods.getUntilFirst('.', chain));
            int horizontal = Integer.parseInt(stringMethods.getUntilSecond('.', chain));

            if (charToPrint == 'X') {
                charToPrint = 'O';
            } else {
                charToPrint = 'X';
            }

            values[vertical][horizontal] = charToPrint;
        } catch (NumberFormatException nfe) {
            Terminal.out.println("Not A Valid Input, try again");
        } catch (ArrayIndexOutOfBoundsException e) {
            Terminal.out.println("Not A Valid Input, must be within range of 0-2");
        }
    }

    public static void runGame(String string) {
        Controller.ioEngine.clearTerminalScreen();
        parseChain(string);
        printBoard();
    }

    public static void start() {
        Terminal.setActiveCycle(2);
    }
}

片段#2:

package Application.control;

import javax.swing.*;

@SuppressWarnings("unused")
public class Out {
    JTextArea outputScreen;

    public Out(JTextArea outputArea) {
        outputScreen = outputArea;
    }

    public void println() {
        outputScreen.append("\n");
    }

    public void println(String output) {
        outputScreen.append(output + "\n");
    }

    public void println(double output) {
        outputScreen.append(output + "\n");
    }

    public void println(int output) {
        outputScreen.append(output + "\n");
    }

    public void println(char output) {
        outputScreen.append(output + "\n");
    }

    public void println(float output) {
        outputScreen.append(output + "\n");
    }
}

代码段 #3:

package Application.terminal;

import Application.control.Controller;
import Application.control.Terminal;
import Application.play.GuessGame;
import Application.play.TicTacToe;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class EventHandler implements KeyListener, ActionListener {

    @SuppressWarnings("all")
    public boolean gameAlreadyInit = false;

    //KeyListener methods
    @Override
    public void keyTyped(KeyEvent e) {

    }

    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == 10) {
            String input = Controller.terminal.inputField.getText();
            Controller.terminal.inputField.setText("");
            switch (Terminal.getActiveCycle()) {
                case 0 -> // runs the base Terminal cycle
                    Controller.ioEngine.parseInput(input);
                case 1 -> { // runs the guessing game
                    if (!gameAlreadyInit) {
                        GuessGame.start();
                        gameAlreadyInit = true;
                    }

                    GuessGame.runGame(input);
                }
                case 2 -> {
                    if (!gameAlreadyInit) {
                        TicTacToe.start();
                        gameAlreadyInit = true;
                    }

                    TicTacToe.runGame(input);
                }
            }
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {

    }

    //ActionListener methods
    @Override
    public void actionPerformed(ActionEvent e) {

    }
}

所以,我提取了你的代码,忽略了 staticnull 布局和 KeyListener 的过度使用,我更改了:

outputScreen.setFont(new Font("SansSerif", Font.PLAIN, 15));

outputScreen.setFont(new Font("Courier", Font.PLAIN, 15));

现在打印

您需要使用 monospaced font 以确保所有字符具有相同的宽度

此外,您应该听从安德鲁的建议...

outputScreen.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 15));

现在您获得了平台独立性。

what's wrong with the null layout?

没有布局管理器...

使用布局管理器...

可靠性免费。您也不必担心 DPI 或可访问性之类的功能。

null 或“像素完美”布局是一种错觉。决定组件大小以及组件之间的布局方式的因素有很多。

解决这些问题已经做了很多工作,Swing 使用布局管理器,其他框架也做类​​似的事情。

与其花很多时间纠结为什么布局在其他计算机上会中断,不如利用您已经可用的布局管理器 - 例如,BorderLayout 将是非常适合您当前的布局

what's wrong with KeyListener?

KeyListener 级别太低 API 无法满足您的需要。由于您所做的只是监控 Enter 键,您不妨利用 ActionListener 支持。您还假设密钥代码是不变的。

如果你想过滤输入,那么你应该使用DocumentFilter