• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*******************************************************************************
2  * Copyright 2011 See AUTHORS file.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  ******************************************************************************/
16 
17 package com.badlogic.gdx.backends.lwjgl;
18 
19 import java.awt.Dimension;
20 import java.awt.EventQueue;
21 import java.awt.Point;
22 
23 import javax.swing.JFrame;
24 
25 import com.badlogic.gdx.ApplicationListener;
26 
27 /** Wraps an {@link LwjglCanvas} in a resizable {@link JFrame}. */
28 public class LwjglFrame extends JFrame {
29 	LwjglCanvas lwjglCanvas;
30 	private Thread shutdownHook;
31 
LwjglFrame(ApplicationListener listener, String title, int width, int height)32 	public LwjglFrame (ApplicationListener listener, String title, int width, int height) {
33 		super(title);
34 		LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();
35 		config.title = title;
36 		config.width = width;
37 		config.height = height;
38 		construct(listener, config);
39 	}
40 
LwjglFrame(ApplicationListener listener, LwjglApplicationConfiguration config)41 	public LwjglFrame (ApplicationListener listener, LwjglApplicationConfiguration config) {
42 		super(config.title);
43 		construct(listener, config);
44 	}
45 
construct(ApplicationListener listener, LwjglApplicationConfiguration config)46 	private void construct (ApplicationListener listener, LwjglApplicationConfiguration config) {
47 		lwjglCanvas = new LwjglCanvas(listener, config) {
48 			protected void stopped () {
49 				LwjglFrame.this.dispose();
50 			}
51 
52 			protected void setTitle (String title) {
53 				LwjglFrame.this.setTitle(title);
54 			}
55 
56 			protected void setDisplayMode (int width, int height) {
57 				LwjglFrame.this.getContentPane().setPreferredSize(new Dimension(width, height));
58 				LwjglFrame.this.getContentPane().invalidate();
59 				LwjglFrame.this.pack();
60 				LwjglFrame.this.setLocationRelativeTo(null);
61 				updateSize(width, height);
62 			}
63 
64 			protected void resize (int width, int height) {
65 				updateSize(width, height);
66 			}
67 
68 			protected void start () {
69 				LwjglFrame.this.start();
70 			}
71 
72 			protected void exception (Throwable t) {
73 				LwjglFrame.this.exception(t);
74 			}
75 
76 			protected int getFrameRate () {
77 				int frameRate = LwjglFrame.this.getFrameRate();
78 				return frameRate == 0 ? super.getFrameRate() : frameRate;
79 			}
80 		};
81 
82 		setHaltOnShutdown(true);
83 
84 		setDefaultCloseOperation(EXIT_ON_CLOSE);
85 		getContentPane().setPreferredSize(new Dimension(config.width, config.height));
86 
87 		initialize();
88 		pack();
89 		Point location = getLocation();
90 		if (location.x == 0 && location.y == 0) setLocationRelativeTo(null);
91 		lwjglCanvas.getCanvas().setSize(getSize());
92 
93 		// Finish with invokeLater so any LwjglFrame super constructor has a chance to initialize.
94 		EventQueue.invokeLater(new Runnable() {
95 			public void run () {
96 				addCanvas();
97 				setVisible(true);
98 				lwjglCanvas.getCanvas().requestFocus();
99 			}
100 		});
101 	}
102 
103 	/** When true, <code>Runtime.getRuntime().halt(0);</code> is used when the JVM shuts down. This prevents Swing shutdown hooks
104 	 * from causing a deadlock and keeping the JVM alive indefinitely. Default is true. */
setHaltOnShutdown(boolean halt)105 	public void setHaltOnShutdown (boolean halt) {
106 		if (halt) {
107 			if (shutdownHook != null) return;
108 			shutdownHook = new Thread() {
109 				public void run () {
110 					Runtime.getRuntime().halt(0); // Because fuck you, deadlock causing Swing shutdown hooks.
111 				}
112 			};
113 			Runtime.getRuntime().addShutdownHook(shutdownHook);
114 		} else if (shutdownHook != null) {
115 			Runtime.getRuntime().removeShutdownHook(shutdownHook);
116 			shutdownHook = null;
117 		}
118 	}
119 
getFrameRate()120 	protected int getFrameRate () {
121 		return 0;
122 	}
123 
exception(Throwable ex)124 	protected void exception (Throwable ex) {
125 		ex.printStackTrace();
126 		lwjglCanvas.stop();
127 	}
128 
129 	/** Called before the JFrame is made displayable. */
initialize()130 	protected void initialize () {
131 	}
132 
133 	/** Adds the canvas to the content pane. This triggers addNotify and starts the canvas' game loop. */
addCanvas()134 	protected void addCanvas () {
135 		getContentPane().add(lwjglCanvas.getCanvas());
136 	}
137 
138 	/** Called after {@link ApplicationListener} create and resize, but before the game loop iteration. */
start()139 	protected void start () {
140 	}
141 
142 	/** Called when the canvas size changes. */
updateSize(int width, int height)143 	public void updateSize (int width, int height) {
144 	}
145 
getLwjglCanvas()146 	public LwjglCanvas getLwjglCanvas () {
147 		return lwjglCanvas;
148 	}
149 }
150