【问题标题】:Use width and max-width to wrap text in JOptionPane使用 width 和 max-width 在 JOptionPane 中换行
【发布时间】:2016-05-26 03:28:55
【问题描述】:

我没有很好的 HTML/CSS 知识,所以请原谅我缺乏知识。我正在开发一个 GUI,当发生错误时,我会在其中生成一个消息对话框。此错误消息可能很短或很长。我正在使用以下代码改编自this solution

import javax.swing.JFrame;
import javax.swing.JOptionPane;

public class TestOptionDialog {
public static void main(String[] args) {
    String msgLong = "This is a freaking long messageThis is a freaking long messageThis is a freaking long messageThis is a freaking long messageThis is a freaking long messageThis is a freaking long messageThis is a freaking long messageThis is a freaking long messageThis is a freaking long messageThis is a freaking long messageThis is a freaking long messageThis is a freaking long messageThis is a freaking long messageThis is a freaking long message";
    String msgShort = "This is a freaking short message";

    int screenWidth = java.awt.Toolkit.getDefaultToolkit().getScreenSize().width;

    JOptionPane.showMessageDialog(new JFrame(),
            "<html><body><p style='width:100%;max-width:" + 0.6 * screenWidth + "px'>" + msgLong + "</p></body></html>",
            "Error", JOptionPane.ERROR_MESSAGE);

    JOptionPane.showMessageDialog(new JFrame(),
            "<html><body><p style='width:100%;max-width:" + 0.6 * screenWidth + "px'>" + msgShort + "</p></body></html>",
            "Error", JOptionPane.ERROR_MESSAGE);
    }
}

我的问题是,如果我只将宽度变量设置为某个像素数(例如 0.6*screenWidth),则会成功包装太长的消息,但是对于短消息,对话框比文本大得多。 相反,如果我只设置 max-width 参数,短消息会以完美的尺寸显示,但是太长的消息不会按照我的意愿包装到屏幕尺寸的 60%。

所以我想,我将只使用这两个参数并将宽度设置为 100%(正如我在某处读到的那样),但这仍然不会包含太长的消息。我怎样才能做到这两点?

编辑:在使用效果很好的 Marius 答案后,我遇到了以下问题:即使计算出的文本宽度高于阈值(例如,60% screenWidth),对话框不会中断。有人明白发生了什么还是我错过了什么?看下面的代码 sn-p 和输出:

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;

public class TestOptionDialog {
public static void main(String[] args) {
    // 1512 px
    String message = "message message message message message message message message message message message message message message message message message message message message message message message message message message message ";
    // 1232 px
    String message1 = "message message message message message message message message message message message message message message message message message message message message message message ";
    // 1064 px
    String message2 = "message message message message message message message message message message message message message message message message message message message ";

    // Break line at:
    int threshold = 1152;

    JOptionPane.showMessageDialog(new JFrame(),getFormattedErrorMessage(message, threshold),
            "Error", JOptionPane.ERROR_MESSAGE);

    JOptionPane.showMessageDialog(new JFrame(),getFormattedErrorMessage(message1, threshold),
            "Error", JOptionPane.ERROR_MESSAGE);

    JOptionPane.showMessageDialog(new JFrame(),getFormattedErrorMessage(message2, threshold),
            "Error", JOptionPane.ERROR_MESSAGE);

    System.exit(0);
}

private static String getFormattedErrorMessage(String message, int maxDialogWidth) {
    String string;

    JLabel label = new JLabel(message);
    if (label.getPreferredSize().width > maxDialogWidth) {
        string = "<html><body><p style='width:" + maxDialogWidth + "px;'>" + message + "</p></body></html>";
    } else {
        string = "<html><body><p>" + message + "</p></body></html>";
    }
    return string;
    }
}

1064 像素: 1232 像素: 1512 像素:

