Sign in to follow this  

[java] Odd LWJGL dialog problem (stolen focus)

This topic is 4729 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've got a LWJGL application that creates a little resolution chooser dialog before init'ing the LWJGL framework. The resolution chooser assigns itself to a new frame - so that it might be modal - and proceeds to get the user's options. Then the dialog turns modal off, goes invisible, and allows the main class to retrieve the user's options from it (by means of getXX functions). Well, the problem is that once the window goes invisible and turns itself non-modal, the main lwjgl window can't get the focus and I get no input! Help! here's the source, LWJGLFramework.java and ResolutionChooser.java.

// ------------------------------------------------------------------
// ResolutionChooser.java

package net.aklabs.game;

import net.aklabs.awtutils.dialogs.AlertDialog;
// ^^ you can take out the reference to this alert dialog if you want to
// compile this, it's not essential, and I don't feel like posting the source
// for the sake of brevity

import java.awt.*;
import java.awt.event.*;
import java.util.*;

public class ResolutionChooser extends Dialog implements ActionListener
{
    private static final String[] resolutionStrings = {
        "640x480",
        "800x600",
        "1024x768",
        "1280x1024",
        "1600x1200" };
    
    private static final int[] screenWidths = 
        {640, 800, 1024, 1280, 1600};

    private static final int[] screenHeights =
        {480, 600, 768, 1024, 1200};

    private static final int[] bitDepths = 
        {8, 16, 24, 32};

    Choice res;
    Choice bitdepth;
    Button okBtn;
    Button cancelBtn;

    Frame theParent;

    public ResolutionChooser(Frame parent)
    {
        super(parent);

        theParent = parent;

        setModal(true);
        
        setLayout(new GridLayout(2, 2, 5, 5));
        
        res = new Choice();
        bitdepth = new Choice();
        okBtn = new Button("Use These Settings");
        cancelBtn = new Button("Cancel");
        int c = 0;

        res.add("<Select a Resolution>");
        bitdepth.add("<Select a Bit Depth>");

        for ( c = 0; c < resolutionStrings.length ; c++ ) {
            res.add(resolutionStrings[c]);
        }

        for ( c = 0; c < bitDepths.length ; c++ ) {
            bitdepth.add(Integer.toString(bitDepths[c]));
        }

        setSize(300, 100);
        setTitle("Select your resolution");

        add(res);
        add(bitdepth);
        add(okBtn);
        add(cancelBtn);

        okBtn.addActionListener(this);
        cancelBtn.addActionListener(this);

        setVisible(true);
    }

    public void actionPerformed(ActionEvent e)
    {
        if ( e.getSource() == okBtn ) {
            if ( res.getSelectedIndex() == 0 ||
                 bitdepth.getSelectedIndex() == 0 ) {
                new AlertDialog(theParent, "Please select a resolution",
                                "Please select a resolution and bit depth",
                                275, 75, 0, 0);
                // ^^ this is the reference I said you could remove
            }
            else {
                setVisible(false);
            }
        }
        else {
            setVisible(false);
            res.select(0);
            bitdepth.select(0);
        }
    }

    public int getBitDepth()
    {
        int b = bitdepth.getSelectedIndex() - 1;
        if ( b > 0 ) {
            return(bitDepths[b]);
        }
        else
            return 0;
    }

    public int getWidth()
    {
        int w = res.getSelectedIndex() - 1;

        if ( w > 0 ) {
            return screenWidths[w];
        }
        else
            return 0;
    }

    public int getHeight()
    {
        int h = res.getSelectedIndex() - 1;
        
        if ( h > 0 ) {
            return screenHeights[h];
        }
        else
            return 0;
    }

    public static void main(String[] args)
    {
        ResolutionChooser theRes = new ResolutionChooser(new Frame());
    }
}


// --------------------------------------------------------------------

// lWJGLFramework.java 
// implements a simple LWJGL framework for your application=
// copy/paste or extend this to make LWJGL apps
// stolen (mainly) from the LWJGL demo application that bounced a white quad around the screen

