conipo
conipo

Reputation: 73

Use width and max-width to wrap text in JOptionPane

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

Upvotes: 1

Views: 2174

Answers (1)

Marius Manastireanu
Marius Manastireanu

Reputation: 2586

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.

Upvotes: 2

Related Questions