【问题讨论】:

  • Swing 对 HTML/CSS 的理解是原始的。它支持 HTML 3.2子集 和少量 CSS。我怀疑 max-width 是否曾经得到 Swing HTML 渲染引擎的支持。
  • 好的,很高兴了解 Swing 和 HTML/CSS 的关系。我在上面构建了我的示例,以使其尽可能小且独立。缺少什么?
  • “缺少什么?” 我对此不好。什么都没有,这是 MCVE 的一个很好的例子。在发表我的(愚蠢的)评论之前我只看了一眼(我很快删除了那部分 - 希望我在你看到它之前就这样做了 - 哎呀!)。

标签: java html css swing joptionpane


【解决方案1】:

这有点棘手。一个“肮脏”的解决方案是仅在需要时才添加“width” css 属性;见附件代码:

public class TestOptionDialog {

public static void main(String[] args) {
String msgLong = "This is a freaking long messageThis is a freaking long messags a freaking long messageThis is a freakis a freaking long messageThis is a freakieThis is a freaking ls a freaking long messageThis is a freakiong messageThis is a freaking long messageThis is a freaking long messageThis is a freaking long messageThis is a freaking long messageThis is a freaking long messageThis is a freaking long messageThis is a freaking long messageThis is a freaking long messageThis is a freaking long messageThis is a freaking long messageThis is a freaking long message";
String msgShort = "This is a freaking short message";

int screenWidth = java.awt.Toolkit.getDefaultToolkit().getScreenSize().width;
int maxDialogWidth = (int) (0.6 * screenWidth);

JOptionPane
    .showMessageDialog(new JFrame(),
        getMessage(msgLong, maxDialogWidth), "Error",
        JOptionPane.ERROR_MESSAGE);

JOptionPane.showMessageDialog(new JFrame(),
    getMessage(msgShort, maxDialogWidth), "Error",
    JOptionPane.ERROR_MESSAGE);
}

private static String getMessage(String message, int maxDialogWidth) {
   String string;
   JLabel label = new JLabel(message);
   if (label.getPreferredSize().width > maxDialogWidth) {
       string = "<html><body><p style='width:" + maxDialogWidth + "px;'>"+message+"</p></body></html>";
   } else {
       string = "<html><body><p>" + message+ "</p></body></html>";
   }
   return string;
}

}

编辑 请注意java.awt.Toolkit.getDefaultToolkit().getScreenSize().width将占用“主”屏幕的屏幕宽度;因此,如果您有一个全屏应用程序并且用户在“辅助”屏幕上运行该应用程序,那么该值可能不是您要查找的值;此外,如果用户没有在全屏模式下运行您的应用程序,则该值可能不是您要查找的值。

如果事实上,您只想提供一个大小为主屏幕 60% 的弹出窗口,是的,这种方法是正确的。

【讨论】:

  • 有趣的解决方案!关于你的编辑,你会怎么做?有没有办法获取应用程序正在运行的屏幕的屏幕尺寸?
  • 假设你有应用程序主框架的引用,你可以调用mainFrame.getBounds().getSize().width
  • 工作得很好,预计在某一点上,swing 的行为很奇怪。当超过方法中标签的首选大小时,字符串还没有中断。在我的示例中,60% 的屏幕宽度为 1152 像素,但它仅在 1500 像素处中断。不知道为什么...imgur.com/a/3xlT7
  • 好吧..实际上不是选项窗格是屏幕宽度的 60%,而只是标签。看图,也许更清楚:imgur.com/HH89HJR
  • 嗯,感谢您一直以来的帮助,但这不是我的意思。我不在乎总对话框最终是否大于屏幕宽度的 60%。我对方法中的JLabels 宽度超过阈值感到困惑,但是将带有阈值的宽度参数传递给JOptionPane 不会使文本中断。你明白我的意思吗?如果没有,请尝试使用不同消息长度的代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-02
  • 2013-09-19
  • 2018-04-18
  • 1970-01-01
  • 2016-09-23
  • 1970-01-01
  • 2018-06-16
相关资源
最近更新 更多