You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在JButton中实现多行文本精准对齐(模拟键盘按键)

实现JButton的键盘按键样式(字母居中+数字右上角)

需求:模拟键盘按键样式,按钮内字母居中显示,数字位于右上角。尝试过HTML文本、添加双JLabel的方案均未成功,现有代码无法实现文本正确对齐。

尝试过的代码:

JPanel panel = new JPanel();
LayoutManager layout = new FlowLayout();
panel.setLayout(layout);

String htmlContent = "<html><font align=right>10</font><br><center><font width=100>Some text</font></center><br><font height=20></font></html>";
String secondContent = "<html><sup>HTML</sup><br><font>Multi-line</font>";

JButton nextButton = new JButton(htmlContent);
nextButton.setForeground(new Color(0x000000));
nextButton.setBackground(new Color(0xffffff));
nextButton.setBorderPainted(false);
nextButton.setFocusPainted(false);
nextButton.setBounds(0, 0, 30, 25);
panel.add(nextButton);

JButton secondButton = new JButton(secondContent);
secondButton.setForeground(new Color(0xffffff));
secondButton.setBackground(new Color(0x0062ff));
secondButton.setBorderPainted(false);
secondButton.setFocusPainted(false);
panel.add(secondButton);

JLabel firstLabel = new JLabel("First");
firstLabel.setHorizontalTextPosition(JLabel.RIGHT);
firstLabel.setVerticalTextPosition(JLabel.TOP);
firstLabel.setSize(150,100);
JLabel secondLabel = new JLabel("So much text");
secondLabel.setHorizontalTextPosition(JLabel.CENTER);
secondLabel.setVerticalTextPosition(JLabel.CENTER);
secondLabel.setSize(100,100);

JButton thirdBtn = new JButton();
thirdBtn.setForeground(new Color(0x000000));
thirdBtn.setBackground(new Color(0xbdbdbd));
thirdBtn.setBorderPainted(false);
thirdBtn.setFocusPainted(false);
thirdBtn.add(firstLabel);
thirdBtn.add(secondLabel);
thirdBtn.setPreferredSize(new Dimension(200, 80));
panel.add(thirdBtn);

frame.getContentPane().add(panel, BorderLayout.CENTER);

可行解决方案

方案1:优化HTML结构实现

之前的HTML布局逻辑有误,通过嵌套带样式的<div>块,就能精准控制文本位置:

// 构造符合要求的HTML文本
String keyHtml = "<html>" +
    "<div style='text-align: right; font-size: 12px; padding-right: 3px; padding-top: 2px;'>10</div>" +
    "<div style='text-align: center; font-size: 18px; margin-top: -10px;'>A</div>" +
    "</html>";

JButton keyButton = new JButton(keyHtml);
keyButton.setPreferredSize(new Dimension(60, 60));
keyButton.setBackground(Color.WHITE);
keyButton.setBorderPainted(true); // 保留边框模拟键盘按键
keyButton.setFocusPainted(false);
  • 第一个<div>通过text-align: right把数字固定在右上角,用padding控制边距
  • 第二个<div>设置text-align: center让字母居中,margin-top调整上下文本的间距,避免重叠
  • 可根据按钮尺寸调整字体大小、padding和margin值

方案2:自定义JButton重写绘制逻辑

如果HTML方案的样式灵活性不足,直接重写paintComponent方法,精确控制文本绘制坐标:

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

class KeyButton extends JButton {
    private final String numberText;
    private final String letterText;

    public KeyButton(String number, String letter) {
        this.numberText = number;
        this.letterText = letter;
        setPreferredSize(new Dimension(60, 60));
        setBackground(Color.WHITE);
        setFocusPainted(false);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

        // 绘制右上角数字
        Font numberFont = new Font(Font.SANS_SERIF, Font.PLAIN, 12);
        g2.setFont(numberFont);
        FontMetrics numberMetrics = g2.getFontMetrics(numberFont);
        int numberX = getWidth() - numberMetrics.stringWidth(numberText) - 5; // 右侧留5px边距
        int numberY = numberMetrics.getAscent() + 3; // 顶部留3px边距
        g2.drawString(numberText, numberX, numberY);

        // 绘制居中字母
        Font letterFont = new Font(Font.SANS_SERIF, Font.BOLD, 18);
        g2.setFont(letterFont);
        FontMetrics letterMetrics = g2.getFontMetrics(letterFont);
        int letterX = (getWidth() - letterMetrics.stringWidth(letterText)) / 2;
        int letterY = (getHeight() + letterMetrics.getAscent()) / 2;
        g2.drawString(letterText, letterX, letterY);
    }
}

// 使用示例
KeyButton customKey = new KeyButton("10", "A");
panel.add(customKey);
  • 利用FontMetrics计算文本的宽高,精准定位绘制坐标
  • 数字通过按钮宽度减去文本宽度和边距,实现右上角对齐
  • 字母通过计算按钮中心位置,实现完全居中
  • 这种方式可以灵活调整字体、颜色、边距等所有细节

内容的提问来源于stack exchange,提问作者seened

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 13:52:07