-1

I am working on a game "loot" element (Swing JComponent), that would disappear if out of frame bounds for a long (I've set 1 sec in example to let you check if faster) time. This option works fine, but...

If I remove one from JFrame, it is not finalized. (Another resource leak!)

Loot is Runnable. I have the following code in the run() method that is used to create a new Thread (new Thread(loot).start();):

class Loot extends JComponent implements Runnable{
static JFrame frame=new JFrame(){
    public void remove(Component c){super.remove(c);revalidate();}
};
int lifetime=100;
public Loot(){
    frame.add(this);
    frame.setVisible(true);
    new Thread(this).start();
}
public void run(){
    while(lifetime>0){
        if(outOfFrameBounds())lifetime--;else lifetime=100;
        //movement processing
        try{Thread.sleep(10);}catch(InterruptedException ex){}
    }
    setVisible(false);
    frame.remove(this);
    System.gc();
    System.runFinalization();
}
public boolean outOfFrameBounds(){
    return true;//check if it's out of bounds
}
public void finalize(){System.out.println("loot removed");}
public static void main(String[]args){
    new Loot();
}}

output (even after System.gc() call):

When the cycle ends, I need to delete the loot. Can the finished anonimous Thread prevent discarding the loot object? Or is the main problem caused by some frame reference that left after removing component from it? Why can not garbage collector destroy loot? And the main question is **"How can I make my programm here to destroy the loot object, call finalize() and, as a consequence, print "loot removed\n".

  • 1
    Welcome to Stack Overflow. Please take the [tour] to learn how Stack Overflow works and read [ask] on how to improve the quality of your question. Then [edit] your question to include your source code as a working [mcve], which can be compiled and tested by others. – Progman Aug 19 '23 at 07:22
  • @Progman, sorry, I've written this question in a hurry. Does it seem more reproducable after a few edits? – Tech of the Absence Aug 19 '23 at 17:42
  • "Reproducable" means that anyone can run the source code and see the problem. Your source code is incomplete to do that. – Progman Aug 19 '23 at 17:49
  • There is nothing to see since nothing is displayed, so not sure what your code is showing or what the problem is. However, when you remove components from the `JFrame`, you might need to call `repaint()` and/or `revalidate()`. See https://stackoverflow.com/questions/1097366/java-swing-revalidate-vs-repaint – Progman Aug 20 '23 at 18:55
  • @Progman, of course there is nothing to see. That is the main problem, as the program should print "loot removed" on finalizing the `loot` object. Thanks for advice, I've tried to call `revalidete()`, it does not help. – Tech of the Absence Aug 21 '23 at 10:07
  • Thread in the constructor, and explicitly starting a thread. Then a static JFrame. I would advise a new class design – Joop Eggen Aug 21 '23 at 10:14
  • There is no static JFrame in real code. I have just added it for easier solution search. What didn't you like in explicit thread starting? – Tech of the Absence Aug 21 '23 at 10:17
  • Okay, a relief. I assume that that same thread is decreasing `lifetime`. Otherwise that could go wrong. Finalize is not necessarily called. – Joop Eggen Aug 21 '23 at 13:36
  • @JoopEggen, what means "Finalize is not necessarily called"? Why? Then how can I ensure that the object is deleted and is no longer using memory? – Tech of the Absence Aug 23 '23 at 07:33
  • Over time objects should be gc'ed. Heap dumps are possible. And then there are holes like calling BufferedImage.getGraphics/create Graphics without destroy. Listeners if course – Joop Eggen Aug 23 '23 at 18:02
  • @JoopEggen, but what if I called `System.gc()` and `System.runFinalization()`? Should not it finalize everything right after them? – Tech of the Absence Aug 25 '23 at 04:53
  • I am not into the internals of finalizations. References could prevent a cleanup. – Joop Eggen Aug 25 '23 at 10:07

0 Answers0