-2

I want to be able to change the Background with a simple Jbutton. The background and every other component I will add will be displaced on a JPanel. I already figured out how to set a background with Java.awt, although I can't figure out how to repaint the background without getting errors.

public class StartPanel extends JPanel{ 
    private Image virus = "ImagePath";
    private Image ecoli = "ImagePath";  
    private Graphics g;
    private boolean img;

    public StartPanel(){        
        this.setLayout(null);       
        this.add(Button()); 
        img = true;


    }   

    private JButton Button(){
        JButton b = new JButton("a");
        b.setBounds(230,480,20,20);
        b.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent arg0) {
                 img = !img;
                 repaint();
            }
        });
        return b;
    }   


    public void paint(Graphics g){
       If(img){
        g.drawImage(ecoli,0,0,this);
    } else {
       g.drawImage(virus,0,0,this);
   }
}
}
  • 1
    1) `this.setLayout(null);` Java GUIs have to work on different OS', screen size, screen resolution etc. using different PLAFs in different locales. As such, they are not conducive to pixel perfect layout. Instead use layout managers, or [combinations of them](http://stackoverflow.com/a/5630271/418556) along with layout padding and borders for [white space](http://stackoverflow.com/a/17874718/418556). 2) `public void paint(Graphics g){` For any `JComponent`, that should be `public void paintComponent(Graphics g){` 3) `public void update(){` Don't touch this method. 4) .. – Andrew Thompson Mar 02 '17 at 19:31
  • 1
    .. 4) `Graphics g = getGraphics();` No, no, a thousand times no. This is the wrong way to do custom painting. Go through the [Performing Custom Painting](https://docs.oracle.com/javase/tutorial/uiswing/painting/) lesson of the tutorial to find out how to do it correctly. – Andrew Thompson Mar 02 '17 at 19:33
  • 1
    *"I have found a solution. No replies neccessary."* - then delete the question – MadProgrammer Mar 02 '17 at 19:48
  • @AndrewThompson, thx for the advices. Your points make total sense, but it would be an overkill for a school project. I've changed it the way Abgehter suggested. Although they are still problems with the JComponents being covered by the Image and are only visible by clicking on them. Any idea how to fix this? – Power-Elch Mar 03 '17 at 11:40
  • *"..it would be an overkill for a school project."* If you think learning to code using good practices is 'overkill', maybe this course is not for you. At the moment that stuff above looks like 'coding by magic'. As you have seen, magic does not work. *"Any idea how to fix this?"* I summed them up in the first 4 points. @MadProgrammer *"then delete the question"* Couldn't agree more. This Q&A **subtracts** from the sum total of human knowledge. – Andrew Thompson Mar 03 '17 at 11:46

2 Answers2

0

You can't just initialize your images with a String they need to be initialized in some other way. I believe the simplest way is to use an ImageIcon, like this:

Image ecoli = new ImageIcon("ImagePath").getImage();
Sore Throat
  • 189
  • 5
-1

If you are fine with your awt-Image ok...

For the changing-task just use an boolean witch you switch in the actionlistener

public class StartPanel extends JPanel{

private BufferedImage virus;
private BufferedImage ecoli;

boolean pic1;


public StartPanel(){

    try{
       virus = ImageIO.read(new File("PathtoImage"));
       ecoli = ImageIO.read(new File("PathtoImage"));
    }
    catch (IOException ex){
        System.out.println("Error ;-)");
    }

    this.setLayout(null);
    this.add(Button());
    pic1 = true;

}

private JButton Button(){
    JButton b = new JButton("a");
    b.setBounds(230,480,20,20);
    b.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent arg0) {
            pic1 = !pic1;
            repaint();
        }
    });
    return b;
}

protected void paintComponent(Graphics g){
    if(pic1)
        g.drawImage(ecoli,0,0,this);
    else
        g.drawImage(virus,0,0,this);
}

}

If you have more than two images use an int in combination with switch case

Abgehter
  • 164
  • 1
  • 9
  • Unfortunatly, your suggestion is not working. The problem is when the Panel is initialized the paintComponent draws the image. Your code just changed the boolean of which image should be painted but it does not change the actual background, after the Button is pressed, which cant happen before the window appears. – Power-Elch Mar 02 '17 at 15:03
  • @Power-Elch Im Sorry! I forgot the most important^^ -> add repaint() to the actionlistener (I edited my example) – Abgehter Mar 02 '17 at 20:09
  • You also forget to call `super.paintComponent` – MadProgrammer Mar 03 '17 at 11:55