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...

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...

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...

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));