0

I have a class (not public, so you probably do not know the class) which is drawing a picture with picture.draw(g2). With picture.changeToDry() I can change the picture. It works fine, when I call the picture and change it in implemented paintComponent() method. But when I call changeToDry() and after it repaint(), it does not work. It just shows the default picture but does not update it. What do I have to do, so that I can change the picture and update the JPanel in another method? It has to be something with the repaint() because the methods work in paintComponent() but not elsewhere.

EDIT: update() will be called in another class. Plus, as I mentioned in the comments, I cannot give more information for the class, as it is a private, teaching-only class. And obviously it should work. Otherwise my teacher would not give it to us. EDIT 2: I have another class ClimateFrame which is drawing a frame. There I am calling update()

public class ClimatePanel extends JPanel {
    ClimatePicture picture = new ClimatePicture(100, 100);
    
    public void update() {
        picture.changeToDry();
        repaint(); // does not work
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        // picture.changeToDry() would work here
        picture.draw(g2);   
    }
}




public class ClimateFrame extends JFrame {
    
    public ClimateFrame() {
        setTitle("A task");
        setLayout(new BorderLayout());
        add(new ClimatePanel(), BorderLayout.CENTER);
    }
    
    public static void main(String [] args) {
        
        ClimateFrame frame = new ClimateFrame ();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(800, 600);
        frame.setVisible(true);
        ClimatePanel climatePanel = new ClimatePanel();
        climatePanel.update();
        
        
    }
}

KerryKilian
  • 95
  • 11
  • changeToDry() is a method provided by the class. I did not write that method. It just updates the picture to a specific topic. – KerryKilian May 16 '22 at 12:23
  • 2
    Right now we can guess: it *could* be a Swing threading issue, or you *could* be updating the wrong instance, .... but these guesses aren't what the site is about. Rather it is to create questions and answers that help future visitors, which is why a clear and unambiguous question is needed, so that we can create a clear and unambiguous answer. – Hovercraft Full Of Eels May 16 '22 at 12:26
  • What do you expect? The class is provided by my teacher and he does not want to hand it out to others. But as I mentioned, the problem cant be caused by the method changeToDry() because it works fine in paintComponent(). I am asking because I am not sure, how to use repaint() method and I want to know what I am doing wrong with repaint(). If you dou not see any problem related to repaint(), you can say it. But I cannot provide you more information because it is a private, (only for teaching) class which obviously should work, as my teacher provided it – KerryKilian May 16 '22 at 12:28
  • 1
    And your use of `repaint()` is fine -- the source of the problem is (***again***) elsewhere in code that we cannot see. – Hovercraft Full Of Eels May 16 '22 at 12:30
  • @HovercraftFullOfEels it is my own version. I would never write parts of the class to public. I changed the names of it. And thank you for telling me, that repaint() is fine. That is what I wanted to know – KerryKilian May 16 '22 at 12:33
  • 1
    This code isn't showing the problem. Consider showing more. Where do you call update? – DontKnowMuchBut Getting Better May 16 '22 at 12:34

1 Answers1

1

There is your problem:

public class ClimateFrame extends JFrame {
    
    public ClimateFrame() {
        setTitle("A task");
        setLayout(new BorderLayout());
        add(new ClimatePanel(), BorderLayout.CENTER);
    }
    
    public static void main(String [] args) {        
        ClimateFrame frame = new ClimateFrame ();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(800, 600);
        frame.setVisible(true);
        ClimatePanel climatePanel = new ClimatePanel(); // ****** here ****
        climatePanel.update();
    }
}

You're creating a new ClimatePanel instance at the indicated line and changing its state rather than the state of the separate originally created and displayed one. This aligns with one of my guesses made in comments above:

Right now we can guess:

  • it could be a Swing threading issue,
  • or you could be updating the wrong instance (THIS ONE)

The solution: don't create a new ClimatePanel instance but instead create a ClimatePanel field, give it a single ClimatePanel reference, add it to the GUI, and later update its state, now the state of the displayed instance.

e.g.,

public class ClimateFrame extends JFrame {
    private ClimatePanel climatePanel = new ClimatePanel(); // ADD
    
    public ClimateFrame() {
        setTitle("A task");
        setLayout(new BorderLayout());
        // add(new ClimatePanel(), BorderLayout.CENTER); // REMOVE
        add(climatePanel, BorderLayout.CENTER); // ADD    
    }
    
    // allow visibility of the climate panel method
    public void updateClimatePanel() {
        climatePanel.update();
    }
    
    public static void main(String [] args) {        
        ClimateFrame frame = new ClimateFrame ();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(800, 600);
        frame.setVisible(true);
        // ClimatePanel climatePanel = new ClimatePanel(); // REMOVE
        frame.updateClimatePanel();
    }
}
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373