JFrame.dispose(); not closing the frame











up vote
1
down vote

favorite












so i'm trying to make it where if these two shapes touch each other the window closes. Here is the first part



public class Mayflower {

JFrame f = new JFrame();

public static void main(String args) {

Mayflower bob = new Mayflower();
bob.Start();

}

private void Start(int clothes, int food, int repair, int money) {
int complete = 0;
Mayflower bob = new Mayflower();
//JOptionPane.showMessageDialog(null, "Your equipment:nClothes - " + clothes + "nFood - " + food + "nrepair equipment - " + repair + "nMoney left - $" + money);
bob.epic(complete);
}

public void epic(int complete) {


if (complete == 0){
Iceberg Tim = new Iceberg();

f.add(Tim);
f.setVisible(true);
f.setSize(600, 600);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setTitle("SAILIN BABEEEEY");
f.setLocation(600, 200);

}

if(complete == 1){
System.out.println("odeyladoeijoo");
f.dispose();
}


}

}


Then it calls to the constructor iceberg where the minigame is, I deleted all the movement input because it wasn't relevant:



package mayflower;


public class Iceberg extends JPanel implements ActionListener, KeyListener {

Timer time = new Timer(5, this);
int x = 260;
int y = 500;
int velx = 0;
int vely = 0;

int hitscany = -4000;
int hitscanvely = -1;


public Iceberg() {

time.start();
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);

}

@Override
public void paintComponent(Graphics g) {

super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;

g.setColor(MyColor1);
g.fillRect(x, y, 40, 60);

g.setColor(Color.GRAY);
g.fillRect(0, hitscany, 650, 0);

if (y == hitscany) {
int complete = 1;
Mayflower bob = new Mayflower();
bob.epic(complete);

}

time.start();

}


So i made it to where The "hitscan" object moves down the screen and when it touches the object the window is supposed to close. When my if statement (for if the y coordinates of the two objects are equal) calls the public void epic its supposed to "activate" the if statement for if complete is == 1 and dispose of the frame but for some reason it doesn't










share|improve this question
























  • Every time you call epic, you create a new instance of JFrame, so you’re not actually talking to the instance which was last created, and been a local variable, I’d be impossible to make it work. You will need to maintain a reference of the frame independent of the epic method
    – MadProgrammer
    Nov 20 at 0:48












  • I tried making the JFrame a global variable instead but got the same result could you possibly elaborate on maintaining a reference independent of the epic method?
    – Max Stephenson
    Nov 20 at 1:20










  • For better help sooner, edit to add a Minimal, Complete, and Verifiable example or Short, Self Contained, Correct Example.
    – Andrew Thompson
    Nov 20 at 1:39










  • @MaxStephenson Without more context, it's going to be impossible to suggest an "actual" fix to the problem. Since you're also creating a new instance Mayflower, you have a double issue
    – MadProgrammer
    Nov 20 at 1:51










  • I updated my code, if its still too vague don't worry about it I will just ask my teacher about it after thanksgiving break.
    – Max Stephenson
    Nov 20 at 2:20















up vote
1
down vote

favorite












so i'm trying to make it where if these two shapes touch each other the window closes. Here is the first part



public class Mayflower {

JFrame f = new JFrame();

public static void main(String args) {

Mayflower bob = new Mayflower();
bob.Start();

}

private void Start(int clothes, int food, int repair, int money) {
int complete = 0;
Mayflower bob = new Mayflower();
//JOptionPane.showMessageDialog(null, "Your equipment:nClothes - " + clothes + "nFood - " + food + "nrepair equipment - " + repair + "nMoney left - $" + money);
bob.epic(complete);
}

public void epic(int complete) {


if (complete == 0){
Iceberg Tim = new Iceberg();

f.add(Tim);
f.setVisible(true);
f.setSize(600, 600);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setTitle("SAILIN BABEEEEY");
f.setLocation(600, 200);

}

if(complete == 1){
System.out.println("odeyladoeijoo");
f.dispose();
}


}

}


Then it calls to the constructor iceberg where the minigame is, I deleted all the movement input because it wasn't relevant:



package mayflower;


public class Iceberg extends JPanel implements ActionListener, KeyListener {

Timer time = new Timer(5, this);
int x = 260;
int y = 500;
int velx = 0;
int vely = 0;

int hitscany = -4000;
int hitscanvely = -1;


public Iceberg() {

time.start();
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);

}

