15 Stimmen

Wortumbruch in JButtons

Ist es möglich, einen automatischen Zeilenumbruch von Texten in JButtons zu erreichen? Ich habe einige dynamische Schaltflächen, die ich zur Laufzeit erstelle. Ich möchte die Schaltflächen mit einem Wortumbruch versehen, damit ich bessere Tests auf den Schaltflächen sehen kann. Ist es möglich, dies zu tun?

25voto

Andrew Thompson Punkte 166383

In diesem Beispiel werden die in Java eingebauten CSS-Rendering-Fähigkeiten genutzt, um zu bestimmen, wann ein Zeilenumbruch erforderlich ist, und um die "schwere Arbeit" zu erledigen. Es verwendet eine JLabel aber die gleichen Grundsätze gelten für jede Komponente, die HTML wiedergibt.

FestgelegteBreiteText.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, "%");
    }
}

Bildschirmfotos

160px

enter image description here

200px

enter image description here

50%

enter image description here

16voto

Romain Hippeau Punkte 23654

HTML verwenden...

button.setText("<html><center>"+"This is a"+"<br>"+"swing button"+"</center></html>");

1voto

Alexander Daum Punkte 721

Am einfachsten ist es, eine andere Komponente, die den Zeilenumbruch unterstützt, so zu ändern, dass sie als Schaltfläche fungiert. Ich habe eine einfache Klasse erstellt, die JTextArea so manipuliert, dass sie als Schaltfläche fungiert.

 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 ist einfach ein Enum mit den Konstanten NORMAL, HOVERED, CLICKED

Der meiste Code wird nur verwendet, um das JTextArea wie einen JButton aussehen zu lassen, und das funktioniert ganz gut. Ein Nachteil ist, dass Sie die Möglichkeit verlieren, es über ButtonModels zu modifizieren, aber für die meisten Anwendungen wird dies ausreichen.

-3voto

Jens Cailliau Punkte 1
@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());
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X