0

I wonder why the repiant() method is not working as intended. My Code:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JPanel;

public class RightPanel extends JPanel implements ActionListener{
    JButton buttono;
    JButton buttonu;
    MyFrame frame;
    ButtomPanel s;
    
    public RightPanel(MyFrame frame){
        super();
        this.frame=frame;
         s= new ButtomPanel(frame);
        this.setPreferredSize(new Dimension((frame.getWidth()/3),frame.getHeight()));
        setBackground(Color.green);
        setLayout(new BorderLayout());
        
        buttono = new JButton ("up");
        buttonu = new JButton ("down");
        buttono .addActionListener(this);
        buttonu .addActionListener(this);
        add(buttono , BorderLayout.NORTH);
        add(buttonu , BorderLayout.SOUTH);
        
        setVisible(true);
    }
    


    @Override
    public void actionPerformed(ActionEvent e) {
        
        
        if (e.getSource()==buttono) {
            System.out.println("Up");
        s.x=s.x+10;
        s.repaint();
        
        
    }
}

I want to Repaint following class:

import java.awt.Color;
import java.util.Timer;
import java.util.TimerTask;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class ButtomPanel extends JPanel {
    MyFrame frame;

    
     BufferedImage image;
     boolean geklickt=false;
     
     public static int x=0;;
    public ButtomPanel(MyFrame frame) {
        super();
        this.frame=frame;
        this.setPreferredSize(new Dimension(((frame.getWidth()/3)*2),585));     
        setBackground(Color.blue); 
        
        
        
        java.net.URL resource = getClass().getResource("/resources/siegel.jpg");
        try {
            image = ImageIO.read(resource);
        } catch (IOException e) {
            e.printStackTrace();
        }
    
        setVisible(true);
        
    }

    public void paint(Graphics g) {
        super.paint(g);       
        g.drawImage(image, 150+x, 150+x, 150, 150, null);}
 
 }
}

I want to change with the ActionListener in the RightPanel Class the x from the BottomPanel Class and then repaint it, but it doesnt work. I can raise the x, but s.repaint() does not call the paint-Method.

Fynn
  • 25
  • 2
  • Add a call to invalidate() before the repaint. – Just another Java programmer Apr 27 '22 at 21:24
  • 1
    "Swing programs should override `paintComponent()` instead of overriding `paint()`."—[*Painting in AWT and Swing: The Paint Methods*](http://www.oracle.com/technetwork/java/painting-140037.html#callbacks). See also [*Initial Threads*](https://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html). – trashgod Apr 27 '22 at 21:27
  • 1
    is `s` - the instance of `ButtomPanel` - being added to any visible component? I can't find it in posted code (maybe I'm too tired; it's so late here) – user16320675 Apr 27 '22 at 21:29
  • Your ButtonPanel class needs "setter" methods to change the x/y values. Then in the setter method you invoke repaint(). That is each class to be responsible for repainting itself whenever a property of the class changes. – camickr Apr 27 '22 at 22:17
  • 1
    `public static int x=0;;` `static` is not your friend – MadProgrammer Apr 27 '22 at 22:37
  • 1
    `s` is never added to anything – MadProgrammer Apr 27 '22 at 22:40

1 Answers1

1

s is never added to anything, so it will never be painted.

this.setPreferredSize(new Dimension((frame.getWidth()/3),frame.getHeight())); is a horribly bad idea. The window should be conforming to the size of the components, not the other way round. In fact, there's never really a good reason to expose MyFrame to the components this way, it provides these components control over MyFrame which they should never have.

java.net.URL resource = getClass().getResource("/resources/siegel.jpg");
try {
    image = ImageIO.read(resource);
} catch (IOException e) {
    e.printStackTrace();
}

is a bad idea. The class should be throwing the exception to those using it, so that they know something has gone wrong. Doing it this way not only consumes the error in a way which is difficult to trace, but also sets you up for a NullPointerException when you call g.drawImage(image, 150+x, 150+x, 150, 150, null)

Don't override paint

public void paint(Graphics g) {
    super.paint(g);       
    g.drawImage(image, 150+x, 150+x, 150, 150, null);
}

prefer paintComponent instead. paint is actually a very complex method. See Painting in AWT and Swing and Performing Custom Painting for more details

public static int x=0; is a bad idea for a three reasons:

  1. static is not your friend. What happens when you have more than one instance of ButtomPanel? Generally speaking, when you use static in this way, it's a red flag telling you that your design is wrong.
  2. public is providing uncontrolled access to the property. This is generally discouraged and you could be preferring to use setters and getters to interact with the property.
  3. JPanel already has a x property, which could make it confusing (ie if if someone used getX instead of x). Better to rename it to something like imageX of imageXOffset.

Runnable example...

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public final class Main {
    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    JFrame frame = new JFrame();
                    frame.add(new RightPanel());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                } catch (IOException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
    }

    public class RightPanel extends JPanel implements ActionListener {
        JButton buttono;
        JButton buttonu;
        ButtomPanel s;

        public RightPanel() throws IOException {
            super();
            s = new ButtomPanel();
            setBackground(Color.green);
            setLayout(new BorderLayout());

            buttono = new JButton("up");
            buttonu = new JButton("down");
            buttono.addActionListener(this);
            buttonu.addActionListener(this);
            add(buttono, BorderLayout.NORTH);
            add(buttonu, BorderLayout.SOUTH);

            add(s);

            setVisible(true);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            if (e.getSource() == buttono) {
                System.out.println("Up");
                s.addToImageXOffset(10);
            }
        }
    }

    public class ButtomPanel extends JPanel {
        private BufferedImage image;
        private int imageXOffset = 0;

        public ButtomPanel() throws IOException {
            super();
            setBackground(Color.blue);
            image = ImageIO.read(getClass().getResource("/images/Heart.png"));
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(400, 400);
        }

        public void addToImageXOffset(int delta) {
            setImageXOffset(getImageXOffset() + delta);
        }

        public void setImageXOffset(int imageXOffset) {
            this.imageXOffset = imageXOffset;
            repaint();
        }

        public int getImageXOffset() {
            return imageXOffset;
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g); //To change body of generated methods, choose Tools | Templates.
            g.drawImage(image, 150 + imageXOffset, 150 + imageXOffset, this);
        }

    }
}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366