0

i created a custom Java Button like this

 public class GraphicPaintedButton extends JButton implements ToPaint{

    protected BufferedImage background;
    private boolean painted = false;

    public GraphicPaintedButton() {

    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        if(painted){
        System.out.println("PAINTING!");
        Dimension size = getSize();
        g.drawImage(background, 0, 0,size.width, size.height,0, 0, background.getWidth(), background.getHeight(), null);
        }
    }

    @Override
    public void loadImage(String url){

        painted = true;
        URL imagePath = getClass().getResource(url);
        BufferedImage result = null;
        try {
            result = ImageIO.read(imagePath);
        } catch (IOException | IllegalArgumentException e) {
            System.err.println("Errore, immagine non trovata");
            e.printStackTrace();
        }
        background = result;
    }
    }

Iif i load an image on the button, it calls the repaint,and it's good, the image is shown, when i load a new Image, it calls the repaint again and the new Image is shown. The problem is when i pass the mouse over the button, it calls the rapaint, but loads the old image. Why? And how did it get the old image, as the new one should have replaced it?

Cath
  • 460
  • 6
  • 21

1 Answers1

1

I don't know why you want to go this extend and not simply use the icon property of the button, but...

First, I'd get rid of the painted flag, it runs the risk of allowing the paintComponent method to try and paint a null image, because the loadImage method may fail, but the painted flag is always set to true - Let's face it, you could easily end up with painted == true and background == null ... which is not a valid state

Instead, reason about the actual state you're interested in...

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    if (background != null) {
        Dimension size = getSize();
        g.drawImage(background, 0, 0, size.width, size.height, 0, 0, background.getWidth(), background.getHeight(), null);
    }
}

I would also change the loadImage method

public void loadImage(URL url) throws IOException {
    background = ImageIO.read(url);
    revalidate();
    repaint();
}

First, don't use String, it's meaning is to ambiguous, instead, specify the lowest common parameter you're willing to deal with.

Secondly, the image is either going to load or it's not, if you're not going to deal with the exception, in any meaningful fashion, pass it back to the caller who may be in a better position to deal with it - IMHO

I don't know if this important or not, but I'd also consider overriding the getPreferredSize method...

@Override
public Dimension getPreferredSize() {
    return background == null ? new Dimension(10, 10) : new Dimension(background.getWidth(), background.getHeight());
}

This will at least try and match the button's size to the size of the image

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • i removed the painted boolean, and changed the loadImage, but it doesn't remove that it shows the wrong image, can i force not to repaint on mouseover – Gabriel Logronio Jul 07 '17 at 11:47
  • hey, ok i tried with the icon, but how do i resize the image to fit the JButton? The resize method needs the height and the width, but i don't have them fixed, but put in a gridBagLayout – Gabriel Logronio Jul 07 '17 at 12:15
  • So, know I'm wondering if you're adding the button multiple times, one over the other – MadProgrammer Jul 07 '17 at 22:20
  • If you want to resize the icon, have a look at [Resizing icon to fit on JButton in Java?](https://stackoverflow.com/questions/25798156/resizing-icon-to-fit-on-jbutton-in-java/25798462#25798462) – MadProgrammer Jul 07 '17 at 22:23