Перенос слов в 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

enter image description here

на 200px

enter image description here

50%

enter image description here


используйте 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());
}