Skip to content

Commit 91072ee

Browse files
committed
5074006: Swing JOptionPane shows </html> tag as a string after newline
8042134: JOptionPane bungles HTML messages Reviewed-by: jdv, tr
1 parent 274ea1d commit 91072ee

File tree

2 files changed

+132
-40
lines changed

2 files changed

+132
-40
lines changed

src/java.desktop/share/classes/javax/swing/plaf/basic/BasicOptionPaneUI.java

+64-40
Original file line numberDiff line numberDiff line change
@@ -456,51 +456,75 @@ protected void addMessageComponents(Container container,
456456
} else if ((nl = s.indexOf('\n')) >= 0) {
457457
nll = 1;
458458
}
459-
if (nl >= 0) {
460-
// break up newlines
461-
if (nl == 0) {
462-
@SuppressWarnings("serial") // anonymous class
463-
JPanel breakPanel = new JPanel() {
464-
public Dimension getPreferredSize() {
465-
Font f = getFont();
466-
467-
if (f != null) {
468-
return new Dimension(1, f.getSize() + 2);
469-
}
470-
return new Dimension(0, 0);
471-
}
472-
};
473-
breakPanel.setName("OptionPane.break");
474-
addMessageComponents(container, cons, breakPanel, maxll,
475-
true);
476-
} else {
477-
addMessageComponents(container, cons, s.substring(0, nl),
478-
maxll, false);
479-
}
480-
// Prevent recursion of more than
481-
// 200 successive newlines in a message
482-
// and indicate message is truncated via ellipsis
483-
if (recursionCount++ > 200) {
484-
recursionCount = 0;
485-
addMessageComponents(container, cons, new String("..."),
486-
maxll,false);
487-
return;
459+
if (s.contains("<html>")) {
460+
/* line break in html text is done by <br> tag
461+
* and not by /n so it's incorrect to address newline
462+
* same as non-html text.
463+
* Text between <html> </html> tags are extracted
464+
* and rendered as JLabel text
465+
*/
466+
int index1 = s.indexOf("<html>");
467+
int index2 = s.indexOf("</html>");
468+
String str = "";
469+
if (index2 >= 0) {
470+
str = s.substring(index2 + "</html>".length());
471+
s = s.substring(index1, index2 + + "</html>".length());
488472
}
489-
addMessageComponents(container, cons, s.substring(nl + nll), maxll,
490-
false);
491-
492-
} else if (len > maxll) {
493-
Container c = Box.createVerticalBox();
494-
c.setName("OptionPane.verticalBox");
495-
burstStringInto(c, s, maxll);
496-
addMessageComponents(container, cons, c, maxll, true );
497-
498-
} else {
499473
JLabel label;
500-
label = new JLabel( s, JLabel.LEADING );
474+
label = new JLabel(s, JLabel.LEADING);
501475
label.setName("OptionPane.label");
502476
configureMessageLabel(label);
503477
addMessageComponents(container, cons, label, maxll, true);
478+
if (!str.isEmpty()) {
479+
addMessageComponents(container, cons, str, maxll, false);
480+
}
481+
} else {
482+
if (nl >= 0) {
483+
// break up newlines
484+
if (nl == 0) {
485+
@SuppressWarnings("serial") // anonymous class
486+
JPanel breakPanel = new JPanel() {
487+
public Dimension getPreferredSize() {
488+
Font f = getFont();
489+
490+
if (f != null) {
491+
return new Dimension(1, f.getSize() + 2);
492+
}
493+
return new Dimension(0, 0);
494+
}
495+
};
496+
breakPanel.setName("OptionPane.break");
497+
addMessageComponents(container, cons, breakPanel, maxll,
498+
true);
499+
} else {
500+
addMessageComponents(container, cons, s.substring(0, nl),
501+
maxll, false);
502+
}
503+
// Prevent recursion of more than
504+
// 200 successive newlines in a message
505+
// and indicate message is truncated via ellipsis
506+
if (recursionCount++ > 200) {
507+
recursionCount = 0;
508+
addMessageComponents(container, cons, new String("..."),
509+
maxll, false);
510+
return;
511+
}
512+
addMessageComponents(container, cons, s.substring(nl + nll), maxll,
513+
false);
514+
515+
} else if (len > maxll) {
516+
Container c = Box.createVerticalBox();
517+
c.setName("OptionPane.verticalBox");
518+
burstStringInto(c, s, maxll);
519+
addMessageComponents(container, cons, c, maxll, true);
520+
521+
} else {
522+
JLabel label;
523+
label = new JLabel(s, JLabel.LEADING);
524+
label.setName("OptionPane.label");
525+
configureMessageLabel(label);
526+
addMessageComponents(container, cons, label, maxll, true);
527+
}
504528
}
505529
}
506530
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
/* @test
24+
* @bug 5074006
25+
* @key headful
26+
* @library /java/awt/regtesthelpers
27+
* @build PassFailJFrame
28+
* @summary Swing JOptionPane shows <html> tag as a string after newline
29+
* @run main/manual TestJOptionHTMLTag
30+
*/
31+
32+
import javax.swing.JDialog;
33+
import javax.swing.JOptionPane;
34+
import javax.swing.SwingUtilities;
35+
36+
public class TestJOptionHTMLTag {
37+
static String instructions
38+
= """
39+
INSTRUCTIONS:
40+
A dialog will be shown.
41+
If it does not contain </html> string, press Pass else press Fail.
42+
""";
43+
static PassFailJFrame passFailJFrame;
44+
45+
public static void main(String[] args) throws Exception {
46+
47+
SwingUtilities.invokeAndWait(() -> {
48+
try {
49+
String message = "<html>" + "This is a test\n" + "</html>";
50+
JOptionPane optionPane = new JOptionPane();
51+
optionPane.setMessage(message);
52+
optionPane.setMessageType(JOptionPane.INFORMATION_MESSAGE);
53+
JDialog dialog = new JDialog();
54+
dialog.setContentPane(optionPane);
55+
dialog.pack();
56+
dialog.setVisible(true);
57+
58+
passFailJFrame = new PassFailJFrame(instructions);
59+
PassFailJFrame.addTestWindow(dialog);
60+
PassFailJFrame.positionTestWindow(dialog, PassFailJFrame.Position.HORIZONTAL);
61+
} catch (Exception e) {
62+
e.printStackTrace();
63+
}
64+
});
65+
passFailJFrame.awaitAndCheck();
66+
}
67+
}
68+

0 commit comments

Comments
 (0)