java JButtons 中的自动换行

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5766175/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 12:39:56  来源:igfitidea点击:

Word Wrap in JButtons

javaswingjbutton

提问by Deepak

Is it possible to achieve automatic word wrap of texts in JButtons? I am having few dynamic buttons which I create on runtime. I want to put word wrap feature on the buttons so that I can see some better test on buttons. Is it possible to do that?

是否可以在 JButtons 中实现文本自动换行?我在运行时创建的动态按钮很少。我想在按钮上放置自动换行功能,以便我可以对按钮进行更好的测试。有可能这样做吗?

回答by Andrew Thompson

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.

此示例使用 Java 的内置 CSS 呈现功能来执行确定何时进行换行的“繁重工作”。它使用JLabel,但同样的原则适用于任何渲染 HTML 的组件。

FixedWidthText.java

固定宽度文本.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

160 像素

enter image description here

在此处输入图片说明

200px

200 像素

enter image description here

在此处输入图片说明

50%

50%

enter image description here

在此处输入图片说明

回答by Romain Hippeau

Use HTML...

使用 HTML...

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

回答by Alexander Daum

The easiest thing to do is to modify another Component that supports word wrap so that it acts as a Button. I made a simple class which manipulates JTextArea to act as Button.

最简单的做法是修改另一个支持自动换行的组件,使其充当按钮。我制作了一个简单的类,它操作 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 is simply an enum with the Constants NORMAL, HOVERED, CLICKED

BtnState 只是一个带有常量 NORMAL、HOVERED、CLICKED 的枚举

Most of the code is just used to make the JTextArea look like a JButton and it works quite fine. One drawback is that you loose the ability of modifying it via ButtonModels, but for the most applications this will be enough.

大部分代码只是用来使 JTextArea 看起来像一个 JButton,它工作得很好。一个缺点是你失去了通过 ButtonModels 修改它的能力,但对于大多数应用程序来说这已经足够了。

回答by Jens Cailliau

@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());
}