Fix crash at startup due to splash screen handling

This commit is contained in:
Sampo Niskanen 2012-09-26 14:51:28 +00:00
parent a28c99fc54
commit efb4952333
3 changed files with 113 additions and 105 deletions

View File

@ -13,6 +13,7 @@ import javax.swing.Timer;
import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.database.ThrustCurveMotorSetDatabase;
import net.sf.openrocket.gui.main.Splash;
import net.sf.openrocket.gui.util.GUIUtil;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.logging.LogHelper;
@ -61,7 +62,8 @@ public class MotorDatabaseLoadingDialog extends JDialog {
if (db.isLoaded())
return;
if (SplashScreen.getSplashScreen() == null) {
SplashScreen splash = Splash.getSplashScreen();
if (splash == null || !splash.isVisible()) {
log.info(1, "Motor database not loaded yet, displaying dialog");

View File

@ -34,6 +34,7 @@ import javax.swing.event.MouseInputAdapter;
import net.sf.openrocket.gui.figureelements.CGCaret;
import net.sf.openrocket.gui.figureelements.CPCaret;
import net.sf.openrocket.gui.figureelements.FigureElement;
import net.sf.openrocket.gui.main.Splash;
import net.sf.openrocket.logging.LogHelper;
import net.sf.openrocket.rocketcomponent.Configuration;
import net.sf.openrocket.rocketcomponent.RocketComponent;
@ -55,42 +56,42 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
//drop down to z-order themselves.
JPopupMenu.setDefaultLightWeightPopupEnabled(false);
}
private static final double fovY = 15.0;
private static double fovX = Double.NaN;
private static final int CARET_SIZE = 20;
private Configuration configuration;
private GLCanvas canvas;
private Overlay extrasOverlay, caretOverlay;
private BufferedImage cgCaretRaster, cpCaretRaster;
private volatile boolean redrawExtras = true;
private final ArrayList<FigureElement> relativeExtra = new ArrayList<FigureElement>();
private final ArrayList<FigureElement> absoluteExtra = new ArrayList<FigureElement>();
private double roll = 0;
private double yaw = 0;
Point pickPoint = null;
MouseEvent pickEvent;
float[] lightPosition = new float[] { 1, 4, 1, 0 };
RocketRenderer rr = new RocketRenderer();
public RocketFigure3d(Configuration config) {
this.configuration = config;
this.setLayout(new BorderLayout());
//Only initizlize GL if 3d is enabled.
if ( is3dEnabled() ){
if (is3dEnabled()) {
//Fixes a linux / X bug: Splash must be closed before GL Init
SplashScreen splash = SplashScreen.getSplashScreen();
if ( splash != null )
SplashScreen splash = Splash.getSplashScreen();
if (splash != null && splash.isVisible())
splash.close();
initGLCanvas();
@ -102,11 +103,11 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
* launch time.
* @return
*/
public static boolean is3dEnabled(){
public static boolean is3dEnabled() {
return System.getProperty("openrocket.3d.disable") == null;
}
private void initGLCanvas(){
private void initGLCanvas() {
log.debug("Initializing RocketFigure3D OpenGL Canvas");
try {
log.debug("Setting up GL capabilities...");
@ -125,16 +126,16 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
log.verbose("GL - setStencilBits");
caps.setStencilBits(1);
log.verbose("GL - Creating Canvas");
canvas = new GLCanvas(caps);
log.verbose("GL - Registering as GLEventListener on canvas");
canvas.addGLEventListener(this);
log.verbose("GL - Adding canvas to this JPanel");
this.add(canvas, BorderLayout.CENTER);
log.verbose("GL - Setting up mouse listeners");
setupMouseListeners();
@ -152,7 +153,7 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
/**
* Set up the standard rendering hints on the Graphics2D
*/
private static void setRenderingHints(Graphics2D g){
private static void setRenderingHints(Graphics2D g) {
g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
RenderingHints.VALUE_STROKE_NORMALIZE);
g.setRenderingHint(RenderingHints.KEY_RENDERING,
@ -165,7 +166,7 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
* Rasterize the carets into 2 buffered images that I can blit onto the
* 3d display every redraw without all of the caret shape rendering overhead
*/
private void rasterizeCarets(){
private void rasterizeCarets() {
Graphics2D g2d;
//Rasterize a CG Caret
@ -176,10 +177,10 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
g2d.setBackground(new Color(0, 0, 0, 0));
g2d.clearRect(0, 0, CARET_SIZE, CARET_SIZE);
new CGCaret(CARET_SIZE/2,CARET_SIZE/2).paint(g2d, 1.0);
new CGCaret(CARET_SIZE / 2, CARET_SIZE / 2).paint(g2d, 1.0);
g2d.dispose();
//Rasterize a CP Caret
cpCaretRaster = new BufferedImage(CARET_SIZE, CARET_SIZE, BufferedImage.TYPE_4BYTE_ABGR);
g2d = cpCaretRaster.createGraphics();
@ -188,47 +189,47 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
g2d.setBackground(new Color(0, 0, 0, 0));
g2d.clearRect(0, 0, CARET_SIZE, CARET_SIZE);
new CPCaret(CARET_SIZE/2,CARET_SIZE/2).paint(g2d, 1.0);
new CPCaret(CARET_SIZE / 2, CARET_SIZE / 2).paint(g2d, 1.0);
g2d.dispose();
}
private void setupMouseListeners() {
MouseInputAdapter a = new MouseInputAdapter() {
int lastX;
int lastY;
MouseEvent pressEvent;
@Override
public void mousePressed(MouseEvent e) {
lastX = e.getX();
lastY = e.getY();
pressEvent = e;
}
@Override
public void mouseClicked(MouseEvent e) {
pickPoint = new Point(lastX, canvas.getHeight() - lastY);
pickEvent = e;
internalRepaint();
}
@Override
public void mouseDragged(MouseEvent e) {
int dx = lastX - e.getX();
int dy = lastY - e.getY();
lastX = e.getX();
lastY = e.getY();
if (pressEvent.getButton() == MouseEvent.BUTTON1) {
if (Math.abs(dx) > Math.abs(dy)) {
setYaw(yaw - (float) dx / 100.0);
setYaw(yaw - dx / 100.0);
} else {
if ( yaw > Math.PI/2.0 && yaw < 3.0*Math.PI/2.0 ){
if (yaw > Math.PI / 2.0 && yaw < 3.0 * Math.PI / 2.0) {
dy = -dy;
}
setRoll(roll - (float) dy / 100.0);
setRoll(roll - dy / 100.0);
}
} else {
lightPosition[0] -= 0.1f * dx;
@ -240,28 +241,28 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
canvas.addMouseMotionListener(a);
canvas.addMouseListener(a);
}
public void setConfiguration(Configuration configuration) {
this.configuration = configuration;
updateFigure();
}
@Override
public void display(GLAutoDrawable drawable) {
GL2 gl = drawable.getGL().getGL2();
GLU glu = new GLU();
gl.glEnable(GL.GL_MULTISAMPLE);
gl.glClearColor(1, 1, 1, 1);
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
setupView(gl, glu);
if (pickPoint != null) {
gl.glDisable(GLLightingFunc.GL_LIGHTING);
final RocketComponent picked = rr.pick(drawable, configuration,
pickPoint, pickEvent.isShiftDown()?selection:null );
pickPoint, pickEvent.isShiftDown() ? selection : null);
if (csl != null && picked != null) {
final MouseEvent e = pickEvent;
SwingUtilities.invokeLater(new Runnable() {
@ -271,13 +272,13 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
e);
}
});
}
pickPoint = null;
gl.glClearColor(1, 1, 1, 1);
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
gl.glEnable(GLLightingFunc.GL_LIGHTING);
}
rr.render(drawable, configuration, selection);
@ -285,7 +286,7 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
drawExtras(gl, glu);
drawCarets(gl, glu);
}
private void drawCarets(GL2 gl, GLU glu) {
final Graphics2D og2d = caretOverlay.createGraphics();
@ -294,12 +295,12 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
og2d.setBackground(new Color(0, 0, 0, 0));
og2d.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
caretOverlay.markDirty(0, 0, canvas.getWidth(), canvas.getHeight());
// The existing relative Extras don't really work right for 3d.
Coordinate pCP = project(cp, gl, glu);
Coordinate pCG = project(cg, gl, glu);
final int d = CARET_SIZE/2;
final int d = CARET_SIZE / 2;
//z order the carets
if (pCG.z < pCP.z) {
@ -335,18 +336,18 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
* Re-blits the overlay every frame. Only re-renders the overlay
* when needed.
*/
private void drawExtras(GL2 gl, GLU glu){
private void drawExtras(GL2 gl, GLU glu) {
//Only re-render if needed
// redrawExtras: Some external change (new simulation data) means
// the data is out of date.
// extrasOverlay.contentsLost(): For some reason the buffer with this
// data is lost.
if ( redrawExtras || extrasOverlay.contentsLost() ){
if (redrawExtras || extrasOverlay.contentsLost()) {
log.debug("Redrawing Overlay");
final Graphics2D og2d = extrasOverlay.createGraphics();
final Graphics2D og2d = extrasOverlay.createGraphics();
setRenderingHints(og2d);
og2d.setBackground(new Color(0, 0, 0, 0));
og2d.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
extrasOverlay.markDirty(0, 0, canvas.getWidth(), canvas.getHeight());
@ -355,7 +356,7 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
e.paint(og2d, 1);
}
Rectangle rect = this.getVisibleRect();
for (FigureElement e : absoluteExtra) {
e.paint(og2d, 1.0, rect);
}
@ -363,28 +364,28 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
redrawExtras = false;
}
//Re-blit to gl canvas every time
gl.glEnable(GL.GL_BLEND);
extrasOverlay.drawAll();
gl.glDisable(GL.GL_BLEND);
}
@Override
public void dispose(GLAutoDrawable drawable) {
log.verbose("GL - dispose() called");
}
@Override
public void init(GLAutoDrawable drawable) {
log.verbose("GL - init() called");
rr.init(drawable);
GL2 gl = drawable.getGL().getGL2();
gl.glClearDepth(1.0f); // clear z-buffer to the farthest
gl.glDepthFunc(GL.GL_LEQUAL); // the type of depth test to do
float amb = 0.5f;
float dif = 1.0f;
gl.glLightfv(GLLightingFunc.GL_LIGHT1, GLLightingFunc.GL_AMBIENT,
@ -393,28 +394,28 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
new float[] { dif, dif, dif, 1 }, 0);
gl.glLightfv(GLLightingFunc.GL_LIGHT1, GLLightingFunc.GL_SPECULAR,
new float[] { dif, dif, dif, 1 }, 0);
gl.glEnable(GLLightingFunc.GL_LIGHT1);
gl.glEnable(GLLightingFunc.GL_LIGHTING);
gl.glShadeModel(GLLightingFunc.GL_SMOOTH);
gl.glEnable(GLLightingFunc.GL_NORMALIZE);
extrasOverlay = new Overlay(drawable);
caretOverlay = new Overlay(drawable);
log.verbose("GL - init() complete");
}
@Override
public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h) {
log.verbose("GL - reshape() called");
GL2 gl = drawable.getGL().getGL2();
GLU glu = new GLU();
double ratio = (double) w / (double) h;
fovX = fovY * ratio;
gl.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
gl.glLoadIdentity();
glu.gluPerspective(fovY, ratio, 0.05f, 100f);
@ -423,7 +424,7 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
redrawExtras = true;
log.verbose("GL - reshape() complete");
}
@SuppressWarnings("unused")
private static class Bounds {
double xMin, xMax, xSize;
@ -431,7 +432,7 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
double zMin, zMax, zSize;
double rMax;
}
/**
* Calculates the bounds for the current configuration
*
@ -443,13 +444,13 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
for (Coordinate c : bounds) {
ret.xMax = Math.max(ret.xMax, c.x);
ret.xMin = Math.min(ret.xMin, c.x);
ret.yMax = Math.max(ret.yMax, c.y);
ret.yMin = Math.min(ret.yMin, c.y);
ret.zMax = Math.max(ret.zMax, c.z);
ret.zMin = Math.min(ret.zMin, c.z);
double r = MathUtil.hypot(c.y, c.z);
ret.rMax = Math.max(ret.rMax, r);
}
@ -458,17 +459,17 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
ret.zSize = ret.zMax - ret.zMin;
return ret;
}
private void setupView(GL2 gl, GLU glu) {
log.verbose("GL - setupView() called");
gl.glLoadIdentity();
gl.glLightfv(GLLightingFunc.GL_LIGHT1, GLLightingFunc.GL_POSITION,
lightPosition, 0);
// Get the bounds
Bounds b = calculateBounds();
// Calculate the distance needed to fit the bounds in both the X and Y
// direction
// Add 10% for space around it.
@ -476,13 +477,13 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
/ Math.tan(Math.toRadians(fovX / 2.0));
double dY = (b.rMax * 2.0 * 1.2 / 2.0)
/ Math.tan(Math.toRadians(fovY / 2.0));
// Move back the greater of the 2 distances
glu.gluLookAt(0, 0, Math.max(dX, dY), 0, 0, 0, 0, 1, 0);
gl.glRotated(yaw * (180.0 / Math.PI), 0, 1, 0);
gl.glRotated(roll * (180.0 / Math.PI), 1, 0, 0);
// Center the rocket in the view.
gl.glTranslated(-b.xMin - b.xSize / 2.0, 0, 0);
@ -493,13 +494,13 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
//Flip textures for LEFT handed coords
gl.glMatrixMode(GL.GL_TEXTURE);
gl.glLoadIdentity();
gl.glScaled(-1,1,1);
gl.glTranslated(-1,0,0);
gl.glScaled(-1, 1, 1);
gl.glTranslated(-1, 0, 0);
gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
log.verbose("GL - setupView() complete");
}
/**
* Call when the rocket has changed
*/
@ -508,8 +509,8 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
rr.updateFigure();
internalRepaint();
}
private void internalRepaint(){
private void internalRepaint() {
log.verbose("GL - internalRepaint() called");
super.repaint();
if (canvas != null)
@ -524,9 +525,9 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
internalRepaint();
log.verbose("GL - repaint() complete");
}
private Set<RocketComponent> selection = new HashSet<RocketComponent>();
public void setSelection(RocketComponent[] selection) {
this.selection.clear();
if (selection != null) {
@ -535,33 +536,33 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
}
internalRepaint();
}
private void setRoll(double rot) {
if (MathUtil.equals(roll, rot))
return;
this.roll = MathUtil.reduce360(rot);
internalRepaint();
}
private void setYaw(double rot) {
if (MathUtil.equals(yaw, rot))
return;
this.yaw = MathUtil.reduce360(rot);
internalRepaint();
}
// ///////////// Extra methods
private Coordinate project(Coordinate c, GL2 gl, GLU glu) {
log.verbose("GL - project() called");
double[] mvmatrix = new double[16];
double[] projmatrix = new double[16];
int[] viewport = new int[4];
gl.glGetIntegerv(GL.GL_VIEWPORT, viewport, 0);
gl.glGetDoublev(GLMatrixFunc.GL_MODELVIEW_MATRIX, mvmatrix, 0);
gl.glGetDoublev(GLMatrixFunc.GL_PROJECTION_MATRIX, projmatrix, 0);
double out[] = new double[4];
glu.gluProject(c.x, c.y, c.z, mvmatrix, 0, projmatrix, 0, viewport, 0,
out, 0);
@ -570,59 +571,59 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
return new Coordinate(out[0], out[1], out[2]);
}
private Coordinate cp = new Coordinate(0, 0, 0);
private Coordinate cg = new Coordinate(0, 0, 0);
public void setCG(Coordinate cg) {
this.cg = cg;
redrawExtras = true;
}
public void setCP(Coordinate cp) {
this.cp = cp;
redrawExtras = true;
}
public void addRelativeExtra(FigureElement p) {
relativeExtra.add(p);
redrawExtras = true;
}
public void removeRelativeExtra(FigureElement p) {
relativeExtra.remove(p);
redrawExtras = true;
}
public void clearRelativeExtra() {
relativeExtra.clear();
redrawExtras = true;
}
public void addAbsoluteExtra(FigureElement p) {
absoluteExtra.add(p);
redrawExtras = true;
}
public void removeAbsoluteExtra(FigureElement p) {
absoluteExtra.remove(p);
redrawExtras = true;
}
public void clearAbsoluteExtra() {
absoluteExtra.clear();
redrawExtras = true;
}
private ComponentSelectionListener csl;
public static interface ComponentSelectionListener {
public void componentClicked(RocketComponent[] components, MouseEvent e);
}
public void addComponentSelectionListener(
ComponentSelectionListener newListener) {
this.csl = newListener;
}
}

View File

@ -38,7 +38,7 @@ public class Splash {
*/
public static boolean init() {
// Get the splash screen
SplashScreen s = getSplash();
SplashScreen s = getSplashScreen();
if (s == null)
return false;
@ -75,14 +75,19 @@ public class Splash {
/**
* Return the current splash screen or <code>null</code> if not available.
* Return the current splash screen or <code>null</code> if not available or already closed.
* This method catches the possible exceptions and returns null if they occur.
*
* @return the current splash screen, or <code>null</code>.
* @return the current (visible) splash screen, or <code>null</code>.
*/
private static SplashScreen getSplash() {
public static SplashScreen getSplashScreen() {
try {
return SplashScreen.getSplashScreen();
SplashScreen splash = SplashScreen.getSplashScreen();
if (splash != null && splash.isVisible()) {
return splash;
} else {
return null;
}
} catch (RuntimeException e) {
return null;
}