简体   繁体   中英

JFrame will not close when “X” button is clicked

The JFrame will not shut down when the default "X" button is clicked. I think this problem has something to do with the main thread not being read, but I don't understand the intricacies of swing or honestly, threads in general. "Window" is an extension of JFrame, "Boxy" drives the program. Program is only in initial stages. Also, I'd like to know how to get the main thread run on every loop-over. Couldn't find anything about this in other questions.

public class Window extends JFrame implements KeyListener{
    private static final long serialVersionUID = 1L;
JPanel panel;
public Window(){
    super("FileTyper");
    super.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    super.setSize(200,100);
    super.setResizable(false);
    panel = new JPanel();
    super.getContentPane().add(panel);
    super.setFocusable(true);
    addKeyListener(this);

    super.setVisible(true);
}
public void update(){

}
public void render(Graphics2D g){

}
@Override
public void keyPressed(KeyEvent e) {

}
@Override
public void keyReleased(KeyEvent e) {
    switch(e.getKeyCode()) {
    case KeyEvent.VK_F9:
        break;
    case KeyEvent.VK_F10:
        break;
    }

}
@Override
public void keyTyped(KeyEvent arg0) {

}

}

public class Boxy {
public Window window;

public static void main (String args[]){
    start();
}
public Boxy(){
    init();
    boolean forever = true;
    while(forever){
        update();
        render();
        delay();
    }
}
private void init(){
    window = new Window();
}
private void update(){
    window.update();
}
private void render(){
    Graphics2D g2 = (Graphics2D) window.getContentPane().getGraphics();
    window.render(g2);
    g2.fillRect(0, 0, 100, 100);
}
private void delay(){
    try {Thread.sleep(20);} catch (InterruptedException ex) {System.out.println("ERROR: Delay compromised");}
}
public static void start(){
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            Boxy box = new Boxy();
        }
    });
}
}

Your program's "game" loop is incorrect:

while(forever){
    update();
    render();
    delay();
}

Rather than looping the program, it freezes it by tying up the Swing event thread or EDT (for vent ispatch hread). vent ispatch hread)来冻结它。 You should use a Swing Timer instead for this functionality.

I would suggest that you are blocking the Event Dispatching Thread with

while(forever){
    update();
    render();
    delay();
}

This is preventing the Event Queue from processing the event that would close the window.

Start by taking a look at Concurrency in Swing . I would suggest you might like to take a look at something like javax.swing.Timer to start with, but if you want more control of the frame rate, you're going to need to use some kind of Thread . Remember though, Swing expects all updates to be executed from within the context of the Event Dispatching Thread.

Custom painting in Swing is not done by using something like...

Graphics2D g2 = (Graphics2D) window.getContentPane().getGraphics();

The Graphics context is short lived, anything your paint to it (using this method) will be destroyed on the next paint cycle.

Instead, you should use something like a JPanel as the bases for your painting and override it's paintComponent method and render the state from within it, when ever it is called.

You would then simply need to call repaint when you want to update the component.

Take a look at Performing Custom Painting for more details.

I would also recommend that you take a look at How to use Key Bindings as an aletrnative to KeyListener

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM