【问题标题】:How to set text above and below a JButton icon?如何在 JButton 图标上方和下方设置文本?
【发布时间】:2011-11-13 18:32:19
【问题描述】:

我想将文本上下设置为JButton 的图标。目前,为了实现这一点,我重写了布局管理器并使用了三个 JLabel 实例(即 2 个用于文本,1 个用于图标)。但这似乎是一个肮脏的解决方案。

有没有更直接的方法?

注意 -
我不是在寻找 multi-line 解决方案,我在寻找 multi-label解决方案。虽然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);
        }
    }

}

【问题讨论】:

  • 不确定我是否理解要求。按钮的边框呢?如果您希望文本超出边界,那么我认为您需要使用您的方法。或者你是否试图让文本在边框内?如果您摆脱了边框,那么为什么要使用按钮?你需要鼠标支持吗?发布您的 SSCCE,展示您目前所做的事情,以便我们可以看到您想要实现的确切外观。

标签: java swing jbutton


【解决方案1】:

没有办法在 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);
    }
}

【讨论】:

  • 所以,我建议你继续做你正在做的事情或使用 CompoundIcon。
  • 不确定您使用的是什么方法,但我发布了 CompoundIcon 解决方案。
  • 不错的解决方案 :-) 虽然:不要让 TextIcon 手动绘制字符串(前面有大量的别名问题),而是让配置了文本的标签将自身绘制到 BufferedImage 并渲染该图像.
  • @kleopatra,再次正确。我只是仔细比较了渲染,TextIcon 并不完全相同。但是,我刚刚发现JDK6现在支持“桌面渲染提示”。当我使用这些属性时,渲染现在是相同的。更新版本的 TextIcon 可用。
  • 您无法像内部一样获得字符串渲染(确切的渲染提示因设备而异,可能取决于操作系统和 LAF,也可能不取决于)。可以为你做这件事的方法是包私有的,甚至隐藏在 sun 类的深处。所以一般的建议是不要尝试,你迟早会被咬(在那里;-)。而是让内部人员为 JLabel 做他们的事情并获取图像。
【解决方案2】:

你有两个四个选项

1) 使用 JLabel + Icon + Html (

2) 使用 XxxButtonUI 并覆盖所有必需的 methods from API

3) 带半透明的JLayeredPane???,另一个带半透明的Layout,作为JButton的JLabel或JComponent,

4) 有很多 Graphics SW 可以为 Icon 准备背景为 *.jpg,然后通过 Event、Action 或 JButton 的实际设置来更改任何内容都非常简单

不正确的方法是寻找 JLabel + What 而不是 JButton,我认为这是一半的解决方法

【讨论】:

    【解决方案3】:

    【讨论】:

    • 正如我上面所说,我已经实现了这样的解决方案。我正在寻找 JButton 是否能够做到这一点,而无需我对布局管理器进行大规模更换。
    猜你喜欢
    • 2010-09-26
    • 2011-01-10
    • 1970-01-01
    • 1970-01-01
    • 2013-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多