2 * Copyright (c) 2010 The Desert team
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use,
8 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
26 package org
.sourceforge
.desert
;
28 import java
.awt
.BorderLayout
;
29 import java
.awt
.Choice
;
30 import java
.awt
.Component
;
31 import java
.awt
.Label
;
32 import java
.awt
.Panel
;
33 import java
.awt
.event
.ActionEvent
;
34 import java
.awt
.event
.ActionListener
;
35 import java
.awt
.event
.ItemEvent
;
36 import java
.awt
.event
.ItemListener
;
37 import java
.awt
.event
.MouseMotionListener
;
38 import java
.awt
.event
.MouseEvent
;
39 import java
.util
.ResourceBundle
;
40 import java
.util
.logging
.Level
;
41 import java
.util
.logging
.Logger
;
42 import javax
.swing
.Box
;
46 * @author codistmonk (creation 2010-04-15)
48 @SuppressWarnings("serial")
49 public class DesertPanel
extends Panel
{
51 private final Timer timer
;
53 private final DrawingBoard drawingBoard
;
55 private final GCThread gcThread
;
57 public DesertPanel() {
58 super(new BorderLayout());
59 this.timer
= new Timer(FRAMERATE
);
60 this.drawingBoard
= new DrawingBoard();
62 final CursorPositionLabel xyMouse
= new CursorPositionLabel();
63 final FramerateLabel framerateLabel
= new FramerateLabel();
64 final ParticleCountLabel particleCountLabel
= this.new ParticleCountLabel();
66 this.add(this.getDrawingBoard(), BorderLayout
.CENTER
);
68 horizontalBox(framerateLabel
, particleCountLabel
, xyMouse
),
69 horizontalBox(new Label("Particle engine: "), this.new ParticleEngineChoice()),
70 horizontalBox(new Label("Particle type: "), this.new ParticleTypeChoice())
71 ), BorderLayout
.SOUTH
);
73 this.getTimer().addActionListener(this.getDrawingBoard());
74 this.getDrawingBoard().addMouseMotionListener(xyMouse
);
75 this.getTimer().addActionListener(framerateLabel
);
76 this.getTimer().addActionListener(particleCountLabel
);
77 this.gcThread
= new GCThread();
78 this.gcThread
.start();
84 * <br>A non-null value
87 public final Timer
getTimer() {
94 * <br>A non-null value
97 public final DrawingBoard
getDrawingBoard() {
98 return this.drawingBoard
;
103 * @author codistmonk (creation 2010-04-17)
105 @SuppressWarnings("serial")
106 private final class ParticleEngineChoice
extends Choice
{
108 public ParticleEngineChoice() {
114 this.addItemListener(this.new ItemHandler());
119 * @author codistmonk (creation 2010-04-17)
121 private final class ItemHandler
implements ItemListener
{
124 public final void itemStateChanged(final ItemEvent event
) {
125 if (event
.getStateChange() == ItemEvent
.SELECTED
) {
127 DesertPanel
.this.getDrawingBoard().setParticleEngine(this.createParticleEngine());
128 } catch (final InstantiationException exception
) {
129 Logger
.getLogger(DesertPanel
.class.getName()).log(Level
.SEVERE
, null, exception
);
130 } catch (final IllegalAccessException exception
) {
131 Logger
.getLogger(DesertPanel
.class.getName()).log(Level
.SEVERE
, null, exception
);
139 * <br>A non-null value
140 * @throws InstantiationException
141 * @throws IllegalAccessException
143 private final ParticleEngine
createParticleEngine() throws InstantiationException
, IllegalAccessException
{
144 return (ParticleEngine
) new Class
<?
>[] {
145 ParticleEngineCustomImplementation
.class,
146 ParticleEngineJBulletImplementation
.class,
147 ParticleEnginePhys2DImplementation
.class,
148 ParticleEngineOde4JImplementation
.class
149 }[ParticleEngineChoice
.this.getSelectedIndex()].newInstance();
158 * @author andrew (creation 2010-04-17)
160 @SuppressWarnings("serial")
161 private final class ParticleTypeChoice
extends Choice
{
163 public ParticleTypeChoice() {
164 final ResourceBundle resourceBundle
= ResourceBundle
.getBundle("org.sourceforge.desert.resources.messages");
166 for (final Particle
.Type type
: Particle
.Type
.values()) {
167 this.add(resourceBundle
.getString(type
.toString()));
170 this.updateDrawingBoardParticleType();
172 this.addItemListener(this.new ItemHandler());
175 final void updateDrawingBoardParticleType() {
176 DesertPanel
.this.getDrawingBoard().setParticleType(
177 Particle
.Type
.values()[ParticleTypeChoice
.this.getSelectedIndex()]);
182 * @author andrew (creation 2010-04-17)
184 private final class ItemHandler
implements ItemListener
{
187 public final void itemStateChanged(final ItemEvent event
) {
188 if (event
.getStateChange() == ItemEvent
.SELECTED
) {
189 ParticleTypeChoice
.this.updateDrawingBoardParticleType();
199 * @author codistmonk (creation 2010-04-15)
201 @SuppressWarnings("serial")
202 private final class ParticleCountLabel
extends Label
implements ActionListener
{
205 public final void actionPerformed(final ActionEvent event
) {
206 this.setText("Particle count: " + DesertPanel
.this.getDrawingBoard().getParticleCount());
213 * @author andrew (creation 2010-04-19)
215 @SuppressWarnings("serial")
216 private final class CursorPositionLabel
extends Label
implements MouseMotionListener
{
219 public final void mouseMoved(final MouseEvent event
) {
220 this.updateText(event
);
224 public final void mouseDragged(final MouseEvent event
) {
225 this.updateText(event
);
231 * <br>Should not be null
233 private final void updateText(final MouseEvent event
) {
234 this.setText("(" + event
.getX() + ", " +
235 (DesertPanel
.this.getDrawingBoard().getHeight() - event
.getY() - 1) + ")");
240 public static final int FRAMERATE
= 25;
245 * <br> Should not be null
248 * <br>A non-null value
250 private static final Box
horizontalBox(final Component
... components
) {
251 final Box result
= Box
.createHorizontalBox();
253 for (final Component component
: components
) {
254 result
.add(component
);
263 * <br> Should not be null
266 * <br>A non-null value
268 private static final Box
verticalBox(final Component
... components
) {
269 final Box result
= Box
.createVerticalBox();
271 for (final Component component
: components
) {
272 result
.add(component
);
280 * @author codistmonk (creation 2010-04-15)
282 @SuppressWarnings("serial")
283 private static final class FramerateLabel
extends Label
implements ActionListener
{
286 public final void actionPerformed(final ActionEvent event
) {
287 this.setText("Framerate: " + String
.format("%.1f", 1.0 / ((Timer
.Event
) event
).getDeltaTime()));
296 private static final class GCThread
extends Thread
{
305 } catch (Exception e
) {