Utilize both the width and max-width properties to effectively wrap text within JOptionPane

I'm not well-versed in HTML/CSS, so please bear with my limited knowledge. I'm currently developing a GUI where I need to display a message dialog in case of an error. The error message could be either short or lengthy. I've implemented the following code, inspired by this solution.

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

public class TestOptionDialog {
public static void main(String[] args) {
    String msgLong = "This is a really long messageThis is a really long messageThis is a really long messageThis is a really long messageThis is a really long messageThis is a really long messageThis is a really long messag";
    String msgShort = "This is a 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);
    }
}

I'm facing an issue where setting the width variable to a specific pixel number only results in long messages being wrapped correctly, while short messages cause the dialog to be much larger than the text. On the other hand, setting the max-width argument only allows short messages to be displayed with the correct size, but long messages are not wrapped as desired. How can I achieve both?

UPDATE: I tried Marius' solution, which works quite well. However, I'm now encountering an issue where even though the calculated text width surpasses the threshold (e.g., 60% of screenWidth), the dialog doesn't break. Can anyone shed light on what might be causing this? See the code snippet and output below:

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: https://i.sstatic.net/JIFBQ.png 1232 px: https://i.sstatic.net/vjnzR.png 1512 px: https://i.sstatic.net/6wYZn.png

Answer №1

Figuring this out can be a bit challenging. A more practical approach would be to include the "width" css attribute only when necessary. See the code snippet below:

public class TestOptionDialog {

public static void main(String[] args) {
String msgLong = "This is a really long message that goes on and on and on...and on some more.";
String msgShort = "This is a 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;
}

}

https://i.sstatic.net/t1JOL.png https://i.sstatic.net/JB0Hu.png

NOTE Keep in mind that

java.awt.Toolkit.getDefaultToolkit().getScreenSize().width
retrieves the screen width of the "main" screen. If your application is running in full screen or on a secondary screen, this value may not be accurate. However, if you simply want a popup that is 60% the size of the main screen, this method is suitable.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Activate a Dropdown Menu by Clicking in a React Application

I have a collapsible feature where you can click to expand or collapse a dropdown. Currently, the dropdown can only be clicked on where the radio button is located. I want the entire area to be clickable so that users can choose the dropdown by clicking an ...

Styling with CSS in a React component

I am trying to display a row of buttons instead of columns on my webpage. I have used display:flex but it is still showing as a column. What I want is for each button to display the first character of its name underneath it, with all buttons lined up next ...

What is the reason behind the malfunction of the float?

Having an issue with the "1" form not extending to 100% width next to the "Tickets". Here is a visual representation of the problem: View how it currently looks here. html: <section id="main_content"> <div class="left inner"> ...

Creating a platform where your choices determine the results is my goal for a new website

My goal is to create a unique website that generates text based on responses to multiple choice questions. For instance, users can select symptoms from a list of options and receive recommended medicine at the end of the process. I'm wondering where ...

Display Text Only When Selected - Material-UI

Is there a way to display only the selected tab's text? I came across this code snippet in the MUI documentation that involves showing labels on selection. How can I achieve this effect, maybe by manipulating the state to change the color of the selec ...

Exploring Unicode Symbols for Icon Selection

I'm currently working on integrating an icon picker into my application that will enable the user to select a mathematical operator for data comparison. While I have successfully implemented the fontawesome-iconpicker on the page, I am encountering d ...

Utilize Selenium with Eclipse (Java) to validate the CSS table border style

I'm currently conducting a form test that involves leaving mandatory fields empty to verify if the field displays a red border indicating it needs to be filled before proceeding. Below is the code snippet I have implemented so far: driver=new Firefox ...

Obtain the href using a combination of xpath and id

I need to extract the href links for 9 search results from this specific website. The xpath and selectors for the first, second, and third items are as follows: '//*[@id="search-results"]/div[4]/div/ctl:cache/div[3]/div[1]/div/div[2]/div[2]/div[2]/p[ ...

error: local server did not return any data

I am currently using PHP on a Linux machine. In my HTML code, I have set up an AJAX request to the local Apache server (check http://localhost), with the intention of displaying the data from the server on the screen. However, for some reason, nothing is b ...

Is it possible to dynamically refresh a Void and PlaceHolder without requiring a full page reload?

Is there a way to automatically update a Void/PlaceHolder using SQL queries without refreshing the entire ASP page? I attempted to use an ASP timer without success. SOLUTION: After experimenting with asp:updatapanel, I discovered a solution that worked ...

Implementing append operations in JavaScript without relying on the id attribute

Is there a way to specify the second div without assigning it an ID or using any attributes, and then perform an append operation inside it? For instance, indicating that the p element should be appended within the second div without relying on an ID or ...

VueJS can manipulate an inline template by dynamically changing its content and reinitializing

this particular query shares similarities with the discussions on VueJS re-compiling HTML in an inline-template component as well as How to implement Vue js directive in an appended html element Regrettably, the approach suggested in those threads is no l ...

is it possible to adjust the height of a tableRow in mui?

I recently created a table component using Mui. I've been attempting to adjust the height of the tableRows, but so far I haven't had any success. Below is my code snippet: import React, { memo } from "react"; import { ActionItemType, ...

Getting JSON with duplicate keys in JavaScript can be achieved by parsing the data using a custom function

I am attempting to retrieve JSON from a URL, but I have encountered an issue where the response object is removing duplicate keys. Is there a way to fetch the JSON without eliminating these duplicates? Below is my JavaScript code: $('document'). ...

Calculating the sum of numbers within a PHP Foreach loop

I'm looking to calculate the total sum of individual records within a foreach loop. My table structure is as follows: <table> <tr> <th>Person Name</th> <th>Balances</th> <th>Total</th> & ...

By incorporating JavaScript, clicking on an image will trigger a shift in the position of a different element

Just starting out with JavaScript and experimenting with creating an event where clicking on an image triggers the movement of another hidden image. The hidden image is positioned off-screen to the left, while there is a table of images in the center of th ...

Is it possible for the `drop-shadow` shadow to be applied only to certain elements?

In the top image below, you can see how the drop-shadow effect would be drawn if applied to the top element. I am exploring the possibility of having the shadow cast only on specific objects, as shown in the bottom image. I am open to unconventional solut ...

Submit information from an HTML form to a PHP script and then send the response back to the client using AJAX,

Looking to run a PHP script using AJAX or JavaScript from an HTML form and then receive the results on the HTML page. This is what my changepsw.php file looks like: <?php // PHP script for changing a password via the API. $system = $_POST['syst ...

Tips for executing a jQuery nested template in a recursive manner

Imagine a world where JSON objects and jQuery templating collide in a thought-provoking inception-like scenario. How can we dive deeper into this rabbit hole? The catch is, I'm a bit lazy and hoping the code will do most of the heavy lifting... Q:& ...

The Angular Material date picker unpredictably updates when a date is manually changed and the tab key is pressed

My component involves the use of the Angular material date picker. However, I have encountered a strange issue with it. When I select a date using the calendar control, everything works fine. But if I manually change the date and then press the tab button, ...