Reputation: 47
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();
}
});
}
}
Upvotes: 1
Views: 667
Reputation: 347334
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
Upvotes: 5
Reputation: 285430
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 Event Dispatch Thread). You should use a Swing Timer instead for this functionality.
Upvotes: 4