/******************************************************************************* | |
* Copyright 2011 See AUTHORS file. | |
* | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
******************************************************************************/ | |
package com.badlogic.gdx.backends.lwjgl; | |
import java.awt.Dimension; | |
import java.awt.EventQueue; | |
import java.awt.Point; | |
import javax.swing.JFrame; | |
import com.badlogic.gdx.ApplicationListener; | |
/** Wraps an {@link LwjglCanvas} in a resizable {@link JFrame}. */ | |
public class LwjglFrame extends JFrame { | |
LwjglCanvas lwjglCanvas; | |
private Thread shutdownHook; | |
public LwjglFrame (ApplicationListener listener, String title, int width, int height) { | |
super(title); | |
LwjglApplicationConfiguration config = new LwjglApplicationConfiguration(); | |
config.title = title; | |
config.width = width; | |
config.height = height; | |
construct(listener, config); | |
} | |
public LwjglFrame (ApplicationListener listener, LwjglApplicationConfiguration config) { | |
super(config.title); | |
construct(listener, config); | |
} | |
private void construct (ApplicationListener listener, LwjglApplicationConfiguration config) { | |
lwjglCanvas = new LwjglCanvas(listener, config) { | |
protected void stopped () { | |
LwjglFrame.this.dispose(); | |
} | |
protected void setTitle (String title) { | |
LwjglFrame.this.setTitle(title); | |
} | |
protected void setDisplayMode (int width, int height) { | |
LwjglFrame.this.getContentPane().setPreferredSize(new Dimension(width, height)); | |
LwjglFrame.this.getContentPane().invalidate(); | |
LwjglFrame.this.pack(); | |
LwjglFrame.this.setLocationRelativeTo(null); | |
updateSize(width, height); | |
} | |
protected void resize (int width, int height) { | |
updateSize(width, height); | |
} | |
protected void start () { | |
LwjglFrame.this.start(); | |
} | |
protected void exception (Throwable t) { | |
LwjglFrame.this.exception(t); | |
} | |
protected int getFrameRate () { | |
int frameRate = LwjglFrame.this.getFrameRate(); | |
return frameRate == 0 ? super.getFrameRate() : frameRate; | |
} | |
}; | |
setHaltOnShutdown(true); | |
setDefaultCloseOperation(EXIT_ON_CLOSE); | |
getContentPane().setPreferredSize(new Dimension(config.width, config.height)); | |
initialize(); | |
pack(); | |
Point location = getLocation(); | |
if (location.x == 0 && location.y == 0) setLocationRelativeTo(null); | |
lwjglCanvas.getCanvas().setSize(getSize()); | |
// Finish with invokeLater so any LwjglFrame super constructor has a chance to initialize. | |
EventQueue.invokeLater(new Runnable() { | |
public void run () { | |
addCanvas(); | |
setVisible(true); | |
lwjglCanvas.getCanvas().requestFocus(); | |
} | |
}); | |
} | |
/** When true, <code>Runtime.getRuntime().halt(0);</code> is used when the JVM shuts down. This prevents Swing shutdown hooks | |
* from causing a deadlock and keeping the JVM alive indefinitely. Default is true. */ | |
public void setHaltOnShutdown (boolean halt) { | |
if (halt) { | |
if (shutdownHook != null) return; | |
shutdownHook = new Thread() { | |
public void run () { | |
Runtime.getRuntime().halt(0); // Because fuck you, deadlock causing Swing shutdown hooks. | |
} | |
}; | |
Runtime.getRuntime().addShutdownHook(shutdownHook); | |
} else if (shutdownHook != null) { | |
Runtime.getRuntime().removeShutdownHook(shutdownHook); | |
shutdownHook = null; | |
} | |
} | |
protected int getFrameRate () { | |
return 0; | |
} | |
protected void exception (Throwable ex) { | |
ex.printStackTrace(); | |
lwjglCanvas.stop(); | |
} | |
/** Called before the JFrame is made displayable. */ | |
protected void initialize () { | |
} | |
/** Adds the canvas to the content pane. This triggers addNotify and starts the canvas' game loop. */ | |
protected void addCanvas () { | |
getContentPane().add(lwjglCanvas.getCanvas()); | |
} | |
/** Called after {@link ApplicationListener} create and resize, but before the game loop iteration. */ | |
protected void start () { | |
} | |
/** Called when the canvas size changes. */ | |
public void updateSize (int width, int height) { | |
} | |
public LwjglCanvas getLwjglCanvas () { | |
return lwjglCanvas; | |
} | |
} |