Shuxin
Shuxin

Reputation: 29

Java Swing: How to set text on a self customized Jbutton?

This is my JButton code:

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

The effect is like this :

pic1

I tried to do this:

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

pic2

The text did not appear and a white line occured at the right side. Could any one help me with this?

PS:I can't just put the words onto my picture because the button text I want to show is related to my program.

The button picture: button

Upvotes: 1

Views: 390

Answers (3)

camickr
camickr

Reputation: 324108

The text did not appear and a white line occured at the right side

I suspect your issue is that you are not using layout managers (or you are manually setting the preferred size of your button) and the size of your button is incorrect and the text is being truncated.

By default the text will appear to the right of the Icon. So what you see is your Icon and then the gap between the Icon and the text.

You need to configure the button for the text to display centered on top the Icon (not right of the Icon):

JButton button = new JButton( "Save" );
button.setIcon(...);
button.setPressedIcon(...);   
button.setHorizontalTextPosition(JLabel.CENTER);
button.setVerticalTextPosition(JLabel.CENTER);

Upvotes: 1

David Kroukamp
David Kroukamp

Reputation: 36423

I think you are using the JButton wrong, the setIcon and setPressedIcon is literally for an icon next to the JButton, however, for a game you probably want the background to change when pressed from one image to another, which by default the JButton class does not support.

Here is a custom JButton I made that allows exactly this:

enter image description here

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

Which you would then use like this:

CustomJButton button = new CustomJButton(ImageIO.read(new URL("https://i.sstatic.net/xCGQQ.png")), ImageIO.read(new URL("https://i.sstatic.net/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");
});

Upvotes: 1

Gilbert Le Blanc
Gilbert Le Blanc

Reputation: 51445

I took your code snippet and put it in a GUI I created.

Here's what I came up with.

Cutsom Button GUI

Now, it's not a very responsive button. You can't tell whether it's pressed or not.

What I did was comment out all of the unusual JButton methods and made sure I could display an ordinary JButton.

Then I uncommented out one line at a time and tested.

Test, test, test.

Here's the code I tested with.

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

}

Upvotes: 1

Related Questions