1

I don't have good HTML/CSS knowledge, so excuse any dramatic lack of knowledge. I'm working on a GUI in which I am producing a message dialog when an error occurs. This error message may be short or very long. I'm using the following code adapted from 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);
    }
}

My problem is that if I only set the width variable to a certain pixel number (e.g. 0.6*screenWidth), too long messages are successfully wrapped, however for short messages the dialog is much larger than the text. On the contrary, if I only set the max-width argument, the short message is displayed with perfect size however too long messages are not wrapped to 60% of the screensize as I wanted to.

So I thought, I'll just use both arguments and set width to 100% (As I read somewhere), but that still doesn't wrap too long messages. How can I achieve both things?

EDIT: After using Marius answer, which works quite well, I'm running into the following problem: even though the calculated width of the text is higher than the threshold (say, 60% of screenWidth), the dialog does not break. Does anybody understand what's going on or am I missing something? See the following code snippet and the output:

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 px: 1064 px 1232 px: 1232 px 1512 px: 1512 px

Community
  • 1
  • 1
conipo
  • 73
  • 2
  • 8
  • 1
    Swing's understanding of HTML/CSS is primitive. It supports a **sub-set** of HTML **3.2** and a smattering of CSS. I doubt that `max-width` has ever been supported by the Swing HTML rendering engine. – Andrew Thompson Feb 15 '16 at 09:36
  • Ok, good to know about the relationship of Swing and HTML/CSS. I constructed my example above to be as minimal and self-contained as possible. What's missing? – conipo Feb 15 '16 at 09:40
  • *"What's missing?"* My bad on that. Nothing is missing and that is a good example of an MCVE. I only glanced at it briefly before making my (fool) comment (which I quickly deleted that part - hoping I did so before you saw it - Oops!). – Andrew Thompson Feb 15 '16 at 09:43
  • 2
    See also [*Text wrap in JOptionPane?*](http://stackoverflow.com/q/14011492/230513). – trashgod Feb 15 '16 at 12:32

1 Answers1

2

This is a bit tricky. A 'dirty' solution would be to only add "width" css attribute only if you need it; see code attached:

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

}

enter image description here enter image description here

EDIT Please take in mind that java.awt.Toolkit.getDefaultToolkit().getScreenSize().widthwill take the screen width of the "main" screen; therefore, if you have a full screen application and if the user is running the application on the "secondary" screen, this value is probably not the one that you are looking for; also, if the user is not running your application on full screen mode, the value is probably not the one that you are looking for.

If in fact, you want to just give a popup that is 60% the size of the main-screen, yes, this approach is correct.

Marius Manastireanu
  • 2,461
  • 5
  • 19
  • 29
  • Interesting solution! About your edit, how would you do it then? Is there a way to get the screen size of the screen that the application is running in? – conipo Feb 15 '16 at 12:22
  • Assuming you have a reference to the main frame of the application, you can call `mainFrame.getBounds().getSize().width` – Marius Manastireanu Feb 15 '16 at 12:27
  • works pretty well expect that at a certain point, swing behaves weirdly. When the preferred size of the label in the method is exceeded, the string doesn't break yet. In my example, 60% screen width is 1152px, but it only breaks at exactly 1500px. No idea why ... http://imgur.com/a/3xlT7 – conipo Feb 15 '16 at 14:01
  • well.. actually not the option pane is 60% of the screen's width, but only the label. take a look at the image, maybe it's more clear: http://imgur.com/HH89HJR – Marius Manastireanu Feb 15 '16 at 14:21
  • Mmh, thanks for the ongoing help, but that's not my point. I don't care if the total dialog box is in the end larger than 60% of screen width. I'm puzzled that the `JLabels` width in the method is over the threshold, but passing on the width parameter with the treshold to the `JOptionPane` doesn't make the text break. You get my point? If not, try out your code with varying message lengths. – conipo Feb 15 '16 at 14:44
  • I'm not sure I understand what your problem is. I've tried to reproduce your issue with different length strings; the string wraps each time exactly where it should; also I've posted an image in the original answer with the text that is wrapped... are you sure you've copied ok the code snippet? – Marius Manastireanu Feb 15 '16 at 14:53
  • see my edit in my original post. This is getting quite lengthy here, but I don't have enough rep to move it to chat, sorry ;) – conipo Feb 15 '16 at 15:22