@Override
public void paintComponent(Graphics g) {

super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;

g.setColor(MyColor1);
g.fillRect(x, y, 40, 60);

g.setColor(Color.GRAY);
g.fillRect(0, hitscany, 650, 0);

if (y == hitscany) {
int complete = 1;
Mayflower bob = new Mayflower();
bob.epic(complete);

}

time.start();

}


So i made it to where The "hitscan" object moves down the screen and when it touches the object the window is supposed to close. When my if statement (for if the y coordinates of the two objects are equal) calls the public void epic its supposed to "activate" the if statement for if complete is == 1 and dispose of the frame but for some reason it doesn't










share|improve this question
























  • Every time you call epic, you create a new instance of JFrame, so you’re not actually talking to the instance which was last created, and been a local variable, I’d be impossible to make it work. You will need to maintain a reference of the frame independent of the epic method
    – MadProgrammer
    Nov 20 at 0:48












  • I tried making the JFrame a global variable instead but got the same result could you possibly elaborate on maintaining a reference independent of the epic method?
    – Max Stephenson
    Nov 20 at 1:20










  • For better help sooner, edit to add a Minimal, Complete, and Verifiable example or Short, Self Contained, Correct Example.
    – Andrew Thompson
    Nov 20 at 1:39










  • @MaxStephenson Without more context, it's going to be impossible to suggest an "actual" fix to the problem. Since you're also creating a new instance Mayflower, you have a double issue
    – MadProgrammer
    Nov 20 at 1:51










  • I updated my code, if its still too vague don't worry about it I will just ask my teacher about it after thanksgiving break.
    – Max Stephenson
    Nov 20 at 2:20













up vote
1
down vote

favorite









up vote
1
down vote

favorite











so i'm trying to make it where if these two shapes touch each other the window closes. Here is the first part



public class Mayflower {

JFrame f = new JFrame();

public static void main(String args) {

Mayflower bob = new Mayflower();
bob.Start();

}

private void Start(int clothes, int food, int repair, int money) {
int complete = 0;
Mayflower bob = new Mayflower();
//JOptionPane.showMessageDialog(null, "Your equipment:nClothes - " + clothes + "nFood - " + food + "nrepair equipment - " + repair + "nMoney left - $" + money);
bob.epic(complete);
}

public void epic(int complete) {


if (complete == 0){
Iceberg Tim = new Iceberg();

f.add(Tim);
f.setVisible(true);
f.setSize(600, 600);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setTitle("SAILIN BABEEEEY");
f.setLocation(600, 200);

}

if(complete == 1){
System.out.println("odeyladoeijoo");
f.dispose();
}


}

}


Then it calls to the constructor iceberg where the minigame is, I deleted all the movement input because it wasn't relevant:



package mayflower;


public class Iceberg extends JPanel implements ActionListener, KeyListener {

Timer time = new Timer(5, this);
int x = 260;
int y = 500;
int velx = 0;
int vely = 0;

int hitscany = -4000;
int hitscanvely = -1;


public Iceberg() {

time.start();
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);

}

@Override
public void paintComponent(Graphics g) {

super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;

g.setColor(MyColor1);
g.fillRect(x, y, 40, 60);

g.setColor(Color.GRAY);
g.fillRect(0, hitscany, 650, 0);

if (y == hitscany) {
int complete = 1;
Mayflower bob = new Mayflower();
bob.epic(complete);

}

time.start();

}


So i made it to where The "hitscan" object moves down the screen and when it touches the object the window is supposed to close. When my if statement (for if the y coordinates of the two objects are equal) calls the public void epic its supposed to "activate" the if statement for if complete is == 1 and dispose of the frame but for some reason it doesn't










share|improve this question















so i'm trying to make it where if these two shapes touch each other the window closes. Here is the first part



public class Mayflower {

JFrame f = new JFrame();

public static void main(String args) {

Mayflower bob = new Mayflower();
bob.Start();

}

private void Start(int clothes, int food, int repair, int money) {
int complete = 0;
Mayflower bob = new Mayflower();
//JOptionPane.showMessageDialog(null, "Your equipment:nClothes - " + clothes + "nFood - " + food + "nrepair equipment - " + repair + "nMoney left - $" + money);
bob.epic(complete);
}

public void epic(int complete) {


if (complete == 0){
Iceberg Tim = new Iceberg();

f.add(Tim);
f.setVisible(true);
f.setSize(600, 600);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setTitle("SAILIN BABEEEEY");
f.setLocation(600, 200);

}

if(complete == 1){
System.out.println("odeyladoeijoo");
f.dispose();
}


}

}


