Since multiline buttons can be created with html text, I tried html's line-height attribute with decimal, pixel and percentage values to change the vertical line spacing. But in vain.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class LineSpacing extends JFrame {
public static final long serialVersionUID = 100L;
public LineSpacing() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(480, 240);
setLayout(new FlowLayout());
setLocationRelativeTo(null);
add(createBox("Decimal", new String[]{"0.8", "0.9", "1.1"}));
add(createBox("px", new String[]{"10px", "12px", "15px"}));
add(createBox("%", new String[]{"85%", "95%", "110%"}));
setVisible(true);
}
static public void main(String args[]) {
EventQueue.invokeLater(LineSpacing::new);
}
private Box createBox(String header, String[] values) {
Box box= Box.createVerticalBox();
JPanel p= new JPanel();
p.add(new JLabel(header, SwingConstants.CENTER));
box.add(p);
for (int i=0; i<3; i++) {
JButton b= new JButton("<html><center><span style='line-height:"+
values[i]+"'>First line<br>and the second</span></html>");
b.setPreferredSize(new Dimension(130, 40));
b.setMargin(new Insets(0,0,0,0));
box.add(b);
}
return box;
}
}
EDIT
Thanks to Dewmith Mihisara for his code below.
I modified his LineHeightButton class to get the overprinting fixed.
add(createBox("Decimal", new Dimension(130, 40),
new int[]{-1, 0, 1, 2, 4, 6}));
.
.
private Box createBox(String header, Dimension dim, int[] spacings) {
.
.
JButton b = new LineHeightButton("First line\nand the second",
dim, spacing);
====================================================
class LineHeightButton extends JButton {
private final int lineSpacing;
String text;
public LineHeightButton(String text, Dimension dim, int lineSpacing) {
super();
this.lineSpacing = lineSpacing;
this.text= text;
setPreferredSize(dim);
setMinimumSize(dim);
setMaximumSize(dim);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setFont(getFont());
String[] lines = text.split("\n");
int i= 0, y = 15;
for (String line : lines) {
g2.drawString(line, getInsets().left,
y += i*(g2.getFontMetrics().getHeight()-5 + lineSpacing));
i++;
}
}
}
Remains the centering to be done, but that was not the problem.
Swing's HTML support is based on a subset of HTML 3.2, and it does not fully support CSS style, which includes the line-height property in all forms.
The line-height
property might work with relative or percentage values if the HTML rendering engine in Swing recognizes it. However, since it's not working as intended, consider these workarounds:
Replace the <span>
element with a <div>
and set the line-height
there. Sometimes, div
elements with line-height
are rendered better.
JButton b = new JButton("<html><center><div style='line-height:" + values[i] + "'>First line<br>and the second</div></html>");
If the line-height property still doesn't work, use explicit spacing methods, such as padding or adding <br>
tags with inline font-size.
Instead of relying on HTML styling, adjust the text rendering yourself using a custom JButton
or a JLabel
with multiline support.
Example :
import java.awt.*;
import javax.swing.*;
public class LineSpacingCustom extends JFrame {
public static final long serialVersionUID = 100L;
public LineSpacingCustom() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(480, 240);
setLayout(new FlowLayout());
setLocationRelativeTo(null);
add(createBox("Decimal", new float[]{0.8f, 0.9f, 1.1f}));
setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(LineSpacingCustom::new);
}
private Box createBox(String header, float[] spacings) {
Box box = Box.createVerticalBox();
JPanel p = new JPanel();
p.add(new JLabel(header, SwingConstants.CENTER));
box.add(p);
for (float spacing : spacings) {
JButton b = new LineHeightButton("First line\nand the second", spacing);
b.setPreferredSize(new Dimension(130, 60));
box.add(b);
}
return box;
}
}
class LineHeightButton extends JButton {
private final float lineSpacing;
public LineHeightButton(String text, float lineSpacing) {
super();
this.lineSpacing = lineSpacing;
setText(text);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setFont(getFont());
String[] lines = getText().split("\n");
int y = getInsets().top;
for (String line : lines) {
g2.drawString(line, getInsets().left, y += g2.getFontMetrics().getHeight() * lineSpacing);
}
}
}