Перенос слов в JButtons
можно ли добиться автоматической обертки текстов в JButtons? У меня есть несколько динамических кнопок, которые я создаю во время выполнения. Я хочу поместить функцию переноса слов на кнопки, чтобы я мог видеть лучший тест на кнопках. Возможно ли это сделать?
4 ответов
в этом примере используются встроенные возможности CSS-рендеринга Java, чтобы сделать "тяжелый подъем" определения, когда делать разрыв строки. Он использует JLabel
, но те же принципы применимы к любому компоненту, который будет отображать 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 = new Runnable() {
public void run() {
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, "%");
}
}
скриншоты
160px
на 200px
50%
используйте HTML...
button.setText("<html><center>"+"This is a"+"<br>"+"swing button"+"</center></html>");
проще всего изменить другой компонент, который поддерживает перенос слов, чтобы он действовал как кнопка. Я сделал простой класс, который манипулирует JTextArea, чтобы действовать как кнопка.
public class MultiLineButton extends JTextArea implements MouseListener {
/**
*
*/
private static final long serialVersionUID = 1L;
private Color defaultColor;
private Color highlight, lightHighlight;
private BtnState state;
private List<ActionListener> actionListeners;
public MultiLineButton(String text, Color defaultColor) {
this.setEditable(false);
this.setText(text);
this.setLineWrap(true);
this.setWrapStyleWord(true);
this.addMouseListener(this);
this.setBorder(new EmptyBorder(5, 10, 5, 10));
state = BtnState.NORMAL;
this.defaultColor = defaultColor;
this.setBackground(defaultColor);
highlight = new Color(122, 138, 153);
lightHighlight = new Color(184, 207, 229);
// clickedColor = new Color(r, g, b);/
actionListeners = new ArrayList<>();
}
@Override
public Color getSelectionColor() {
return getBackground();
}
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
setBackground(lightHighlight);
state = BtnState.CLICKED;
repaint();
}
@Override
public void mouseReleased(MouseEvent e) {
for (ActionListener l : actionListeners) {
l.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, this.getText()));
}
setBackground(defaultColor);
state = BtnState.NORMAL;
repaint();
}
@Override
public void mouseEntered(MouseEvent e) {
state = BtnState.HOVERED;
repaint();
}
@Override
public void mouseExited(MouseEvent e) {
setBackground(defaultColor);
state = BtnState.NORMAL;
repaint();
}
@Override
public void paintBorder(Graphics g) {
super.paintBorder(g);
Graphics g2 = g.create();
g2.setColor(highlight);
switch (state) {
case NORMAL:
g2.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
break;
case HOVERED:
g2.drawRect(1, 1, getWidth() - 3, getHeight() - 3);
g2.setColor(lightHighlight);
g2.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
g2.drawRect(2, 2, getWidth() - 5, getHeight() - 5);
break;
case CLICKED:
Border b = new BevelBorder(BevelBorder.LOWERED);
b.paintBorder(this, g2, 0, 0, getWidth(), getHeight());
break;
}
g2.dispose();
}
public void addActionListener(ActionListener l) {
actionListeners.add(l);
}
public List<ActionListener> getActionListeners() {
return actionListeners;
}
}
BtnState - это просто перечисление с константами NORMAL, HOVERED, CLICKED
большая часть кода используется только для того, чтобы JTextArea выглядела как JButton, и она отлично работает. Одним из недостатков является то, что вы теряете возможность изменять его с помощью ButtonModels, но для большинства приложений этого будет достаточно.
@Override
public void paint(Graphics pGraphics)
{
super.paint(pGraphics);
Graphics2D g2d = (Graphics2D) pGraphics;
FontRenderContext frc = g2d.getFontRenderContext();
String itemName = item.getName();
AttributedString attributedString = new AttributedString(itemName);
attributedString.addAttribute(TextAttribute.FONT, getFont());
AttributedCharacterIterator iterator = attributedString.getIterator();
LineBreakMeasurer measurer = new LineBreakMeasurer(iterator, frc);
float wrappingWidth = getSize().width - 15;
StringBuilder stringBuilder = new StringBuilder("<html><center>");
int previousIndex = 0;
while (measurer.getPosition() < itemName.length())
{
if (previousIndex != 0) stringBuilder.append("<br>");
stringBuilder.append(itemName.substring(previousIndex, measurer.getPosition()));
previousIndex = measurer.getPosition();
measurer.nextLayout(wrappingWidth);
}
if (previousIndex < itemName.length())
{
if (previousIndex != 0) stringBuilder.append("<br>");
stringBuilder.append(itemName.substring(previousIndex));
}
stringBuilder.append("</center></html>");
setText(stringBuilder.toString());
}