英文:
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:
英文:
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:
答案1
得分: 2
Oracle有一个有用的教程,使用Swing创建GUI。跳过使用NetBeans IDE学习Swing部分。特别关注执行自定义绘制部分。
正如我在评论中所说,为什么不只是创建一张图像并将图像放在JButton
中。
这是我设计的GUI。
要为所有的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.
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, '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);
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论