Then it calls to the constructor iceberg where the minigame is, I deleted all the movement input because it wasn't relevant:



package mayflower;


public class Iceberg extends JPanel implements ActionListener, KeyListener {

Timer time = new Timer(5, this);
int x = 260;
int y = 500;
int velx = 0;
int vely = 0;

int hitscany = -4000;
int hitscanvely = -1;


public Iceberg() {

time.start();
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);

}

@Override
public void paintComponent(Graphics g) {

super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;

g.setColor(MyColor1);
g.fillRect(x, y, 40, 60);

g.setColor(Color.GRAY);
g.fillRect(0, hitscany, 650, 0);

if (y == hitscany) {
int complete = 1;
Mayflower bob = new Mayflower();
bob.epic(complete);

}

time.start();

}


So i made it to where The "hitscan" object moves down the screen and when it touches the object the window is supposed to close. When my if statement (for if the y coordinates of the two objects are equal) calls the public void epic its supposed to "activate" the if statement for if complete is == 1 and dispose of the frame but for some reason it doesn't







java swing jframe dispose






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 20 at 2:18

























asked Nov 20 at 0:14









Max Stephenson

83




83












  • Every time you call epic, you create a new instance of JFrame, so you’re not actually talking to the instance which was last created, and been a local variable, I’d be impossible to make it work. You will need to maintain a reference of the frame independent of the epic method
    – MadProgrammer
    Nov 20 at 0:48












  • I tried making the JFrame a global variable instead but got the same result could you possibly elaborate on maintaining a reference independent of the epic method?
    – Max Stephenson
    Nov 20 at 1:20










  • For better help sooner, edit to add a Minimal, Complete, and Verifiable example or Short, Self Contained, Correct Example.
    – Andrew Thompson
    Nov 20 at 1:39










  • @MaxStephenson Without more context, it's going to be impossible to suggest an "actual" fix to the problem. Since you're also creating a new instance Mayflower, you have a double issue
    – MadProgrammer
    Nov 20 at 1:51










  • I updated my code, if its still too vague don't worry about it I will just ask my teacher about it after thanksgiving break.
    – Max Stephenson
    Nov 20 at 2:20


















  • Every time you call epic, you create a new instance of JFrame, so you’re not actually talking to the instance which was last created, and been a local variable, I’d be impossible to make it work. You will need to maintain a reference of the frame independent of the epic method
    – MadProgrammer
    Nov 20 at 0:48












  • I tried making the JFrame a global variable instead but got the same result could you possibly elaborate on maintaining a reference independent of the epic method?
    – Max Stephenson
    Nov 20 at 1:20










  • For better help sooner, edit to add a Minimal, Complete, and Verifiable example or Short, Self Contained, Correct Example.
    – Andrew Thompson
    Nov 20 at 1:39










  • @MaxStephenson Without more context, it's going to be impossible to suggest an "actual" fix to the problem. Since you're also creating a new instance Mayflower, you have a double issue
    – MadProgrammer
    Nov 20 at 1:51










  • I updated my code, if its still too vague don't worry about it I will just ask my teacher about it after thanksgiving break.
    – Max Stephenson
    Nov 20 at 2:20
















Every time you call epic, you create a new instance of JFrame, so you’re not actually talking to the instance which was last created, and been a local variable, I’d be impossible to make it work. You will need to maintain a reference of the frame independent of the epic method
– MadProgrammer
Nov 20 at 0:48






Every time you call epic, you create a new instance of JFrame, so you’re not actually talking to the instance which was last created, and been a local variable, I’d be impossible to make it work. You will need to maintain a reference of the frame independent of the epic method
– MadProgrammer
Nov 20 at 0:48














I tried making the JFrame a global variable instead but got the same result could you possibly elaborate on maintaining a reference independent of the epic method?
– Max Stephenson
Nov 20 at 1:20




I tried making the JFrame a global variable instead but got the same result could you possibly elaborate on maintaining a reference independent of the epic method?
– Max Stephenson
Nov 20 at 1:20












For better help sooner, edit to add a Minimal, Complete, and Verifiable example or Short, Self Contained, Correct Example.
– Andrew Thompson
Nov 20 at 1:39




