How can I evenly space out 2d array in JTextArea w

2019-09-07 00:45发布

I ran into a little problem today while I was coding. I'm no expert in java, and I'm only just starting to learn GUI, so bear with me please.

I'm creating a game that involves a map that is composed of this 2D array, I've created a method to put that 2D array in a textArea.

public void viewMap(String[][] matrix)
{
    for (int r = 0; r < matrix.length; r++) {
        for (int c = 0; c < matrix[0].length; c++)
        {
            textArea.setText(textArea.getText() + "\t" + String.valueOf(matrix[r][c]));
        }
        textArea.setText(textArea.getText() + "\n" );
    }
}

If you notice the "\t" that i use to space each element. This works well for evenly spacing it, but the space is extremely large. My array turns out something like this:

x              H              f              f              x              x
x              f              x              f              D              x
x              x              x              x              x              x

This kind of spacing is great because the different letters not offset the position of the other letters, but it is way to large for my purposes, but if i simply put a few spaces in place of the "\t" i get something that doesn't line up like it does when i use /t, instead that different sizes of the letters throws off the rest of the row.

So i was wondering if anyone could help me come up with a solution in order to evenly space these letters when printing them out. I would really appreciate any feedback and help.

Thanks.

2条回答
狗以群分
2楼-- · 2019-09-07 01:08

If you want to use the JTextField, it has the method JTextArea#setTabSize(int), with which you can reduce the tabwidth.

EDIT: JTextArea doesn't seem to align tabs, so you will need to use a monospaced font.

查看更多
我想做一个坏孩纸
3楼-- · 2019-09-07 01:18

Text components aren't really well designed for formatting data in this way (at least not components that are designed to display plain text).

You could use a JTable instead, for example...

enter image description here

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.DefaultTableModel;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            setLayout(new BorderLayout());
            String[][] matrix = new String[][]{
                {"x", "H", "f", "f", "x", "x"},
                {"x", "f", "x", "f", "D", "x"},
                {"x", "H", "f", "f", "x", "x"},
            };

            DefaultTableModel model = new DefaultTableModel(0, 6);
            for (String[] row : matrix) {
                model.addRow(row);
            }

            JTable table = new JTable(model) {
                @Override
                protected void configureEnclosingScrollPane() {
                }
            };
            table.setShowGrid(false);
            table.setIntercellSpacing(new Dimension(0, 0));

            add(new JScrollPane(table));

        }

    }

}

If you don't need to edit the values or need anything really fancy (like selection), you could use a JLabel and wrap your text within a HTML TABLE...

enter image description here

setLayout(new GridBagLayout());
String[][] matrix = new String[][]{
    {"x", "H", "f", "f", "x", "x"},
    {"x", "f", "x", "f", "D", "x"},
    {"x", "H", "f", "f", "x", "x"},
};

JLabel label = new JLabel();
StringBuilder sb = new StringBuilder("<html>");
sb.append("<table boder=0>");
for (String[] row : matrix) {
    sb.append("<tr>");
    for (String col : row) {
        sb.append("<td align=center>").append(col).append("</td>");
    }
    sb.append("</tr>");
}
sb.append("</table>");
label.setText(sb.toString());
add(label);

And... If you "really" want to use a text component, then something like JEditorPane would probably be a better choice, as you don't need to worry about mono-spaced fonts...

enter image description here

setLayout(new BorderLayout());
String[][] matrix = new String[][]{
    {"x", "H", "f", "f", "x", "x"},
    {"x", "f", "x", "f", "D", "x"},
    {"x", "H", "f", "f", "x", "x"},};

JLabel label = new JLabel();
StringBuilder sb = new StringBuilder("<html><body>");
sb.append("<table boder=0>");
for (String[] row : matrix) {
    sb.append("<tr>");
    for (String col : row) {
        sb.append("<td align=center>").append(col).append("</td>");
    }
    sb.append("</tr>");
}
sb.append("</table></body></html>");
JEditorPane ep = new JEditorPane();
ep.setContentType("text/html");
ep.setText(sb.toString());
add(new JScrollPane(ep));
查看更多
登录 后发表回答