Java Swing:如何在自定义的Jbutton上设置文字?
Java Swing: How to set text on a self customized Jbutton?
这是我的 JButton 代码:
JButton Savebtn = new JButton();//("Save");
Savebtn.setFont(btnFont);
Savebtn.setOpaque(false);
Savebtn.setContentAreaFilled(false);
Savebtn.setBorder(null);
Savebtn.setMargin(new Insets(0, 0, 0, 0));
Savebtn.setIcon(new ImageIcon("src/Pic2/menubtn0.png"));
Savebtn.setPressedIcon(new ImageIcon("src/Pic2/menubtn1.png"));
//Savebtn.setText("Save");
效果是这样的:
我试过这样做:
JButton Savebtn = new JButton();//("Save");
Savebtn.setFont(btnFont);
Savebtn.setOpaque(false);
Savebtn.setContentAreaFilled(false);
Savebtn.setBorder(null);
Savebtn.setMargin(new Insets(0, 0, 0, 0));
Savebtn.setIcon(new ImageIcon("src/Pic2/menubtn0.png"));
Savebtn.setPressedIcon(new ImageIcon("src/Pic2/menubtn1.png"));
Savebtn.setText("Save");
文字没有出现,右侧出现一条白线。
谁能帮我解决这个问题?
PS:我不能只把文字放到我的图片上,因为我要显示的按钮文本与我的程序有关。
按钮图片:
我把你的代码片段放在我创建的 GUI 中。
这是我的想法。
现在,它不是一个非常灵敏的按钮。压不压你也分不清
我所做的是注释掉所有不寻常的 JButton 方法并确保我可以显示普通的 JButton。
然后我一次取消注释一行并测试。
测试,测试,测试。
这是我测试过的代码。
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class CustomButtonGUI implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new CustomButtonGUI());
}
@Override
public void run() {
JFrame frame = new JFrame("Custom Button");
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 BorderLayout());
panel.setPreferredSize(new Dimension(300, 100));
Font font = panel.getFont().deriveFont(48f);
JButton saveButton = new JButton("Save");
saveButton.setFont(font);
saveButton.setOpaque(false);
saveButton.setContentAreaFilled(false);
saveButton.setBorder(null);
saveButton.setMargin(new Insets(0, 0, 0, 0));
// saveButton.setIcon(new ImageIcon("src/Pic2/menubtn0.png"));
// saveButton.setPressedIcon(new ImageIcon("src/Pic2/menubtn1.png"));
//
panel.add(saveButton, BorderLayout.CENTER);
return panel;
}
}
我认为你使用的 JButton
是错误的, setIcon
和 setPressedIcon
字面意思是 JButton
旁边的图标,但是,对于游戏可能希望背景在从一个图像按下到另一个图像时发生变化,默认情况下 JButton
class 不支持。
这是我定制的 JButton
完全允许这样做:
CustomJButton.java:
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import javax.swing.JButton;
public class CustomJButton extends JButton {
private final BufferedImage normalIcon;
private final BufferedImage selectedIcon;
public CustomJButton(BufferedImage normalImage, BufferedImage selectedImage) {
super();
setOpaque(false);
setContentAreaFilled(false);
setBorder(null);
setFocusPainted(false);
setMargin(new Insets(0, 0, 0, 0));
this.normalIcon = normalImage;
this.selectedIcon = selectedImage;
}
@Override
public Dimension getPreferredSize() {
return new Dimension(normalIcon.getWidth(), normalIcon.getHeight());
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
// lets anti-alias for better quality
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
// lets anti-alias for text too
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
// lets draw the correct image depending on if the button is pressed or not
if (getModel().isPressed()) {
g2d.drawImage(selectedIcon, 0, 0, getWidth(), getHeight(), this);
} else {
g2d.drawImage(normalIcon, 0, 0, getWidth(), getHeight(), this);
}
// calc string x and y position
Font font = getFont();
String text = getText();
FontMetrics metrics = g2d.getFontMetrics(font);
int textWidth = metrics.stringWidth(text);
int textHeight = metrics.getHeight();
int textY = getWidth() / 2 - textWidth / 2;
int textX = getHeight() / 2 - textHeight / 2 + metrics.getAscent();
// draw the text
g2d.drawString(text, textY, textX);
}
}
然后你会像这样使用:
CustomJButton button = new CustomJButton(ImageIO.read(new URL("https://i.stack.imgur.com/xCGQQ.png")), ImageIO.read(new URL("https://i.stack.imgur.com/R9i1s.png")));
button.setFont(new Font("Jokerman", Font.BOLD, 22));
button.setForeground(Color.WHITE);
button.setText("Press Me!");
button.addActionListener((ActionEvent e) -> {
JOptionPane.showMessageDialog(frame, "You pressed me");
});
The text did not appear and a white line occured at the right side
我怀疑您的问题是您没有使用布局管理器(或者您正在手动设置按钮的首选大小)并且按钮的大小不正确并且文本被截断了。
默认情况下,文本将显示在图标的右侧。所以你看到的是你的图标,然后是图标和文字之间的差距。
您需要将按钮配置为在图标顶部居中显示文本(而不是图标右侧):
JButton button = new JButton( "Save" );
button.setIcon(...);
button.setPressedIcon(...);
button.setHorizontalTextPosition(JLabel.CENTER);
button.setVerticalTextPosition(JLabel.CENTER);
这是我的 JButton 代码:
JButton Savebtn = new JButton();//("Save");
Savebtn.setFont(btnFont);
Savebtn.setOpaque(false);
Savebtn.setContentAreaFilled(false);
Savebtn.setBorder(null);
Savebtn.setMargin(new Insets(0, 0, 0, 0));
Savebtn.setIcon(new ImageIcon("src/Pic2/menubtn0.png"));
Savebtn.setPressedIcon(new ImageIcon("src/Pic2/menubtn1.png"));
//Savebtn.setText("Save");
效果是这样的:
我试过这样做:
JButton Savebtn = new JButton();//("Save");
Savebtn.setFont(btnFont);
Savebtn.setOpaque(false);
Savebtn.setContentAreaFilled(false);
Savebtn.setBorder(null);
Savebtn.setMargin(new Insets(0, 0, 0, 0));
Savebtn.setIcon(new ImageIcon("src/Pic2/menubtn0.png"));
Savebtn.setPressedIcon(new ImageIcon("src/Pic2/menubtn1.png"));
Savebtn.setText("Save");
文字没有出现,右侧出现一条白线。 谁能帮我解决这个问题?
PS:我不能只把文字放到我的图片上,因为我要显示的按钮文本与我的程序有关。
按钮图片:
我把你的代码片段放在我创建的 GUI 中。
这是我的想法。
现在,它不是一个非常灵敏的按钮。压不压你也分不清
我所做的是注释掉所有不寻常的 JButton 方法并确保我可以显示普通的 JButton。
然后我一次取消注释一行并测试。
测试,测试,测试。
这是我测试过的代码。
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class CustomButtonGUI implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new CustomButtonGUI());
}
@Override
public void run() {
JFrame frame = new JFrame("Custom Button");
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 BorderLayout());
panel.setPreferredSize(new Dimension(300, 100));
Font font = panel.getFont().deriveFont(48f);
JButton saveButton = new JButton("Save");
saveButton.setFont(font);
saveButton.setOpaque(false);
saveButton.setContentAreaFilled(false);
saveButton.setBorder(null);
saveButton.setMargin(new Insets(0, 0, 0, 0));
// saveButton.setIcon(new ImageIcon("src/Pic2/menubtn0.png"));
// saveButton.setPressedIcon(new ImageIcon("src/Pic2/menubtn1.png"));
//
panel.add(saveButton, BorderLayout.CENTER);
return panel;
}
}
我认为你使用的 JButton
是错误的, setIcon
和 setPressedIcon
字面意思是 JButton
旁边的图标,但是,对于游戏可能希望背景在从一个图像按下到另一个图像时发生变化,默认情况下 JButton
class 不支持。
这是我定制的 JButton
完全允许这样做:
CustomJButton.java:
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import javax.swing.JButton;
public class CustomJButton extends JButton {
private final BufferedImage normalIcon;
private final BufferedImage selectedIcon;
public CustomJButton(BufferedImage normalImage, BufferedImage selectedImage) {
super();
setOpaque(false);
setContentAreaFilled(false);
setBorder(null);
setFocusPainted(false);
setMargin(new Insets(0, 0, 0, 0));
this.normalIcon = normalImage;
this.selectedIcon = selectedImage;
}
@Override
public Dimension getPreferredSize() {
return new Dimension(normalIcon.getWidth(), normalIcon.getHeight());
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
// lets anti-alias for better quality
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
// lets anti-alias for text too
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
// lets draw the correct image depending on if the button is pressed or not
if (getModel().isPressed()) {
g2d.drawImage(selectedIcon, 0, 0, getWidth(), getHeight(), this);
} else {
g2d.drawImage(normalIcon, 0, 0, getWidth(), getHeight(), this);
}
// calc string x and y position
Font font = getFont();
String text = getText();
FontMetrics metrics = g2d.getFontMetrics(font);
int textWidth = metrics.stringWidth(text);
int textHeight = metrics.getHeight();
int textY = getWidth() / 2 - textWidth / 2;
int textX = getHeight() / 2 - textHeight / 2 + metrics.getAscent();
// draw the text
g2d.drawString(text, textY, textX);
}
}
然后你会像这样使用:
CustomJButton button = new CustomJButton(ImageIO.read(new URL("https://i.stack.imgur.com/xCGQQ.png")), ImageIO.read(new URL("https://i.stack.imgur.com/R9i1s.png")));
button.setFont(new Font("Jokerman", Font.BOLD, 22));
button.setForeground(Color.WHITE);
button.setText("Press Me!");
button.addActionListener((ActionEvent e) -> {
JOptionPane.showMessageDialog(frame, "You pressed me");
});
The text did not appear and a white line occured at the right side
我怀疑您的问题是您没有使用布局管理器(或者您正在手动设置按钮的首选大小)并且按钮的大小不正确并且文本被截断了。
默认情况下,文本将显示在图标的右侧。所以你看到的是你的图标,然后是图标和文字之间的差距。
您需要将按钮配置为在图标顶部居中显示文本(而不是图标右侧):
JButton button = new JButton( "Save" );
button.setIcon(...);
button.setPressedIcon(...);
button.setHorizontalTextPosition(JLabel.CENTER);
button.setVerticalTextPosition(JLabel.CENTER);