For better help sooner, edit to add a Minimal, Complete, and Verifiable example or Short, Self Contained, Correct Example.
– Andrew Thompson
Nov 20 at 1:39












@MaxStephenson Without more context, it's going to be impossible to suggest an "actual" fix to the problem. Since you're also creating a new instance Mayflower, you have a double issue
– MadProgrammer
Nov 20 at 1:51




@MaxStephenson Without more context, it's going to be impossible to suggest an "actual" fix to the problem. Since you're also creating a new instance Mayflower, you have a double issue
– MadProgrammer
Nov 20 at 1:51












I updated my code, if its still too vague don't worry about it I will just ask my teacher about it after thanksgiving break.
– Max Stephenson
Nov 20 at 2:20




I updated my code, if its still too vague don't worry about it I will just ask my teacher about it after thanksgiving break.
– Max Stephenson
Nov 20 at 2:20












2 Answers
2






active

oldest

votes

















up vote
0
down vote



accepted










So, I assume that, this (previously, now removed) code goes some where in your Iceberg key handler code...



if ((((x - icex)) >= -40 && ((x - icex) - 180) <= -130) && (((y - icey)) >= -60 && ((y - icey) - 180) <= -130)) {
int complete = 1;
Mayflower bob = new Mayflower();
bob.epic(complete);
}


This highlights a number of issues. First, you are creating another instance of Mayflower, which is creating another instance of JFrame, which is what's getting disposed, not the original frame.



Iceberg really has no need to interact with Mayflower, it's beyond it's realm of responsibility. Instead, Iceberg "should" be generating event notifications to interested parties about its change in state.



For that, we need an observer pattern!



Let's start with a simple interface which describes all the notifications Iceberg is willing to make...



public interface GameListener {
public void completed(Iceberg berg);
}


Next, we need some way to manage these listeners in Iceberg...



public class Iceberg extends JPanel implements ActionListener, KeyListener {

private List<GameListener> listeners = new ArrayList<>(25);


public void addGameListener(GameListener listener) {
listeners.add(listener);
}

public void removeGameListener(GameListener listener) {
listeners.remove(listener);
}


And finally, some way to generate the notifications...



public class Iceberg extends JPanel implements ActionListener, KeyListener {
//...
protected void fireCompleted() {
for (GameListener listener : listeners) {
listener.completed(this);
}
}


Now, when you have a "completed" state, you can notify the interested parties...



if ((((x - icex)) >= -40 && ((x - icex) - 180) <= -130) && (((y - icey)) >= -60 && ((y - icey) - 180) <= -130)) {
fireCompleted();
}


Now, in your start method, you simply need to create an instance of Iceberg, register a GameListener and get it all started...



private void Start(int clothes, int food, int repair, int money) {
Iceberg Tim = new Iceberg();
Tim.addGameListener(new GameListener() {
@Override
public void completed(Iceberg berg) {
f.dispose();
}
});

f.add(Tim);
f.setVisible(true);
f.setSize(600, 600);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setTitle("SAILIN BABEEEEY");
f.setLocation(600, 200);
}


Observations...



Okay, there is plenty about your code sample to be worried about, but let's start with...



@Override
public void paintComponent(Graphics g) {

super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;

g.setColor(Color.RED);
g.fillRect(x, y, 40, 60);

g.setColor(Color.GRAY);
g.fillRect(0, hitscany, 650, 0);

if (y == hitscany) {
int complete = 1;
Mayflower bob = new Mayflower();
bob.epic(complete);

}

time.start();

}




  • paintComponent should never be public, no-one should ever be calling it directly.

  • You declare but never use g2


This...



if (y == hitscany) {
int complete = 1;
Mayflower bob = new Mayflower();
bob.epic(complete);

}


is a bad idea on a number of levels. Paint should paint the current state of the component, nothing else, it should not be making decisions about the state of the component. This belongs in your main loop



And...



time.start();


I can't begin to tell you how horrible this is. paintComponent will be called often (if you're performing animation), meaning you are continuously reseting the Timer. The Timer's state should never be modified inside paintComponent. Instead, it should control through other means, like the constructor or start/stop methods



KeyListener is a poor choice now days. It suffers from a number of well known and documented short comings. A better, all round solution, is to use the Key Bindings API which has been designed to help solve these issues in a reliable and robust way






share|improve this answer























