如何正确对齐JButton中的多行文本?

huangapple go评论73阅读模式
英文:

How to properly align a multiline text in a JButton?

问题

I am trying to figure it out how to align some text in a JButton, but it seems to be more challenging than I thought it can be. In some ways I have tried to use HTML and JLabel, but had no luck with it. What I am trying to do, I want to simulate a keyboard key with letter centered and a digit on the right-top of it.

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);

So far here is the code I have tried to use to achieve this, but I can see no result of what I need, just cannot align the text to right or make it flow to there. Also tried using double labeled button, it seems that the labels cannot be aligned regarding each other. Is there a way to do that?

P.S. Forgot to mention, have tried to use align=right or align='right' or just 'right' in HTML tags, but none of these works

Results:

如何正确对齐JButton中的多行文本?

英文:

I am trying to figure it out how to align some text in a JButton, but it seems to be more challenging than I thought it can be. In some ways I have tried to use HTML and JLabel, but had no luck with it. What I am trying to do, I want to simulate a keyboard key with letter centered and a digit on the right-top of it.

如何正确对齐JButton中的多行文本?

JPanel panel = new JPanel();
LayoutManager layout = new FlowLayout();
panel.setLayout(layout);
String htmlContent = &quot;&lt;html&gt;&lt;font align=right&gt;10&lt;/font&gt;&lt;br&gt;&lt;center&gt;&lt;font width=100&gt;Some text&lt;font&gt;&lt;/center&gt;&lt;br&gt;&lt;font height=20&gt;&lt;/font&gt;&lt;/html&gt;&quot;;
String secondContent = &quot;&lt;html&gt;&lt;sup&gt;HTML&lt;/sup&gt;&lt;br&gt;&lt;font&gt;Multi-line&lt;/font&gt;&quot;;
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(&quot;First&quot;);
firstLabel.setHorizontalTextPosition(JLabel.RIGHT);
firstLabel.setVerticalTextPosition(JLabel.TOP);
firstLabel.setSize(150,100);
JLabel secondLabel = new JLabel(&quot;So much text&quot;);
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);

So far here is the code I have tried to use to achieve this, but I can see no result of what I need, just cannot align the text to right or make it flow to there. Also tried using double labeled button, it seems that the labels cannot be aligned regarding each other. Is there a way to do that?

P.S. Forgot to mention, have tried to use align=right or align='right' or just 'right' in HTML tags, but none of these works

Results:

如何正确对齐JButton中的多行文本?

答案1

得分: 2

Oracle有一个有用的教程,使用Swing创建GUI。跳过使用NetBeans IDE学习Swing部分。特别关注执行自定义绘制部分。

正如我在评论中所说,为什么不只是创建一张图像并将图像放在JButton中。

这是我设计的GUI。

如何正确对齐JButton中的多行文本?

要为所有的JButton创建图像,只需在循环中调用图像创建方法。

以下是完整的可运行代码。

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);
    }
}
英文:

Oracle has a helpful tutorial, Creating a GUI With Swing. Skip the Learning Swing with the NetBeans IDE section. Pay particular attention to the Performing Custom Painting section.

As I said in my comment, why not just create an image and place the image in a JButton.

Here's the GUI I came up with.

如何正确对齐JButton中的多行文本?

To create images for all your JButtons, just call the image creation method in a loop.

Here's the complete runnable code.

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, &#39;G&#39;, 7);
}
@Override
public void run() {
JFrame frame = new JFrame(&quot;Example&quot;);
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);
}
}

huangapple
  • 本文由 发表于 2023年5月10日 21:48:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/76219222.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定