JOptionPange:即使使用等宽字体也无法打印 String.format table

JOptionPange: Can't print String.format table even with monospaced font

我正在尝试在 JOptionPane 中显示一个 table。但是,列缩进已关闭。我尝试将字体更改为等宽字体,但没有成功。

import javax.swing.*;
import java.awt.*;

public class Test {
    public static void main(String[] args) {
        String[] names = {"tom","john", "vincent", "dan"};
        String[] colors = {"red", "orange", "green", "blue"};
        String[] pets = {"dog", "crocodile", "monkey", "parrot"};
        int[] ages = {23, 5454, 1, 6565, 87};

        String s = "";
        for (int i = 0; i < 4; i++) {
            s += String.format("%-20s%-20s%-20s%-20d%n",
                names[i], colors[i], pets[i], ages[i]);
        }

        System.out.println(s);

        JOptionPane.showMessageDialog(null, s);

        JLabel label = new JLabel(s);
        label.setFont(new Font("Monospaced", Font.BOLD, 18));
        JOptionPane.showMessageDialog(null,label,"ERROR",JOptionPane.WARNING_MESSAGE);
   }
}

控制台输出如下所示:

第一个 window 看起来像这样(可以看出列已关闭):

第二个 window 看起来像这样:

如何让 table 以控制台中的打印方式打印?

您可以使用 JTextArea:

import javax.swing.*;
import java.awt.*;

public class Test5
{
    public static void main(String[] args)
    {
        String[] names = {"tom","john", "vincent", "dan"};
        String[] colors = {"red", "orange", "green", "blue"};
        String[] pets = {"dog", "crocodile", "monkey", "parrot"};
        int[] ages = {23, 5454, 1, 6565, 87};

        StringBuilder s = new StringBuilder();

        for (int i = 0; i < 4; i++)
        {
            if (i > 0)
                s.append("\n");

            s.append(String.format("%-20s%-20s%-20s%-20d", names[i], colors[i], pets[i], ages[i]));
        }

        JTextArea label = new JTextArea(s.toString());
        label.setOpaque( false );
        label.setEditable( false );
        label.setFont(new Font("Monospaced", Font.BOLD, 12));

       JOptionPane.showMessageDialog(null,label,"ERROR",JOptionPane.WARNING_MESSAGE);
   }
}

我提出两种可能性。

  1. class JOptionPane 的重载 showMessageDialog 方法中的 message 参数是一个 Object。因此它可以是您想要的任何。所以我用了javax.swing.JTable.
  2. 您尝试了 JLabel,但 JLabel 不支持其文本中的换行符,因此文本出现在一长行中。但是,JLabel 的文本可以包含 HTML 标记。所以我的第二个实现使用 JLabel 和 HTML table.

这是代码。 (后面有解释。)

import javax.swing.*;
import java.awt.*;

public class Test {
    public static void main(String[] args) {
        String[] names = {"tom", "john", "vincent", "dan"};
        String[] colors = {"red", "orange", "green", "blue"};
        String[] pets = {"dog", "crocodile", "monkey", "parrot"};
        int[] ages = {23, 5454, 1, 6565, 87};
        String s = "<html><table>";
        for (int i = 0; i < 4; i++) {
            s += String.format("<tr><td>%s</td><td>%s</td><td>%s</td><td>%d</td></tr>",
                               names[i],
                               colors[i],
                               pets[i],
                               ages[i]);
        }
        String[][] data = new String[][]{{"tom", "red", "dog", "23"},
                                         {"john", "orange", "crocodile", "5454"},
                                         {"vincent", "green", "monkey", "1"},
                                         {"dan", "blue", "parrot", "6565"}};
        JTable table = new JTable(data, new String[]{"", "", "", ""});
        table.setShowGrid(false);
        JOptionPane.showMessageDialog(null, table);
        JLabel label = new JLabel(s);
        label.setFont(new Font("Monospaced", Font.BOLD, 18));
        JOptionPane.showMessageDialog(null, label, "ERROR", JOptionPane.WARNING_MESSAGE);
    }
}
  • 我为 JTable 使用了虚拟列 headers,因为如果 JTable 未包含在 JScrollPane 中,则不会显示 headers。您不能使用 null 因为这会导致 NullPointerException.
  • 默认情况下,JTable 显示网格线,因此调用方法 setShowGrid(false) 因为我知道你不需要网格线。
  • JLabel 的文本是 HTML table。请注意,HTML 字符串不必有效。 (请注意,它不包含标签 <body><head>,甚至不包含结束符 </html>)。

这里是第一个JOptionPane,还有JTable

这是第二个 JOptionPane,带有 JLabel 和 HTML 文本。

此时我会将文本输出为 HTML。您只需在代码中添加一行即可获得您想要的结果。

import javax.swing.*;
import java.awt.*;

public class Test {
    public static void main(String[] args) {
        String[] names = {"tom","john", "vincent", "dan"};
        String[] colors = {"red", "orange", "green", "blue"};
        String[] pets = {"dog", "crocodile", "monkey", "parrot"};
        int[] ages = {23, 5454, 1, 6565, 87};

        String s = "";
        for (int i = 0; i < 4; i++) {
            s += String.format("%-20s%-20s%-20s%-20d%n",
                names[i], colors[i], pets[i], ages[i]);
        }

        System.out.println(s);

        s = "<html><pre>" + s.replace(System.lineSeparator(), "<br/>") + "</html>";
        JOptionPane.showMessageDialog(null, s);

        JLabel label = new JLabel(s);
        label.setFont(new Font("Monospaced", Font.PLAIN, 18));
        JOptionPane.showMessageDialog(null,label,"ERROR",JOptionPane.WARNING_MESSAGE);
   }
}

也许这是一个可行的解决方案。