如何在JButton图标上方和下方设置文本?

3
我希望在一个 JButton 的图标上下设置文本。目前,为了实现这一点,我重写了布局管理器,并使用了三个 JLabel 实例(即两个用于文本和一个用于图标)。但这似乎是一种不太好的解决方案。是否有更直接的方法来做到这一点?
注意 - 我不是寻求多行解决方案,我正在寻找多标签解决方案。虽然this文章将其称为多行解决方案,但实际上它似乎是指多标签解决方案。

例子

import java.awt.Component;
import java.awt.FlowLayout;
import javax.swing.BoxLayout;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;

public final class JButtonDemo {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable(){
            @Override
            public void run() {
                createAndShowGUI();
            }
        });
    }


    private static void createAndShowGUI(){
        final JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new FlowLayout());
        frame.add(new JMultiLabelButton());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    private static final class JMultiLabelButton extends JButton
    {
        private static final long serialVersionUID = 7650993517602360268L;

        public JMultiLabelButton()
        {
            super();
            setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
            add(new JCenterLabel("Top Label"));
            add(new JCenterLabel(UIManager.getIcon("OptionPane.informationIcon"))); 
            add(new JCenterLabel("Bottom Label"));
        }
    }

    private static final class JCenterLabel extends JLabel
    {
        private static final long serialVersionUID = 5502066664726732298L;

        public JCenterLabel(final String s)
        {
            super(s);
            setAlignmentX(Component.CENTER_ALIGNMENT);
        }

        public JCenterLabel(final Icon i)
        {
            super(i);
            setAlignmentX(Component.CENTER_ALIGNMENT);
        }
    }

}

enter image description here


1
我不确定我理解这个要求。按钮的边框呢?如果您希望文字在边框外面,那么我认为您需要使用您的方法。或者您是想让文本出现在边框内部吗?如果您去掉了边框,那么为什么要使用按钮?您需要鼠标支持吗?请发布一个 SSCCE,演示您当前所做的内容,以便我们可以看到您试图实现的确切外观。 - camickr
3个回答

5

无法在JButton的顶部/底部之间拆分文本。这将涉及自定义绘制。

由于我不确定您的确切要求,因此我将提出一些随机想法:

  1. 您可以使用带有文本和图标的JButton。API中有一些方法,允许您控制文本相对于图标的位置。然后您需要一个第二个标签来显示另一行文本。基本上与当前解决方案相同,但只需要两个标签。

  2. 您可以使用Text IconCompound Icon类将3个单独的图标创建为1个图标。然后,您只需将图标添加到按钮即可。

  3. 使用JTextPane。它支持insertIcon()方法。因此,您可以添加一行文本,添加图标,然后添加其他行文本。如果您不想文本左对齐,可以调整文本窗格的段落属性以使文本在空间内水平对齐。您还可以玩弄背景颜色,使其看起来像标签。

使用CompoundIcon的示例:

import java.awt.*;
import javax.swing.*;

public final class JButtonDemo {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable(){
            @Override
            public void run() {
                createAndShowGUI();
            }
        });
    }


    private static void createAndShowGUI()
    {
        JButton button = new JButton();

        CompoundIcon icon = new CompoundIcon(CompoundIcon.Axis.Y_AXIS,
            new TextIcon(button, "Top Label"),
            UIManager.getIcon("OptionPane.informationIcon"),
            new TextIcon(button, "Bottom Label"));

        button.setIcon( icon );
        button.setFocusPainted( false );

        final JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new FlowLayout());
        frame.add( button );
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

2
因此,我建议您继续做您正在做的事情或使用CompoundIcon。 - camickr
不确定您使用了什么方法,但我发布了一个CompoundIcon解决方案。 - camickr
不错的解决方案 :-) 但是:不要让TextIcon手动绘制字符串(会有大量的锯齿问题),而是让一个配置了文本的标签自己绘制到一个BufferedImage上,然后再渲染该图像。 - kleopatra
@kleopatra,你说得对。我刚刚仔细比较了渲染和TextIcon并不完全相同。但是,我刚刚发现JDK6现在支持“桌面渲染提示”。当我使用这些属性时,渲染现在是相同的。新版本的TextIcon已经可用。 - camickr
@camickr,不要忘记,即使JButton最终调用SwingUtilities2.drawString,而SwingUtilities2.drawString又调用Graphics.drawString,但可能会有设置渲染提示的地方影响文本的绘制方式。 - Jason
显示剩余3条评论

2
你有四个选择:
1)使用JLabel + Icon + Html (<= Html 3.2)
2)使用XxxButtonUI并覆盖所有需要的 API方法 3)JLayeredPane with translucency???,另一个带有半透明效果的布局,作为JButton的JLabel或JComponent,
4)有很多图形软件可以准备背景作为*.jpg的图标,然后通过事件、操作或实际设置来轻松更改任何内容的按钮。
不正确的方法是寻找JLabel + Whatever而不是JButton,我认为这是一种不完整的解决方案。

-1

3
如我之前所说,我已经实现了这样的解决方案。我想知道JButton是否能够做到这一点,而无需彻底更换布局管理器。 - mre

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接