/* 
 * Copyright (c) 2002-2004 LWJGL Project
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are 
 * met:
 * 
 * * Redistributions of source code must retain the above copyright 
 *   notice, this list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 *
 * * Neither the name of 'LWJGL' nor the names of 
 *   its contributors may be used to endorse or promote products derived 
 *   from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package net.aklabs.game;

import net.aklabs.game.ResolutionChooser;

import java.awt.*;

import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.glu.GLU;
import org.lwjgl.util.vector.Vector2f;

public class LWJGLFramework {
	/** Intended deiplay mode */
	private DisplayMode			mode;
        
	/**
	 * Creates a FullScreenWindowedTest
	 */
	public LWJGLFramework() {
	}
	/**
	 * Executes the test
	 */
	public void execute(int w, int h, int bd, int fps) {
		initialize(w, h, bd);
		mainLoop((int)1000/fps);
		cleanup();
	}
	/**
	 * Initializes the test
	 */
	private void initialize(int width, int height, int bpp) {
		try {
			//find displaymode
			mode = findDisplayMode(width, height, bpp);
			// start of in windowed mode
			Display.create();
			glInit();
                } catch (Exception e) {
			e.printStackTrace();
		}
	}
	/**
	 * Runs the main loop of the "test"
	 */
	private void mainLoop(int sleeptime) {
		while (!Keyboard.isKeyDown(Keyboard.KEY_ESCAPE) && !Display.isCloseRequested()) {
			if (Display.isVisible()) {
				// check keyboard input
				processKeyboard();
				// do "game" logic, and render it
				logic();
				render();
			} else {
				// no need to render/paint if nothing has changed (ie. window
				// dragged over)
				if (Display.isDirty()) {
					render();
				}
				// don't waste cpu time, sleep more
				try {
					Thread.sleep(sleeptime);
				} catch (InterruptedException inte) {
				}
			}
			// Update window
			Display.update();
		}
	}
	/**
	 * Performs the logic
	 */
	private void logic() {
		// put game logic here
	}
	private void render() {
		//clear background and do your drawing
		GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
                GL11.glPushMatrix();
                GL11.glPopMatrix();
	}
	/**
	 * Processes keyboard input
	 */
	private void processKeyboard() {
		//check for fullscreen key
		if (Keyboard.isKeyDown(Keyboard.KEY_F)) {
			try {
				Display.setFullscreen(true);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		//check for window key
		if (Keyboard.isKeyDown(Keyboard.KEY_W)) {
			try {
				Display.setFullscreen(false);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

	}
	/**
	 * Cleans up the test
	 */
	private void cleanup() {
//		Display.destroy();
	}

	/**
	 * Retrieves a displaymode, if one such is available
	 * 
	 * @param width
	 *            Required width
	 * @param height
	 *            Required height
	 * @param bpp
	 *            Minimum required bits per pixel
	 * @return
	 */
	private DisplayMode findDisplayMode(int width, int height, int bpp) {
		DisplayMode[] modes = Display.getAvailableDisplayModes();
		for (int i = 0; i < modes.length; i++) {
			if (modes[i].getWidth() == width && modes[i].getHeight() == height && modes[i].getBitsPerPixel() >= bpp && modes[i].getFrequency() <= 60) {
				try {
					Display.setDisplayMode(modes[i]);
				} catch (LWJGLException e) {
					e.printStackTrace();
				}
				return modes[i];
			}
		}
		return null;
	}
	/**
	 * Initializes OGL
	 */
	private void glInit() {
		// Go into orthographic projection mode.
		GL11.glMatrixMode(GL11.GL_PROJECTION);
		GL11.glLoadIdentity();
		GLU.gluOrtho2D(0, mode.getWidth(), 0, mode.getHeight());
		GL11.glMatrixMode(GL11.GL_MODELVIEW);
		GL11.glLoadIdentity();
		GL11.glViewport(0, 0, mode.getWidth(), mode.getHeight());
		//set clear color to black
		GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
		//sync frame (only works on windows)
		Display.setVSyncEnabled(true);
	}
	/**
	 * Test entry point
	 */
	public static void main(String[] args) {
                System.out.println("\nPress W for windowed, F for fullscreen, and ESC to quit.\n");
                System.out.println("\nYes, that's all I do. I'm a framework. Leave me be.\n");
                
                /*ResolutionChooser theRes = new ResolutionChooser(new Frame());
                int w = theRes.getWidth();
                int h = theRes.getHeight();
                int bd = theRes.getBitDepth();*/
                
                // the above code would work, but it's like the resolution chooser
                // isn't letting go of the keyboard... I've got no input in the main
                // window after init'ing.
                
                LWJGLFramework lwjglFrame = new LWJGLFramework();
		lwjglFrame.execute( 800, 600, 16, 30 );
	}
}



(edit) I haven't slept in like 36 hours. Sorry if it's a mess or there's a bug in it that I don't even know about yet. [Edited by - andrewk3652 on December 30, 2004 2:04:46 PM]

Share this post


Link to post
Share on other sites
works fine here - though I had to add: theParent.dispose(); to actionPerformed to make the program exit.

The program responds to f/w and works as expected, using 0.94.
This is what I have:
package net.aklabs.game;

import java.awt.Button;
import java.awt.Choice;
import java.awt.Dialog;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class ResolutionChooser extends Dialog implements ActionListener
{
private static final String[] resolutionStrings = {
"640x480",
"800x600",
"1024x768",
"1280x1024",
"1600x1200" };

private static final int[] screenWidths =
{640, 800, 1024, 1280, 1600};

private static final int[] screenHeights =
{480, 600, 768, 1024, 1200};

private static final int[] bitDepths =
{8, 16, 24, 32};

Choice res;
Choice bitdepth;
Button okBtn;
Button cancelBtn;

Frame theParent;

public ResolutionChooser(Frame parent)
{
super(parent);

theParent = parent;

setModal(true);

setLayout(new GridLayout(2, 2, 5, 5));

res = new Choice();
bitdepth = new Choice();
okBtn = new Button("Use These Settings");
cancelBtn = new Button("Cancel");
int c = 0;

res.add("<Select a Resolution>");
bitdepth.add("<Select a Bit Depth>");

for ( c = 0; c < resolutionStrings.length ; c++ ) {
res.add(resolutionStrings[c]);
}

for ( c = 0; c < bitDepths.length ; c++ ) {
bitdepth.add(Integer.toString(bitDepths[c]));
}

setSize(300, 100);
setTitle("Select your resolution");

add(res);
add(bitdepth);
add(okBtn);
add(cancelBtn);

okBtn.addActionListener(this);
cancelBtn.addActionListener(this);

setVisible(true);
}

public void actionPerformed(ActionEvent e)
{
if ( e.getSource() == okBtn ) {
if ( res.getSelectedIndex() == 0 ||
bitdepth.getSelectedIndex() == 0 ) {
}
else {
setVisible(false);
}
}
else {
setVisible(false);
res.select(0);
bitdepth.select(0);
}
theParent.dispose();
}

public int getBitDepth()
{
int b = bitdepth.getSelectedIndex() - 1;
if ( b > 0 ) {
return(bitDepths[b]);
}
else
return 0;
}

public int getWidth()
{
int w = res.getSelectedIndex() - 1;

if ( w > 0 ) {
return screenWidths[w];
}
else
return 0;
}

public int getHeight()
{
int h = res.getSelectedIndex() - 1;

if ( h > 0 ) {
return screenHeights[h];
}
else
return 0;
}

public static void main(String[] args)
{
ResolutionChooser theRes = new ResolutionChooser(new Frame());
}
}


//--------------------------------------------------------------------

//lWJGLFramework.java
//implements a simple LWJGL framework for your application=
//copy/paste or extend this to make LWJGL apps
//stolen (mainly) from the LWJGL demo application that bounced a white quad around the screen

/*
* Copyright (c) 2002-2004 LWJGL Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'LWJGL' nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/


package net.aklabs.game;

import java.awt.Frame;

import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.glu.GLU;

public class LWJGLFramework {

/** Intended deiplay mode */
private DisplayMode mode;

/** A rotating square! */
private static float angle;


/**
* Creates a FullScreenWindowedTest
*/

public LWJGLFramework() {
}

/**
* Executes the test
*/

public void execute(int w, int h, int bd, int fps) {
initialize(w, h, bd);
mainLoop((int) 1000 / fps);
cleanup();
}

/**
* Initializes the test
*/

private void initialize(int width, int height, int bpp) {
try {
//find displaymode
mode = findDisplayMode(width, height, bpp);
// start of in windowed mode
Display.create();
glInit();
} catch (Exception e) {
e.printStackTrace();
}
}

/**
* Runs the main loop of the "test"
*/

private void mainLoop(int sleeptime) {
while (!Keyboard.isKeyDown(Keyboard.KEY_ESCAPE) && !Display.isCloseRequested()) {
if (Display.isVisible()) {
// check keyboard input
processKeyboard();
// do "game" logic, and render it
logic();
render();
} else {
// no need to render/paint if nothing has changed (ie. window
// dragged over)
if (Display.isDirty()) {
render();
}
// don't waste cpu time, sleep more
try {
Thread.sleep(sleeptime);
} catch (InterruptedException inte) {
}
}
// Update window
Display.update();
}
}

/**
* Performs the logic
*/

private void logic() {
// put game logic here
angle += 2.0f % 360;
}

private void render() {
//clear background and do your drawing
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_STENCIL_BUFFER_BIT);

// TODO: all your rendering goes here
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
GL11.glPushMatrix();
GL11.glTranslatef(Display.getDisplayMode().getWidth() / 2, Display.getDisplayMode().getHeight() / 2, 0.0f);
GL11.glRotatef(angle, 0, 0, 1.0f);
GL11.glBegin(GL11.GL_QUADS);
GL11.glVertex2i(-50, -50);
GL11.glVertex2i(50, -50);
GL11.glVertex2i(50, 50);
GL11.glVertex2i(-50, 50);
GL11.glEnd();
GL11.glPopMatrix(); }

/**
* Processes keyboard input
*/

private void processKeyboard() {
//check for fullscreen key
if (Keyboard.isKeyDown(Keyboard.KEY_F)) {
try {
Display.setFullscreen(true);
} catch (Exception e) {
e.printStackTrace();
}
}
//check for window key
if (Keyboard.isKeyDown(Keyboard.KEY_W)) {
try {
Display.setFullscreen(false);
} catch (Exception e) {
e.printStackTrace();
}
}

}

/**
* Cleans up the test
*/

private void cleanup() {
Display.destroy();
}

/**
* Retrieves a displaymode, if one such is available
*
* @param width
* Required width
* @param height
* Required height
* @param bpp
* Minimum required bits per pixel
* @return
*/

private DisplayMode findDisplayMode(int width, int height, int bpp) {
DisplayMode[] modes = Display.getAvailableDisplayModes();
for (int i = 0; i < modes.length; i++) {
if (modes[i].getWidth() == width && modes[i].getHeight() == height && modes[i].getBitsPerPixel() >= bpp
&& modes[i].getFrequency() <= 60) {
try {
Display.setDisplayMode(modes[i]);
} catch (LWJGLException e) {
e.printStackTrace();
}
return modes[i];
}
}
return null;
}

/**
* Initializes OGL
*/

private void glInit() {
// Go into orthographic projection mode.
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GLU.gluOrtho2D(0, mode.getWidth(), 0, mode.getHeight());
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glLoadIdentity();
GL11.glViewport(0, 0, mode.getWidth(), mode.getHeight());
//set clear color to black
GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
//sync frame (only works on windows)
Display.setVSyncEnabled(true);
}

/**
* Test entry point
*/

public static void main(String[] args) {
System.out.println("\nPress W for windowed, F for fullscreen, and ESC to quit.\n");
System.out.println("\nYes, that's all I do. I'm a framework. Leave me be.\n");

ResolutionChooser theRes = new ResolutionChooser(new Frame());
int w = theRes.getWidth();
int h = theRes.getHeight();
int bd = theRes.getBitDepth();
theRes.dispose();
theRes = null;

// the above code would work, but it's like the resolution chooser
// isn't letting go of the keyboard... I've got no input in the main
// window after init'ing.

LWJGLFramework lwjglFrame = new LWJGLFramework();
lwjglFrame.execute(w, h, bd, 30);
}
}

Share this post


Link to post
Share on other sites

This topic is 4729 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this