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 是错误的, setIconsetPressedIcon 字面意思是 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);