Как правильно выровнять многострочный текст в 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);

Пока что вот код, который я пытался использовать для достижения этого, но я не вижу результата того, что мне нужно, просто не могу выровнять текст вправо или заставить его перетекать туда. Также пытался использовать кнопку с двойной меткой, кажется, что метки не могут быть выровнены друг относительно друга. Есть ли способ сделать это?

P.S. Забыл упомянуть, пытался использовать align=right или align='right' или просто 'right' в тегах HTML, но ничего из этого не работает.

Полученные результаты:

Начните с поиска справочника по синтаксису HTML. Не просто гадать. Например, почему во всех ваших примерах используется тег Font? Шрифт — это стиль или размер текста. Вы не можете назначить выравнивание шрифту. Почему вы должны сначала определить тег «sup»? Логически он идет после текста, поэтому определяйте свой HTML таким же образом. Для базового теста вы можете начать с: String secondContent = "<html>Multi-line<sup>HTML</sup></html>";

camickr 10.05.2023 16:27

Не добавляйте JLabels к JButton; это не сработает. Кроме того, нет смысла устанавливать FlowLayout на свежесозданном экземпляре JPanel, так как в любом случае это значение по умолчанию. camickr уже рассказал вам, как правильно сделать html, но обратите внимание, что нет смысла писать подразумеваемые теги в таких фрагментах, достаточно только "<html>Some text<sup>10" и "<html>Multi-line<sup>HTML"… И в качестве примечания, глядя на ваш скриншот, мне интересно, что это RoundedBorder подходит для. Кажется, это не имеет никакого эффекта.

Holger 10.05.2023 17:04

Почему бы просто не создать изображения, как вы сделали для вопроса, загрузить изображения и отобразить их на JButtons?

Gilbert Le Blanc 10.05.2023 20:15
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
3
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

У Oracle есть полезный учебник Создание графического интерфейса с помощью Swing . Пропустите раздел Изучение Swing с помощью среды IDE NetBeans. Обратите особое внимание на раздел Выполнение заказной живописи.

Как я сказал в своем комментарии, почему бы просто не создать изображение и не поместить его в JButton.

Вот графический интерфейс, который я придумал.

Чтобы создать изображения для всех ваших JButtons, просто вызовите метод создания изображения в цикле.

Вот полный исполняемый код.

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class JButtonImageExample implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new JButtonImageExample());
    }

    private BufferedImage image;

    public JButtonImageExample() {
        Font font = new Font(Font.DIALOG, Font.PLAIN, 36);
        this.image = createLetterImage(70, 70, font, 'G', 7);
    }

    @Override
    public void run() {
        JFrame frame = new JFrame("Example");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.add(createButtonPanel(), BorderLayout.CENTER);

        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    private JPanel createButtonPanel() {
        JPanel panel = new JPanel(new FlowLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(100, 100, 100, 100));

        JButton button = new JButton(new ImageIcon(image));
        panel.add(button);

        return panel;
    }

    private BufferedImage createLetterImage(int width, int height, Font font,
            char letter, int value) {
        BufferedImage image = new BufferedImage(width, height,
                BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = (Graphics2D) image.getGraphics();
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
                RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
                RenderingHints.VALUE_FRACTIONALMETRICS_ON);
        g2d.setFont(font);

        g2d.setColor(Color.WHITE);
        g2d.fillRect(0, 0, width, height);

        g2d.setColor(Color.BLACK);
        String s = Character.toString(letter);
        Rectangle rect = new Rectangle(0, 0, width, height);
        drawCenteredString(g2d, s, rect, font);

        g2d.setColor(Color.BLUE);
        s = Integer.toString(value);
        drawRightAlignedString(g2d, s, width, font);

        g2d.dispose();

        return image;
    }

    private void drawRightAlignedString(Graphics2D g2d, String text, int width,
            Font font) {
        int pointSize = font.getSize() / 2;
        g2d.setFont(font.deriveFont((float) pointSize));
        FontMetrics metrics = g2d.getFontMetrics(g2d.getFont());
        int margin = 2;
        int x = width - metrics.stringWidth(text) - margin;
        int y = metrics.getAscent() - margin;
        g2d.drawString(text, x, y);
    }

    private void drawCenteredString(Graphics2D g2d, String text, Rectangle rect,
            Font font) {
        FontMetrics metrics = g2d.getFontMetrics(font);
        int x = rect.x + (rect.width - metrics.stringWidth(text)) / 2;
        int y = rect.y + ((rect.height - metrics.getHeight()) / 2)
                + metrics.getAscent();
        g2d.setFont(font);
        g2d.drawString(text, x, y);
    }

}

Другие вопросы по теме