  • holy crap thanks for taking the time out of your day dude.
    – Max Stephenson
    Nov 21 at 3:25










  • 👍.............
    – MadProgrammer
    Nov 21 at 3:36


















up vote
-1
down vote













You could use



f.setVisible(false)



This just hides the window, and f.dispose() deletes the actual object.



If you want it to act like you clicked the X button, then use this:



f.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));


(got from How to programmatically close a JFrame)



(f being your JFrame)






share|improve this answer





















    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53384448%2fjframe-dispose-not-closing-the-frame%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    0
    down vote



    accepted










    So, I assume that, this (previously, now removed) code goes some where in your Iceberg key handler code...



    if ((((x - icex)) >= -40 && ((x - icex) - 180) <= -130) && (((y - icey)) >= -60 && ((y - icey) - 180) <= -130)) {
    int complete = 1;
    Mayflower bob = new Mayflower();
    bob.epic(complete);
    }


    This highlights a number of issues. First, you are creating another instance of Mayflower, which is creating another instance of JFrame, which is what's getting disposed, not the original frame.



    Iceberg really has no need to interact with Mayflower, it's beyond it's realm of responsibility. Instead, Iceberg "should" be generating event notifications to interested parties about its change in state.



    For that, we need an observer pattern!



    Let's start with a simple interface which describes all the notifications Iceberg is willing to make...



    public interface GameListener {
    public void completed(Iceberg berg);
    }


    Next, we need some way to manage these listeners in Iceberg...



    public class Iceberg extends JPanel implements ActionListener, KeyListener {

    private List<GameListener> listeners = new ArrayList<>(25);


    public void addGameListener(GameListener listener) {
    listeners.add(listener);
    }

    public void removeGameListener(GameListener listener) {
    listeners.remove(listener);
    }


    And finally, some way to generate the notifications...



    public class Iceberg extends JPanel implements ActionListener, KeyListener {
    //...
    protected void fireCompleted() {
    for (GameListener listener : listeners) {
    listener.completed(this);
    }
    }


    Now, when you have a "completed" state, you can notify the interested parties...



    if ((((x - icex)) >= -40 && ((x - icex) - 180) <= -130) && (((y - icey)) >= -60 && ((y - icey) - 180) <= -130)) {
    fireCompleted();
    }


    Now, in your start method, you simply need to create an instance of Iceberg, register a GameListener and get it all started...



    private void Start(int clothes, int food, int repair, int money) {
    Iceberg Tim = new Iceberg();
    Tim.addGameListener(new GameListener() {
    @Override
    public void completed(Iceberg berg) {
    f.dispose();
    }
    });

    f.add(Tim);
    f.setVisible(true);
    f.setSize(600, 600);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.setTitle("SAILIN BABEEEEY");
    f.setLocation(600, 200);
    }


    Observations...



    Okay, there is plenty about your code sample to be worried about, but let's start with...



    @Override
    public void paintComponent(Graphics g) {

    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D) g;

    g.setColor(Color.RED);
    g.fillRect(x, y, 40, 60);

    g.setColor(Color.GRAY);
    g.fillRect(0, hitscany, 650, 0);

    if (y == hitscany) {
    int complete = 1;
    Mayflower bob = new Mayflower();
    bob.epic(complete);

    }

    time.start();

    }




    • paintComponent should never be public, no-one should ever be calling it directly.

    • You declare but never use g2


    This...



    if (y == hitscany) {
    int complete = 1;
    Mayflower bob = new Mayflower();
    bob.epic(complete);

    }


    is a bad idea on a number of levels. Paint should paint the current state of the component, nothing else, it should not be making decisions about the state of the component. This belongs in your main loop



    And...



    time.start();


    I can't begin to tell you how horrible this is. paintComponent will be called often (if you're performing animation), meaning you are continuously reseting the Timer. The Timer's state should never be modified inside paintComponent. Instead, it should control through other means, like the constructor or start/stop methods



    KeyListener is a poor choice now days. It suffers from a number of well known and documented short comings. A better, all round solution, is to use the Key Bindings API which has been designed to help solve these issues in a reliable and robust way






    share|improve this answer























    • holy crap thanks for taking the time out of your day dude.
      – Max Stephenson
      Nov 21 at 3:25










    • 👍.............
      – MadProgrammer
      Nov 21 at 3:36















    up vote
    0
    down vote



    accepted










    So, I assume that, this (previously, now removed) code goes some where in your Iceberg key handler code...



    if ((((x - icex)) >= -40 && ((x - icex) - 180) <= -130) && (((y - icey)) >= -60 && ((y - icey) - 180) <= -130)) {
    int complete = 1;
    Mayflower bob = new Mayflower();
    bob.epic(complete);
    }


    This highlights a number of issues. First, you are creating another instance of Mayflower, which is creating another instance of JFrame, which is what's getting disposed, not the original frame.



    Iceberg really has no need to interact with Mayflower, it's beyond it's realm of responsibility. Instead, Iceberg "should" be generating event notifications to interested parties about its change in state.



    For that, we need an observer pattern!



    Let's start with a simple interface which describes all the notifications Iceberg is willing to make...



    public interface GameListener {
    public void completed(Iceberg berg);
    }


    Next, we need some way to manage these listeners in Iceberg...



    public class Iceberg extends JPanel implements ActionListener, KeyListener {

    private List<GameListener> listeners = new ArrayList<>(25);


    public void addGameListener(GameListener listener) {
    listeners.add(listener);
    }

    public void removeGameListener(GameListener listener) {
    listeners.remove(listener);
    }


    And finally, some way to generate the notifications...



    public class Iceberg extends JPanel implements ActionListener, KeyListener {
    //...
    protected void fireCompleted() {
    for (GameListener listener : listeners) {
    listener.completed(this);
    }
    }


    Now, when you have a "completed" state, you can notify the interested parties...



    if ((((x - icex)) >= -40 && ((x - icex) - 180) <= -130) && (((y - icey)) >= -60 && ((y - icey) - 180) <= -130)) {
    fireCompleted();
    }


    Now, in your start method, you simply need to create an instance of Iceberg, register a GameListener and get it all started...



    private void Start(int clothes, int food, int repair, int money) {
    Iceberg Tim = new Iceberg();
    Tim.addGameListener(new GameListener() {
    @Override
    public void completed(Iceberg berg) {
    f.dispose();
    }
    });

    f.add(Tim);
    f.setVisible(true);
    f.setSize(600, 600);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.setTitle("SAILIN BABEEEEY");
    f.setLocation(600, 200);
    }


    Observations...



    Okay, there is plenty about your code sample to be worried about, but let's start with...



    @Override
    public void paintComponent(Graphics g) {

    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D) g;

    g.setColor(Color.RED);
    g.fillRect(x, y, 40, 60);

    g.setColor(Color.GRAY);
    g.fillRect(0, hitscany, 650, 0);

    if (y == hitscany) {
    int complete = 1;
    Mayflower bob = new Mayflower();
    bob.epic(complete);

    }

    time.start();

    }




    • paintComponent should never be public, no-one should ever be calling it directly.

    • You declare but never use g2


    This...



    if (y == hitscany) {
    int complete = 1;
    Mayflower bob = new Mayflower();
    bob.epic(complete);

    }


    is a bad idea on a number of levels. Paint should paint the current state of the component, nothing else, it should not be making decisions about the state of the component. This belongs in your main loop



    And...



    time.start();


    I can't begin to tell you how horrible this is. paintComponent will be called often (if you're performing animation), meaning you are continuously reseting the Timer. The Timer's state should never be modified inside paintComponent. Instead, it should control through other means, like the constructor or start/stop methods



    KeyListener is a poor choice now days. It suffers from a number of well known and documented short comings. A better, all round solution, is to use the Key Bindings API which has been designed to help solve these issues in a reliable and robust way






    share|improve this answer























    • holy crap thanks for taking the time out of your day dude.
      – Max Stephenson
      Nov 21 at 3:25










    • 👍.............
      – MadProgrammer
      Nov 21 at 3:36













    up vote
    0
    down vote



    accepted







    up vote
    0
    down vote



    accepted






    So, I assume that, this (previously, now removed) code goes some where in your Iceberg key handler code...



    if ((((x - icex)) >= -40 && ((x - icex) - 180) <= -130) && (((y - icey)) >= -60 && ((y - icey) - 180) <= -130)) {
    int complete = 1;
    Mayflower bob = new Mayflower();
    bob.epic(complete);
    }


    This highlights a number of issues. First, you are creating another instance of Mayflower, which is creating another instance of JFrame, which is what's getting disposed, not the original frame.



    Iceberg really has no need to interact with Mayflower, it's beyond it's realm of responsibility. Instead, Iceberg "should" be generating event notifications to interested parties about its change in state.



    For that, we need an observer pattern!



    Let's start with a simple interface which describes all the notifications Iceberg is willing to make...



    public interface GameListener {
    public void completed(Iceberg berg);
    }


    Next, we need some way to manage these listeners in Iceberg...



    public class Iceberg extends JPanel implements ActionListener, KeyListener {

    private List<GameListener> listeners = new ArrayList<>(25);


    public void addGameListener(GameListener listener) {
    listeners.add(listener);
    }

    public void removeGameListener(GameListener listener) {
    listeners.remove(listener);
    }


    And finally, some way to generate the notifications...



    public class Iceberg extends JPanel implements ActionListener, KeyListener {
    //...
    protected void fireCompleted() {
    for (GameListener listener : listeners) {
    listener.completed(this);
    }
    }


    Now, when you have a "completed" state, you can notify the interested parties...



    if ((((x - icex)) >= -40 && ((x - icex) - 180) <= -130) && (((y - icey)) >= -60 && ((y - icey) - 180) <= -130)) {
    fireCompleted();
    }


    Now, in your start method, you simply need to create an instance of Iceberg, register a GameListener and get it all started...



    private void Start(int clothes, int food, int repair, int money) {
    Iceberg Tim = new Iceberg();
    Tim.addGameListener(new GameListener() {
    @Override
    public void completed(Iceberg berg) {
    f.dispose();
    }
    });

    f.add(Tim);
    f.setVisible(true);
    f.setSize(600, 600);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.setTitle("SAILIN BABEEEEY");
    f.setLocation(600, 200);
    }


    Observations...



    Okay, there is plenty about your code sample to be worried about, but let's start with...



    @Override
    public void paintComponent(Graphics g) {

    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D) g;

    g.setColor(Color.RED);
    g.fillRect(x, y, 40, 60);

    g.setColor(Color.GRAY);
    g.fillRect(0, hitscany, 650, 0);

    if (y == hitscany) {
    int complete = 1;
    Mayflower bob = new Mayflower();
    bob.epic(complete);

    }

    time.start();

    }




    • paintComponent should never be public, no-one should ever be calling it directly.

    • You declare but never use g2


    This...



    if (y == hitscany) {
    int complete = 1;
    Mayflower bob = new Mayflower();
    bob.epic(complete);

    }


    is a bad idea on a number of levels. Paint should paint the current state of the component, nothing else, it should not be making decisions about the state of the component. This belongs in your main loop



    And...



    time.start();


    I can't begin to tell you how horrible this is. paintComponent will be called often (if you're performing animation), meaning you are continuously reseting the Timer. The Timer's state should never be modified inside paintComponent. Instead, it should control through other means, like the constructor or start/stop methods



    KeyListener is a poor choice now days. It suffers from a number of well known and documented short comings. A better, all round solution, is to use the Key Bindings API which has been designed to help solve these issues in a reliable and robust way






    share|improve this answer














    So, I assume that, this (previously, now removed) code goes some where in your Iceberg key handler code...



    if ((((x - icex)) >= -40 && ((x - icex) - 180) <= -130) && (((y - icey)) >= -60 && ((y - icey) - 180) <= -130)) {
    int complete = 1;
    Mayflower bob = new Mayflower();
    bob.epic(complete);
    }


    This highlights a number of issues. First, you are creating another instance of Mayflower, which is creating another instance of JFrame, which is what's getting disposed, not the original frame.



    Iceberg really has no need to interact with Mayflower, it's beyond it's realm of responsibility. Instead, Iceberg "should" be generating event notifications to interested parties about its change in state.



    For that, we need an observer pattern!



    Let's start with a simple interface which describes all the notifications Iceberg is willing to make...



    public interface GameListener {
    public void completed(Iceberg berg);
    }


    Next, we need some way to manage these listeners in Iceberg...



    public class Iceberg extends JPanel implements ActionListener, KeyListener {

    private List<GameListener> listeners = new ArrayList<>(25);


    public void addGameListener(GameListener listener) {
    listeners.add(listener);
    }

    public void removeGameListener(GameListener listener) {
    listeners.remove(listener);
    }


    And finally, some way to generate the notifications...



    public class Iceberg extends JPanel implements ActionListener, KeyListener {
    //...
    protected void fireCompleted() {
    for (GameListener listener : listeners) {
    listener.completed(this);
    }
    }


    Now, when you have a "completed" state, you can notify the interested parties...



    if ((((x - icex)) >= -40 && ((x - icex) - 180) <= -130) && (((y - icey)) >= -60 && ((y - icey) - 180) <= -130)) {
    fireCompleted();
    }


    Now, in your start method, you simply need to create an instance of Iceberg, register a GameListener and get it all started...



    private void Start(int clothes, int food, int repair, int money) {
    Iceberg Tim = new Iceberg();
    Tim.addGameListener(new GameListener() {
    @Override
    public void completed(Iceberg berg) {
    f.dispose();
    }
    });

    f.add(Tim);
    f.setVisible(true);
    f.setSize(600, 600);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.setTitle("SAILIN BABEEEEY");
    f.setLocation(600, 200);
    }


    Observations...



    Okay, there is plenty about your code sample to be worried about, but let's start with...



    @Override
    public void paintComponent(Graphics g) {

    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D) g;

    g.setColor(Color.RED);
    g.fillRect(x, y, 40, 60);

    g.setColor(Color.GRAY);
    g.fillRect(0, hitscany, 650, 0);

    if (y == hitscany) {
    int complete = 1;
    Mayflower bob = new Mayflower();
    bob.epic(complete);

    }

    time.start();

    }




    • paintComponent should never be public, no-one should ever be calling it directly.

    • You declare but never use g2


    This...



    if (y == hitscany) {
    int complete = 1;
    Mayflower bob = new Mayflower();
    bob.epic(complete);

    }


    is a bad idea on a number of levels. Paint should paint the current state of the component, nothing else, it should not be making decisions about the state of the component. This belongs in your main loop



    And...



    time.start();


    I can't begin to tell you how horrible this is. paintComponent will be called often (if you're performing animation), meaning you are continuously reseting the Timer. The Timer's state should never be modified inside paintComponent. Instead, it should control through other means, like the constructor or start/stop methods



    KeyListener is a poor choice now days. It suffers from a number of well known and documented short comings. A better, all round solution, is to use the Key Bindings API which has been designed to help solve these issues in a reliable and robust way







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 21 at 3:35

























    answered Nov 20 at 21:00









    MadProgrammer

    298k17152264




    298k17152264












    • holy crap thanks for taking the time out of your day dude.
      – Max Stephenson
      Nov 21 at 3:25










    • 👍.............
      – MadProgrammer
      Nov 21 at 3:36


















    • holy crap thanks for taking the time out of your day dude.
      – Max Stephenson
      Nov 21 at 3:25










    • 👍.............
      – MadProgrammer
      Nov 21 at 3:36
















    holy crap thanks for taking the time out of your day dude.
    – Max Stephenson
    Nov 21 at 3:25




    holy crap thanks for taking the time out of your day dude.
    – Max Stephenson
    Nov 21 at 3:25












    👍.............
    – MadProgrammer
    Nov 21 at 3:36




    👍.............
    – MadProgrammer
    Nov 21 at 3:36












    up vote
    -1
    down vote













    You could use



    f.setVisible(false)



    This just hides the window, and f.dispose() deletes the actual object.



    If you want it to act like you clicked the X button, then use this:



    f.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));


    (got from How to programmatically close a JFrame)



    (f being your JFrame)






    share|improve this answer

























      up vote
      -1
      down vote













      You could use



      f.setVisible(false)



      This just hides the window, and f.dispose() deletes the actual object.



      If you want it to act like you clicked the X button, then use this:



      f.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));


      (got from How to programmatically close a JFrame)



      (f being your JFrame)






      share|improve this answer























        up vote
        -1
        down vote










        up vote
        -1
        down vote









        You could use



        f.setVisible(false)



        This just hides the window, and f.dispose() deletes the actual object.



        If you want it to act like you clicked the X button, then use this:



        f.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));


        (got from How to programmatically close a JFrame)



        (f being your JFrame)






        share|improve this answer












        You could use



        f.setVisible(false)



        This just hides the window, and f.dispose() deletes the actual object.



        If you want it to act like you clicked the X button, then use this:



        f.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));


        (got from How to programmatically close a JFrame)



        (f being your JFrame)







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 20 at 1:31









        oriont

        1177




        1177






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53384448%2fjframe-dispose-not-closing-the-frame%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Costa Masnaga

            Fotorealismo

            Sidney Franklin