0

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 Answers2

1

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));
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • This is great info, i really appreciate the reply. Quick question though, just to clarify, if i do the html wrapped table, i Wont be able to change the values? – TheDrunkenHuntsman Feb 11 '15 at 01:34
  • In the `JEditorPane`, you "should" be able to, not going to say it would be easy though (adding rows would be a complete PITA). Personally, for my money, the `JTable` would represent less of an issue, but that's just me... – MadProgrammer Feb 11 '15 at 01:35
  • I'll take your word and give jTables a go. Thanks a bunch! – TheDrunkenHuntsman Feb 11 '15 at 01:50
0

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.

Adrian Leonhard
  • 7,040
  • 2
  • 24
  • 38
  • Thanks for your reply, but sadly, I attempted your recommendation but it worked the same way as if i had put spaces in place of the \t. – TheDrunkenHuntsman Feb 11 '15 at 00:26
  • @TheDrunkenHuntsman is using a monospace font an option? That would be an easy solution. – Adrian Leonhard Feb 11 '15 at 00:29
  • fantastic idea, i believe the only method i need is setFont()? Do you know if there are built in monospaced fonts, if not, where do i save a downloaded font in order to use it within the program? – TheDrunkenHuntsman Feb 11 '15 at 00:35
  • @TheDrunkenHuntsman Courier New is on all Windows PCs, http://support.microsoft.com/KB/90057 . See http://stackoverflow.com/questions/5652344/how-can-i-use-a-custom-font-in-java for using custom fonts. – Adrian Leonhard Feb 11 '15 at 00:38