Word Wrap in Jbuttons

Word Wrap in JButtons

This example uses Java's inbuilt CSS rendering abilities to to do the 'heavy lifting' of determining when to do a line break. It uses a JLabel, but the same principles apply to any component that will render HTML.

FixedWidthText.java

import javax.swing.*;

class FixedWidthText {

public static void showLabel(int width, String units) {
String content1 = "<html>"
+ "<body style='background-color: white; width: ";
String content2 = "'>"
+ "<h1>Fixed Width</h1>"
+ "<p>Body width fixed at ";
String content3
= " using CSS. "
+ "Java's HTML"
+ " support includes support"
+ " for basic CSS.</p>";
final String content = content1 + width + units
+ content2 + width + units + content3;
Runnable r = () -> {
JLabel label = new JLabel(content);
JOptionPane.showMessageDialog(null, label);
};
SwingUtilities.invokeLater(r);
}

public static void main(String[] args) {
showLabel(160, "px");
showLabel(200, "px");
showLabel(50, "%");
}
}

Screen shots

160px

Sample Image

200px

Sample Image

50%

Sample Image

Wrap dynamic text automatically in Jbutton

A very easy solution for this problem is a utility method, I wrote.

Just call it in your *ButtonUI #paint method before you call super.paint(c,g);

e.g.:

if (c instanceof AbstractButton) {
String txt = button.getText();
button.setText(getWrappedText(g, button, txt));
}

Here is my formatter for free use (and for optimization, too ;) )

private static final String STR_NEWLINE = "<br />";
private FontRenderContext fontRenderContext = new FontRenderContext(new AffineTransform(), true, true);

private String getWrappedText(Graphics graphics, AbstractButton button, String str) {
if( str != null ) {
String text = str.replaceAll("<html><center>", "").replaceAll("</center></html>", "");
int width = button.getWidth();
Rectangle2D stringBounds = button.getFont().getStringBounds(text, fontRenderContext);
if ( !str.contains(STR_NEWLINE) && (width-5) < ((Double)stringBounds.getWidth()).intValue()) {
String newStr;
if( str.contains(" ") ) {
int lastIndex = str.lastIndexOf(" ");
newStr = str.substring(0, lastIndex)+STR_NEWLINE+str.substring(lastIndex);
} else {
int strLength = ((str.length()/3)*2);
newStr = str.substring(0, strLength)+STR_NEWLINE+str.substring(strLength);
}
return newStr;
}
}
return str;
}

How to add a multi line text to a JButton with the line unknown? (dynamically)

You'll need to at least know how each line is delimited. For example if lines are delimited with newline characters, you could do:

String twoLines = "Two\nLines";
JButton b =
new JButton("<html>" + twoLines.replaceAll("\\n", "<br>") + "</html>");

Wrap the text inside a Button

Check out below code :

public class Sample {
public static void main(String[] args) {
Display display = new Display();
Shell shell = new Shell(display);
shell.setLayout(new GridLayout(1, false));

Composite comp = new Composite(shell, SWT.NONE);
comp.setLayout(new GridLayout(1, false));
comp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

Button testButton = new Button(comp, SWT.PUSH | SWT.WRAP);
testButton.setText("A long text, but not so long, just enough");
final GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true);
layoutData.widthHint = 100;
testButton.setLayoutData(layoutData);

shell.pack();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
}

Output on Windows 10:

Image 2

Image 1

Simple wrapping text in a button but with minimized width without unnecessary white space

Ok, so two things to cover here:

  1. To have the words break when they are super long, just add the property word-break: break-word;. This will break just long words that reached the boundary of the container.
  2. Your container will not reduce its size because when a text node goes under another one, the container is technically still the same size, just that one of its text nodes moved lower. To control how this affects your buttons, you have two options:

    a. Correct the max-width value to be way less than 120px, one that is good enough to hold most of the probable text you'll write for the buttons.

    b. Add some padding-left to the buttons to make up for its right size.

You can check the fiddle I created for this (using the padding solution) here: https://jsfiddle.net/Ahm7777/aL4L8m5q/5/.

Update

Well, I can't really think of any CSS solution for this, as it's kind of an expected behavior from the interaction of all properties defined, but the easier approach would just be to have a span wrapping the words on the button, retrieve its width and apply it to the button. Here is the fiddle with the sample of what I'm talking about. You'll just have to apply the code to get executed whenever the buttons end loading their text

How to wrap text inside bootstrap button without changing button size?

Here you go with a solution https://jsfiddle.net/3yv314dx/3/

$('[data-toggle="tooltip"]').tooltip(); 
.btn-outline {    background-color: transparent;    color: inherit;    transition: all .5s;}
.btn-wrap-text { overflow: hidden; white-space: nowrap; display: inline-block; text-overflow: ellipsis;}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/><script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script><div class="container">    <div class="row">    <div class="col-sm-6">             <div class="col-sm-4 col-md-4">                    <button class="btn btn-success btn-sm btn-block btn-outline">                        ARTICLE                                            </button>                </div>    <div class="col-sm-4 col-md-4">                    <button class="btn btn-success btn-sm btn-block btn-outline">                       ARTICLE                                      </button>                </div>    <div class="col-sm-4 col-md-4">                    <button class="btn btn-success btn-sm btn-block btn-outline">                         ARTICLE WITH LONGER NAME                    </button>                </div>    <div class="col-sm-4 col-md-4">                    <button class="btn btn-success btn-sm btn-block btn-outline">                         ARTICLE                           </button>                </div>    <div class="col-sm-4 col-md-4">                    <button class="btn btn-success btn-sm btn-block btn-outline">                        ARTICLE                                   </button>                </div>    <div class="col-sm-4 col-md-4">                    <button class="btn btn-success btn-sm btn-block btn-outline">                       ARTICLE                                 </button>                </div>    <div class="col-sm-4 col-md-4">                    <button class="btn btn-success btn-sm btn-block btn-outline">                        ARTICLE WITH LONGER NAME                    </button>                </div>    <div class="col-sm-4 col-md-4">                     <button class="btn btn-success btn-sm btn-block btn-outline btn-wrap-text" data-toggle="tooltip" title="ARTICLE WITH LONGER NAME">                       ARTICLE WITH LONGER NAME                    </button>                </div>    <div class="col-sm-4 col-md-4">                    <button class="btn btn-success btn-sm btn-block btn-outline">                        ARTICLE                                            </button>                </div>    <div class="col-sm-4 col-md-4">                    <button class="btn btn-success btn-sm btn-block btn-outline">                        ARTICLE                                             </button>                </div>    <div class="col-sm-4 col-md-4">                    <button class="btn btn-success btn-sm btn-block btn-outline">                        ARTICLE                                            </button>                </div>               <div class="col-sm-4 col-md-4">                    <button class="btn btn-success btn-sm btn-block btn-outline">                        ARTICLE                                            </button>                </div>    <div class="col-sm-4 col-md-4">                    <button class="btn btn-success btn-sm btn-block btn-outline">                        ARTICLE                                            </button>                </div>            </div>                 </div>    </div>

How to wrap text of HTML button with fixed width?

I found that you can make use of the white-space CSS property:

white-space: normal;

And it will break the words as normal text.

How to make an auto-sized Swing Popup with wrapped text?

See FixedWidthText which uses CSS to fix the width:



Related Topics



Leave a reply



Submit