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
200px
50%
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:
Simple wrapping text in a button but with minimized width without unnecessary white space
Ok, so two things to cover here:
- 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. 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
Comparing Float/Double Values Using == Operator
Can One Do a for Each Loop in Java in Reverse Order
Java Regex to Extract Text Between Tags
What Is @Joincolumn and How It Is Used in Hibernate
Creating Random Colour in Java
Java; String Replace (Using Regular Expressions)
Is Java 7 Using Tim Sort for the Method Arrays.Sort
How to Get Names of Classes Inside a Jar File
How to Create a Topic in Kafka from the Ide Using API
Multiple Java Versions Running Concurrently Under Windows
How to Create an Object of an Interface
Convert String to Calendar Object in Java
Access to Private Inherited Fields via Reflection in Java
Java Serialization with Non Serializable Parts
Hibernate Criteria: Joining Table Without a Mapped Association
Using Jaxb to Unmarshal/Marshal a List<String>
Error: Servlet Jar Not Loaded... Offending Class: Javax/Servlet/Servlet.Class