GLFW is not initializing window (LWJGL) - java

I am new to using LWJGL (and relatively so to Java in general) and as such, I was reading their page on getting started where they supplied an example Hello World program. I tried to run it myself and found that it errored with the following:
2020-03-18 10:20:02.145 java[19779:1119716] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '+[NSUndoManager(NSInternal) _endTopLevelGroupings] is only safe to invoke on the main thread.
I was confused as to what this meant because I didn't think the init() method was running in any thread other than main, and so I added a line to print which thread it was running in, and sure enough, it printed Thread[main,5,main].
What is going on here, and how can I fix it?
The full code is below for context.
import org.lwjgl.glfw.*;
import org.lwjgl.opengl.*;
import org.lwjgl.system.*;
import java.nio.*;
import static org.lwjgl.glfw.Callbacks.*;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.system.MemoryStack.*;
import static org.lwjgl.system.MemoryUtil.*;
public class HelloWorld {
// The window handle
private long window;
public void run() {
System.out.println("Hello LWJGL " + Version.getVersion() + "!");
init();
loop();
// Free the window callbacks and destroy the window
glfwFreeCallbacks(window);
glfwDestroyWindow(window);
// Terminate GLFW and free the error callback
glfwTerminate();
glfwSetErrorCallback(null).free();
}
private void init() {
// Setup an error callback. The default implementation
// will print the error message in System.err.
GLFWErrorCallback.createPrint(System.err).set();
// Initialize GLFW. Most GLFW functions will not work before doing this.
if ( !glfwInit() )
throw new IllegalStateException("Unable to initialize GLFW");
// Configure GLFW
glfwDefaultWindowHints(); // optional, the current window hints are already the default
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); // the window will stay hidden after creation
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); // the window will be resizable
// This should be running on main?
System.out.println(Thread.currentThread());
// Create the window -- This is where the problem is
window = glfwCreateWindow(300, 300, "Hello World!", NULL, NULL);
if ( window == NULL )
throw new RuntimeException("Failed to create the GLFW window");
// Setup a key callback. It will be called every time a key is pressed, repeated or released.
glfwSetKeyCallback(window, (window, key, scancode, action, mods) -> {
if ( key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE )
glfwSetWindowShouldClose(window, true); // We will detect this in the rendering loop
});
// Get the thread stack and push a new frame
try ( MemoryStack stack = stackPush() ) {
IntBuffer pWidth = stack.mallocInt(1); // int*
IntBuffer pHeight = stack.mallocInt(1); // int*
// Get the window size passed to glfwCreateWindow
glfwGetWindowSize(window, pWidth, pHeight);
// Get the resolution of the primary monitor
GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
// Center the window
glfwSetWindowPos(
window,
(vidmode.width() - pWidth.get(0)) / 2,
(vidmode.height() - pHeight.get(0)) / 2
);
} // the stack frame is popped automatically
// Make the OpenGL context current
glfwMakeContextCurrent(window);
// Enable v-sync
glfwSwapInterval(1);
// Make the window visible
glfwShowWindow(window);
}
private void loop() {
// This line is critical for LWJGL's interoperation with GLFW's
// OpenGL context, or any context that is managed externally.
// LWJGL detects the context that is current in the current thread,
// creates the GLCapabilities instance and makes the OpenGL
// bindings available for use.
GL.createCapabilities();
// Set the clear color
glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
// Run the rendering loop until the user has attempted to close
// the window or has pressed the ESCAPE key.
while ( !glfwWindowShouldClose(window) ) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the framebuffer
glfwSwapBuffers(window); // swap the color buffers
// Poll for window events. The key callback above will only be
// invoked during this call.
glfwPollEvents();
}
}
public static void main(String[] args) {
new HelloWorld().run();
}
}

There appears to be multiple issues with the example presented by the LWJGl3.org group.
1> The glfwInit() function call may need to be called a good deal earlier. this function needs to be called before other LWJGL function calls according to the library documentation.
1.1> Suggestion: place the call in the main()
public static void main(String[] args) {
glfwInit();
.....
1.2 OR- Suggestion: place it by itself as the first statement of the init() function
private void init() {
glfwInit();
....
1.3>OR- Suggestion:Create a class constructor and place the glfwInit(); function call in it so you are guaranteed that it is call early.
2> The import static declarations may need to be be altered
2.1> Suggestion: Try
import static org.lwjgl.glfw.GLFW.* ; // fires glfwInit;
//not helpful import static org.lwjgl.glfw.GLFW.glfwSetKeyCallback;
import static org.lwjgl.glfw.Callbacks.*;
import static org.lwjgl.glfw.GLFW.glfwSetKeyCallback;
//import static org.lwjgl.glfw.GLFWKeyCallback.*; //fails to do any thing
3> Give the "window" class variable a unique name in its declaration to avoid name collisions with the "window" associated with the Lambda function call --discussed later.
3.1 Suggestion:
// The window handle
private long windowid;
4> The init() function needs to have "local variable declarations;
int key;
int scancode;
int action ;
int mods;
5> The example as presented employs the new JRE8 feature Lambda function syntax: () -> trick. However Lambda functions are not "supported" for Eclipse 3.8.1 (ubuntu 16.04) already running on JRE8 but with Java SDK compliance set by default to 1.7. That required substantial child-birthing to move to Eclipse 2020-6R. Unfortunately, the effort is now in my Limbo like CPM86.
5.1> A "possible" work around may evolve from following Warmful Development's Setting up LWJGL 3 with Eclipse video at https://www.youtube.com/watch?v=VH9KAhjXVFM. The plan is to scan his series to see if a possible solution can evolve to my specific need.

Related

LWJGL: failed to load a library

Have been trying to work with 'lwjgl' on linux and am running into an issue when I run my compiled code from the terminal. I am using the stable release of lwjgl 3.
I downloaded the lwjgl.jar from the website and run the command javac -cp lwjgl.jar: Main.java
which compiles the code fine. Then I run: java -cp lwjgl.jar: Main after and it throws this error;
[LWJGL] Failed to load a library. Possible solutions:
a) Set -Djava.library.path or -Dorg.lwjgl.librarypath to the directory that contains the shared libraries.
b) Add the JAR(s) containing the shared libraries to the classpath.
[LWJGL] Enable debug mode with -Dorg.lwjgl.util.Debug=true for better diagnostics.
Exception in thread "EndlessRunner" java.lang.UnsatisfiedLinkError: Failed to locate library: liblwjgl.so
at org.lwjgl.system.Library.loadSystemRelative(Library.java:100)
at org.lwjgl.system.Library.loadSystem(Library.java:71)
at org.lwjgl.system.Library.<clinit>(Library.java:43)
at org.lwjgl.system.MemoryAccess.<clinit>(MemoryAccess.java:17)
at org.lwjgl.system.Pointer.<clinit>(Pointer.java:22)
at org.lwjgl.glfw.GLFW.<clinit>(GLFW.java:562)
at Main.init(Main.java:31)
at Main.run(Main.java:78)
at java.lang.Thread.run(Thread.java:745)
I'm not sure if I missed some files that I needed too or if I'm going about this entirely the wrong way. Here is the code I am using, it's just some that I found online and I'm using as a test.
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.system.MemoryUtil.*;
import java.nio.ByteBuffer;
import org.lwjgl.glfw.GLFWVidMode;
public class Main implements Runnable{
private Thread thread;
public boolean running = true;
private long window;
private int width = 1200, height = 800;
public static void main(String args[]){
Main game = new Main();
game.start();
}
public void start(){
running = true;
thread = new Thread(this, "EndlessRunner");
thread.start();
}
public void init(){
// Initializes our window creator library - GLFW
// This basically means, if this glfwInit() doesn't run properlly
// print an error to the console
if(glfwInit() != true){
// Throw an error.
System.err.println("GLFW initialization failed!");
}
// Allows our window to be resizable
glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);
// Creates our window. You'll need to declare private long window at the
// top of the class though.
// We pass the width and height of the game we want as well as the title for
// the window. The last 2 NULL parameters are for more advanced uses and you
// shouldn't worry about them right now.
window = glfwCreateWindow(width, height, "Endless Runner", NULL, NULL);
// This code performs the appropriate checks to ensure that the
// window was successfully created.
// If not then it prints an error to the console
if(window == NULL){
// Throw an Error
System.err.println("Could not create our Window!");
}
// creates a bytebuffer object 'vidmode' which then queries
// to see what the primary monitor is.
//ByteBuffer vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
// Sets the initial position of our game window.
glfwSetWindowPos(window, 100, 100);
// Sets the context of GLFW, this is vital for our program to work.
glfwMakeContextCurrent(window);
// finally shows our created window in all it's glory.
glfwShowWindow(window);
}
public void update(){
// Polls for any window events such as the window closing etc.
glfwPollEvents();
}
public void render(){
// Swaps out our buffers
glfwSwapBuffers(window);
}
#Override
public void run() {
// All our initialization code
init();
// Our main game loop
while(running){
update();
render();
// Checks to see if either the escape button or the
// red cross at the top were pressed.
// if so sets our boolean to false and closes the
// thread.
if(glfwWindowShouldClose(window) == true){
running = false;
}
}
}
}
Any help you guys can give would be very much appreciated.
Thanks.
I can only speak from using NetBeans 8 to run LWJGL 3, but I also got the same error. The problem I found had to do with the "native" jar files needing to be added to the "classpath" tab when setting up LWJGL initially. The reason for this is that it enables LWJGL to automatically find the native jars. Then under your VM settings you will want to set it to:
-Djava.library.path="Path to where you extracted JAR files"
Only include quotes if your path name includes any spaces
You can add lwjgl.jar to module path and lwjgl-native-\*.jar to classpath. Other too. For example: add lwjgl-opengl.jar to module path and lwjgl-opengl-native-\*.jar to classpath. That's work.

Processing: Sketch gets stuck when using Capture class

I'm using Processing 2.0.3 on Windows 8. I tried to use the following code but I've no idea why my sketch couldn't run when I'm using the processing.video.* library:
import processing.video.*;
Capture cam;
void setup() {
size(200, 200);
cam = new Capture(this);
cam.start();
}
void draw() {
if (cam.available()) {
// Reads the new frame
cam.read();
}
image(cam, 0, 0);
}
I notice that the sketch will get stuck and will not open the sketch applet window at all if I call anything related to the Capture class. Calling println(Capture.list()); for example will cause the sketch to stuck at where ever that line was called.
What do I have to do to resolve this problem?

Nifty GUI control prevents the rest of my application from rendering

I've been trying to add some basic gui elements to a openGl (via LWJGL) application using nifty gui, and while I've been successful in rendering panels and static text on top of the the applications graphics, using the built-in nifty controls (e.g. an editable text field) causes the rest of the application to not render. The strange part is that I don't even have to render the gui control, merely declaring it appears to cause this problem.
Compiler ready code showing the basic layout of the problem:
import static org.lwjgl.opengl.GL11.*;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.*;
import de.lessvoid.nifty.Nifty;
import de.lessvoid.nifty.builder.LayerBuilder;
import de.lessvoid.nifty.builder.ScreenBuilder;
import de.lessvoid.nifty.builder.TextBuilder;
import de.lessvoid.nifty.controls.textfield.builder.TextFieldBuilder;
import de.lessvoid.nifty.nulldevice.NullSoundDevice;
import de.lessvoid.nifty.renderer.lwjgl.input.LwjglInputSystem;
import de.lessvoid.nifty.renderer.lwjgl.render.LwjglRenderDevice;
import de.lessvoid.nifty.screen.Screen;
import de.lessvoid.nifty.tools.TimeProvider;
public class NiftyBreaksRendering {
private Nifty nifty;
private Screen screen;
public NiftyBreaksRendering() throws Exception{
//init display
Display.setDisplayMode(new DisplayMode(640,480));
Display.create();
//init nifty gui
LwjglInputSystem inputSystem = new LwjglInputSystem();
inputSystem.startup();
nifty = new Nifty(
new LwjglRenderDevice(),
new NullSoundDevice(),
inputSystem,
new TimeProvider());
// load default styles
nifty.loadStyleFile("nifty-default-styles.xml");
// load standard controls
nifty.loadControlFile("nifty-default-controls.xml");
screen = new ScreenBuilder("start") {{
layer(new LayerBuilder("baseLayer") {{
childLayoutHorizontal();
text(new TextBuilder("test"){{
font("aurulent-sans-16.fnt");
color("#f00f");
backgroundColor("#33af");
text("l33t");
}});
//begin: lines that break the rendering
control(new TextFieldBuilder("input","asdf") {{
width("200px");
}});
//end: lines that break the rendering
}});
}}.build(nifty);
nifty.gotoScreen("start");
//init opengl
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0,640,480,0,1,-1);
glMatrixMode(GL_MODELVIEW);
while(!Display.isCloseRequested())
{
//render
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_QUADS);
glVertex2i(400,400); //Upper left
glVertex2i(450,400);//upper right
glVertex2i(450,450);//bottom right
glVertex2i(400,450);//bottom left
glEnd();
glBegin(GL_LINES);
glVertex2i(100,100);
glVertex2i(200,200);
glEnd();
nifty.render(false);
Display.update();
Display.sync(60);
}
Display.destroy();
}
public static void main(String[] args) throws Exception {
new NiftyBreaksRendering();
}
}
What would really help to diagnose this kind of problems is a link to a http://sscce.org/
I guess this is related to OpenGL states changed by Nifty OR to textures being loaded by the Nifty controls which might mess up the rest of your application.
If you could provide more or the complete code I'm pretty sure we can find the problem.
Modified answer after complete example code was provided:
Thanks for providing a complete example!
As expected the problem is, that Nifty changes OpenGL state and leaves you with OpenGL basically in undefined state. The solution is to save your OpenGL states before you call Nifty and restore it afterwards. Here is some code that does exactly that. I've added the call to nifty.update() as well so that Nifty actually updates the GUI (and makes keyboard and mouse events work):
// update nifty
nifty.update();
// save your OpenGL state
// (assuming you are in glMatrixMode(GL_MODELVIEW) all the time)
glPushMatrix();
glPushAttrib(GL_ALL_ATTRIB_BITS);
// render Nifty (this will change OpenGL state)
nifty.render(false);
// restore your OpenGL state
glPopAttrib();
glPopMatrix();
With this change to your original code your example works for me now.
NiftyGUI (as a non-shader-based render) will at some point modify the modelview matrix. Do you clean up the damage it does to the modelview matrix, by initializing it with identity? You know, like this:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
GLU.gluOrtho2D(0f,(float)VIEWPORT_DIMENSIONS[0],0f,(float)VIEWPORT_DIMENSIONS[1]);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(translation[0],translation[1],0);
glRectf(-1,-1,1,1);

FullScreen Swing Components Fail to Receive Keyboard Input on Java 7 on Mac OS X Mountain Lion

Update 12/21:
7u10 was recently released. Confirmed that:
The issue still persists
Thankfully, the workaround still functions!
Update 11/7:
And we have a workaround!
Leonid Romanov from Oracle on the openjdk.java.net mailing list provided some insight as to what's going on:
Well, although I'm not 100% sure yet, but it looks like when we enter full screen some other window becomes the first responder, hence the beep. Could you please try the following workaround: after calling setFullScreenWindow() on a frame, call setVisible(false) followed by setVisible(true). This, in theory, should restore the correct first responder.
The snippet of code that seems to work is simply:
dev.setFullScreenWindow(f);
f.setVisible(false);
f.setVisible(true);
I have updated the sample code with the ability to toggle this fix on and off; it is required every time a window enters fullscreen.
In the larger context of my more complex application, I am still running into keyboard focus issues on subcomponents within the fullscreen window, where a mouse click causes my window to lose focus. (I'm guessing it's going to the undesired first responder window referenced above.) I'll report back when I have more information about this case - I cannot reproduce it in the smaller sample yet.
Update 10/31:
Major update to the sample code:
Includes toggle between FullScreen exclusive and Lion-style FullScreen modes
Listens to the KeyboardFocusManager to display the hierarchy for the currently focused component
Uses both input maps and KeyListeners to try to capture input
Also did some more digging with coworkers to try to isolate issues:
On one front, we tried overriding some methods in RT.jar to see if there were problems with the way the screen device is being selected. Also tried were the entry points to the Toolkit.beep() functionality to see if the alert sounds were coming from the Java side - appears not.
On another front, it was clear that not even the native side is receiving keyboard events. A coworker attributes this to a switch from an AWTView to a NSWindow in 7u6.
A selection of existing Oracle bugs has been found, which you can look up here:
8000276 : [macosx] graphicsDevice.setFullScreenWindow(frame) crashes JVM
8000430 : [macosx] java.awt.FileDialog issues on macosx
7175707 : [macosx] PIT: 8 b43 Not running on AppKit thread issue again
Update 10/26:
Thanks to the comment by #maslovalex below regarding an Applet working on 7u5, I went back and painstakingly examined compatibility with the JDK versions for OSX:
10.7.1 with 7u4: Fullscreen Works!
10.7.1 with 7u5: Fullscreen Works!
10.7.5 with 7u5: Fullscreen Works!
10.7.5 with 7u6: Fullscreen Breaks :(
Combined with the other tests noted elsewhere, it's clear there was an issue introduced with 7u6 that remains in 7u7 and 7u9, and it affects both Lion 10.7 and Mountain Lion 10.8.
7u6 was a major milestone release, bringing full support of the JRE and JDK to Mac OS X and also including Java FX as part of the distribution. Further info is available in the Release Notes and the Roadmap. It's not tremendously surprising that such an issue could crop up as support shifts to Java FX.
The question becomes:
Will Oracle fix this in a near-term release of the JDK? (If you have links to existing bugs, please include them here.)
Is a workaround possible in the interim?
Other updates from today:
I incorporated the Apple extensions approach to fullscreen mode as an alternate path of exploration (updated sample code pending cleanup). The good news: input works! The bad news: there really don't seem to be any kiosking/isolation options.
I tried killing the Dock - directly or with an App - as I understand the Dock is responsible for Command-Tab app switching, Mission Control, and Launch Pad, only to find out that it's responsible for the handling of fullscreen apps as well! As such, the Java calls become non-functional and never return.
If there's a way to disable Command-Tab (and Mission Control and Launchpad and Spaces) without affecting the Dock's fullscreen handling, that would be extremely useful. Alternatively, one can try to remap certain keys such as Command, but that will affect the ability to use that modifier elsewhere in the program and the system itself (not exactly ideal, when you need to Command-C to copy some text).
I've had no luck with KeyListeners (I'm not receiving any callbacks), but I have a few more options to try.
Based on a coworker's suggestion, I tried ((sun.lwawt.macosx.LWCToolkit)Toolkit.getDefaultToolkit()).isApplicationActive() via reflection. The idea was that it:
is a native method with the comment "Returns true if the application (one of its windows) owns keyboard focus.". Calls to this method were added in CPlatformWindow.java in the past few months related to focus logic. If it returns false in your test code, it's probably part of the problem.
Unfortunately, everywhere I checked it, the method returned true. So even according to the low level system, my windows should have keyboard focus.
My previous optimism regarding the JAlbum fix has been dashed. The developer posted a response on their forum that explains how they simply removed proper fullscreen support on OS X while running Java 7. They have a bug into Oracle (and I'm hoping to get the bug number).
Update 10/25:
I have now also tried Java 7u9 on Lion 10.7.4 and have seen the exact same issue, so it's JDK- not OS-specific.
The core question has become whether you can embed in a fullscreen window core Swing Components that have default handling for keyboard input (JTextField/JTextArea or even editable combo boxes) and expect them to behave normally (without having to resort to rebuilding their basic key bindings manually). Also in question is whether other stalwarts of windowed layouts, such as using tab for focus traversal, should work.
The ideal goal would be to have the ability take a windowed Swing app with all of its buttons, tabs, fields, etc. and run it in fullscreen exclusive/kiosk mode with most functionality intact. (Previously, I have seen that Dialog pop ups or ComboBox drop downs do not function in fullscreen on Java 6 on OS X, but other Components behave fine.)
I'll be looking into the eawt FullScreen capabilities, which will be interesting if they support kiosk lock down options, such as eliminating Command-Tab application switching.
Original Question:
I have a Swing app that for years has supported FullScreen (exclusive) mode on Mac OS X up through Java 6. I've been doing compatibility testing with the latest Mountain Lion release (10.8.2 Supplemental) and Oracle's JDK 7 and noticed a glaring issue while in that mode: mouse movement and clicks work fine, but keyboard input is not delivered to the components.
(I've narrowed this down in a test case below to not being able to type into a simple JTextField while in fullscreen mode.)
One symptom is that each key press results in a system beep, as if the OS is disallowing keyboard events from being delivered to the application.
Separately, my application has an exit hook installed, and the Command-Q combo will trigger that hook - it's clear that the OS is listening to standard key combos.
I have tested this separately on three different Macs with various installs:
On Apple Java 6u35 and 6u37: both windowed and fullscreen modes receive input.
On Oracle Java 7u7 and 7u9: windowed mode works as expected while fullscreen has the symptoms above.
This may have been previously reported:
Java Graphics Full Screen Mode not Registering Keyboard Input.
However, that question is not specific about the Java version or platform.
Additional searching has turned up a separate fullscreen option introduced in Lion:
Fullscreen feature for Java Apps on OSX Lion.
I have yet to try using this approach, as keyboard input seems integral to the target use cases of FullScreen Exclusive mode, such as games.
There is some mention in the JavaDoc for this mode that input methods might be disabled. I tried to call the suggested Component.enableInputMethods(false), but it seemed to have no effect.
I'm somewhat optimistic that there's a solution to this issue based on an entry in the release notes of a Java app I came across (JAlbum). A stated fix for 10.10.6: "Keyboard support wasn't working when running the full screen slide show on Mac and Java 7"
My test case is below. It is lightly modified from the second example in this issue (which, unmodified, also exhibits my problem): How to handle events from keyboard and mouse in full screen exclusive mode in java?
In particular, it adds a button to toggle fullscreen.
import java.lang.reflect.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.beans.*;
/** #see https://stackoverflow.com/questions/13064607/ */
public class FullScreenTest extends JPanel {
private GraphicsDevice dev = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
private JFrame f = new JFrame("FullScreenTest");
private static final String EXIT = "Exit";
private Action exit = new AbstractAction(EXIT) {
#Override
public void actionPerformed(ActionEvent e) {
Object o = dev.getFullScreenWindow();
if(o != null) {
dev.setFullScreenWindow(null);
}
f.dispatchEvent(new WindowEvent(f, WindowEvent.WINDOW_CLOSING));
}
};
private JButton exitBTN = new JButton(exit);
private JTextField jtf = new JTextField("Uneditable in FullScreen with Java7u6+ on Mac OS X 10.7.3+");
private JLabel keystrokeLabel = new JLabel("(Last Modifier+Key Pressed in JTextField)");
private JLabel jtfFocusLabel = new JLabel("(JTextField Focus State)");
private JLabel focusLabel = new JLabel("(Focused Component Hierarchy)");
private JCheckBox useOSXFullScreenCB = new JCheckBox("Use Lion-Style FullScreen Mode");
private JCheckBox useWorkaroundCB = new JCheckBox("Use Visibility Workaround to Restore 1st Responder Window");
private static final String TOGGLE = "Toggle FullScreen (Command-T or Enter)";
private Action toggle = new AbstractAction(TOGGLE) {
#Override
public void actionPerformed(ActionEvent e) {
Object o = dev.getFullScreenWindow();
if(o == null) {
f.pack();
/**
* !! Neither of these calls seem to have any later effect.
* One exception: I have a report of a
* Mini going into an unrecoverable black screen without setVisible(true);
* May be only a Java 6 compatibility issue. !!
*/
//f.setVisible(true);
//f.setVisible(false);
if(!useOSXFullScreenCB.isSelected()) {
// No keyboard input after this call unless workaround is used
dev.setFullScreenWindow(f);
/**
* Workaround provided by Leonid Romanov at Oracle.
*/
if(useWorkaroundCB.isSelected()) {
f.setVisible(false);
f.setVisible(true);
//Not necessary to invoke later...
/*SwingUtilities.invokeLater(new Runnable() {
public void run() {
f.setVisible(false);
f.setVisible(true);
}
});*/
}
}
else {
toggleOSXFullscreen(f);
}
}
else {
dev.setFullScreenWindow(null);
f.pack();
f.setVisible(true);
}
isAppActive();
}
};
private JButton toggleBTN = new JButton(toggle);
public FullScreenTest() {
// -- Layout --
this.setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
exitBTN.setAlignmentX(JComponent.CENTER_ALIGNMENT);
exitBTN.setMaximumSize(new Dimension(Short.MAX_VALUE, 50));
this.add(exitBTN);
jtf.setAlignmentX(JComponent.CENTER_ALIGNMENT);
jtf.setMaximumSize(new Dimension(Short.MAX_VALUE, Short.MAX_VALUE));
this.add(jtf);
keystrokeLabel.setAlignmentX(JComponent.CENTER_ALIGNMENT);
keystrokeLabel.setMaximumSize(new Dimension(Short.MAX_VALUE, 50));
keystrokeLabel.setHorizontalAlignment(SwingConstants.CENTER);
keystrokeLabel.setForeground(Color.DARK_GRAY);
this.add(keystrokeLabel);
jtfFocusLabel.setAlignmentX(JComponent.CENTER_ALIGNMENT);
jtfFocusLabel.setMaximumSize(new Dimension(Short.MAX_VALUE, 50));
jtfFocusLabel.setHorizontalAlignment(SwingConstants.CENTER);
jtfFocusLabel.setForeground(Color.DARK_GRAY);
this.add(jtfFocusLabel);
focusLabel.setAlignmentX(JComponent.CENTER_ALIGNMENT);
focusLabel.setMaximumSize(new Dimension(Short.MAX_VALUE, 50));
focusLabel.setHorizontalAlignment(SwingConstants.CENTER);
focusLabel.setForeground(Color.DARK_GRAY);
this.add(focusLabel);
useOSXFullScreenCB.setAlignmentX(JComponent.CENTER_ALIGNMENT);
useOSXFullScreenCB.setMaximumSize(new Dimension(Short.MAX_VALUE, 50));
useOSXFullScreenCB.setHorizontalAlignment(SwingConstants.CENTER);
this.add(useOSXFullScreenCB);
useWorkaroundCB.setAlignmentX(JComponent.CENTER_ALIGNMENT);
useWorkaroundCB.setMaximumSize(new Dimension(Short.MAX_VALUE, 50));
useWorkaroundCB.setHorizontalAlignment(SwingConstants.CENTER);
this.add(useWorkaroundCB);
toggleBTN.setAlignmentX(JComponent.CENTER_ALIGNMENT);
toggleBTN.setMaximumSize(new Dimension(Short.MAX_VALUE, 50));
this.add(toggleBTN);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setResizable(false);
f.setUndecorated(true);
f.add(this);
f.pack();
enableOSXFullscreen(f);
// -- Listeners --
// Default BTN set to see how input maps respond in fullscreen
f.getRootPane().setDefaultButton(toggleBTN);
// Explicit input map test with Command-T toggle action from anywhere in the window
this.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
KeyStroke.getKeyStroke(KeyEvent.VK_T, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()),
toggle.getValue(Action.NAME));
this.getActionMap().put(toggle.getValue(Action.NAME), toggle);
// KeyListener test
jtf.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
String ktext = "KeyPressed: "+e.getKeyModifiersText(e.getModifiers()) + "_"+ e.getKeyText(e.getKeyCode());
keystrokeLabel.setText(ktext);
System.out.println(ktext);
}
});
// FocusListener test
jtf.addFocusListener(new FocusListener() {
public void focusGained(FocusEvent fe) {
focused(fe);
}
public void focusLost(FocusEvent fe) {
focused(fe);
}
private void focused(FocusEvent fe) {
boolean allGood = jtf.hasFocus() && jtf.isEditable() && jtf.isEnabled();
jtfFocusLabel.setText("JTextField has focus (and is enabled/editable): " + allGood);
isAppActive();
}
});
// Keyboard Focus Manager
KeyboardFocusManager focusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
focusManager.addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent e) {
if (!("focusOwner".equals(e.getPropertyName()))) return;
Component comp = (Component)e.getNewValue();
if(comp == null) {
focusLabel.setText("(No Component Focused)");
return;
}
String label = comp.getClass().getName();
while(true) {
comp = comp.getParent();
if(comp == null) break;
label = comp.getClass().getSimpleName() + " -> " + label;
}
focusLabel.setText("Focus Hierarchy: " + label);
isAppActive();
}
});
}
/**
* Hint that this Window can enter fullscreen. Only need to call this once per Window.
* #param window
*/
#SuppressWarnings({"unchecked", "rawtypes"})
public static void enableOSXFullscreen(Window window) {
try {
Class util = Class.forName("com.apple.eawt.FullScreenUtilities");
Class params[] = new Class[]{Window.class, Boolean.TYPE};
Method method = util.getMethod("setWindowCanFullScreen", params);
method.invoke(util, window, true);
} catch (ClassNotFoundException e1) {
} catch (Exception e) {
System.out.println("Failed to enable Mac Fullscreen: "+e);
}
}
/**
* Toggle OSX fullscreen Window state. Must call enableOSXFullscreen first.
* Reflection version of: com.apple.eawt.Application.getApplication().requestToggleFullScreen(f);
* #param window
*/
#SuppressWarnings({"unchecked", "rawtypes"})
public static void toggleOSXFullscreen(Window window) {
try {
Class appClass = Class.forName("com.apple.eawt.Application");
Method method = appClass.getMethod("getApplication");
Object appInstance = method.invoke(appClass);
Class params[] = new Class[]{Window.class};
method = appClass.getMethod("requestToggleFullScreen", params);
method.invoke(appInstance, window);
} catch (ClassNotFoundException e1) {
} catch (Exception e) {
System.out.println("Failed to toggle Mac Fullscreen: "+e);
}
}
/**
* Quick check of the low-level window focus state based on Apple's Javadoc:
* "Returns true if the application (one of its windows) owns keyboard focus."
*/
#SuppressWarnings({"unchecked", "rawtypes"})
public static void isAppActive() {
try {
Class util = Class.forName("sun.lwawt.macosx.LWCToolkit");
Method method = util.getMethod("isApplicationActive");
Object obj = method.invoke(Toolkit.getDefaultToolkit());
System.out.println("AppActive: "+obj);
} catch (ClassNotFoundException e1) {
} catch (Exception e) {
System.out.println("Failed to check App: "+e);
}
}
public static void main(String[] args) {
System.out.println("Java Version: " + System.getProperty("java.version"));
System.out.println("OS Version: " + System.getProperty("os.version"));
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
FullScreenTest fst = new FullScreenTest();
if(!fst.dev.isFullScreenSupported()) {
System.out.println("FullScreen not supported on this graphics device. Exiting.");
System.exit(0);
}
fst.toggle.actionPerformed(null);
}
});
}
}
This is because the component to which you added the other has now lost focus, you can fix this by either:
calling requestFocus() on the component instance to which you add KeyBindings
or
alternatively use JComponent.WHEN_IN_FOCUSED_WINDOW with KeyBindings:
component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_Q, 0),
"doSomething");
component.getActionMap().put("doSomething",
anAction);
Reference:
How to Use Key Bindings
Instead, use key bindings, as shown in this FullScreenTest. Also, consider a DocumentListener, shown here, for text components.
I think I finally found a solution, registering click listeners against to the JFrame itself. (This is a class which extends JFrame, hence all the "this" references.)
/**
* Toggles full screen mode. Requires a lot of references to the JFrame.
*/
public void setFullScreen(boolean fullScreen){
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice dev = env.getDefaultScreenDevice();//Gets the main screen
if(!fullScreen){//Checks if a full screen application isn't open
this.dispose();//Restarts the JFrame
this.setVisible(false);
this.setResizable(true);//Re-enables resize-ability.
this.setUndecorated(false);//Adds title bar back
this.setVisible(true);//Shows restarted JFrame
this.removeMouseListener(macWorkAround);
this.pack();
this.setExtendedState(this.getExtendedState()|JFrame.MAXIMIZED_BOTH);//Returns to maximized state
this.fullScreen = false;
}
else{
this.dispose();//Restarts the JFrame
this.setResizable(false);//Disables resizing else causes bugs
this.setUndecorated(true);//removes title bar
this.setVisible(true);//Makes it visible again
this.revalidate();
this.setSize(Toolkit.getDefaultToolkit().getScreenSize());
try{
dev.setFullScreenWindow(this);//Makes it full screen
if(System.getProperty("os.name").indexOf("Mac OS X") >= 0){
this.setVisible(false);
this.setVisible(true);
this.addMouseListener(macWorkAround);
}
this.repaint();
this.revalidate();
}
catch(Exception e){
dev.setFullScreenWindow(null);//Fall back behavior
}
this.requestFocus();
this.fullScreen = true;
}
}
private MouseAdapter macWorkAround = new MouseAdapter(){
public void mouseClicked(MouseEvent e){
MainGUI.this.setVisible(false);
MainGUI.this.setVisible(true);
}
};

How can I use the return statement from one method in another?

I want to call the return statement tempimage in load_picture by passing it to showWindow, but I'm not sure how. heres a snippet of my code. edit:
i guess what I'm trying to say is, I'm not exactly sure what to do with the hardcoded "picture1.gif". I understand that I need to call a method to load the image, but I'm not too sure what to put in place of it.
:
package project3;
import java.util.Scanner;
import javax.swing.;
import java.awt.;
import java.net.*;
public class Project3 {
//initializing global
static Project3 theobject = new Project3();
final static int MIN_NUMBER=1;
final static int MAX_NUMBER=8;
static int image_number=1;
static Image theimage;
// This routine will load an image into memory, non-static requires an object
// It expects the name of the image file name and a JFrame passed to it
// It will assume an Internet conection is available
// It can only be called AFTER the program object has been created
// It will return a type Image variable, call it like this: theimage = object.load_picture("picture1.gif", frame);
// (hard code 'picture1.gif' only when testing - USE a method or variable for 'real' call)
// This code requires you to do an 'import java.awt.*' and an 'import java.net.*'
// Note: this method is using parameter and return type for input/output
// This routine will load an image into memory, non-static requires an object
// It expects the name of the image file name and a JFrame passed to it
// It will assume an Internet conection is available
// It can only be called AFTER the program object has been created
// It will return a type Image variable, call it like this: theimage = object.load_picture("picture1.gif", frame);
// (hard code 'picture1.gif' only when testing - USE a method or variable for 'real' call)
// This code requires you to do an 'import java.awt.*' and an 'import java.net.*'
// Note: this method is using parameter and return type for input/output
public Image load_picture(String imagefile, JFrame theframe)
{
Image tempimage;
// Create a MediaTracker to inform us when the image has
// been completely loaded.
MediaTracker tracker;
tracker = new MediaTracker(theframe);
// getImage() returns immediately. The image is not
// actually loaded until it is first used. We use a
// MediaTracker to make sure the image is loaded
// before we try to display it.
String startURL;
if (imagefile.startsWith("http"))
startURL = "";
else
startURL = "http://www.canyons.edu/departments/comp_sci/ferguson/cs111/images/";
URL myURL=null;
try
{
myURL = new URL(startURL + imagefile);
}
catch(MalformedURLException e) {
System.out.println("Error caught " + e.toString());
}
//tempimage = getImage(myURL); // JApplet version
tempimage = Toolkit.getDefaultToolkit().getImage(myURL); // stand alone program version
// Add the image to the MediaTracker so that we can wait for it
tracker.addImage(tempimage, 0);
try { tracker.waitForID(0); }
catch ( InterruptedException err) { System.err.println(err); }
return tempimage;
}
// This class/method uses a global variable that MUST be set before calling/using
// note: You can not call the paint routine directly, it is called when frame/window is shown
// look up the repaint() routine in the book
// Review Listings 8.5 and 8.6
//
public static class MyPanel extends JPanel {
public void paintComponent (Graphics g) {
JPanel panel= new JPanel();
int xpos,ypos;
super.paintComponent(g);
// set the xpos and ypos before you display the image
xpos = 300; // you pick the position
ypos = 200; // you pick the position
if (theimage != null) {
g.drawImage(theimage,xpos,ypos,this);
// note: theimage global variable must be set BEFORE paint is called
}
}
}
public static void showWindow( String filename ) {
// create, size and show a GUI window frame, you may need to click on taskbar to see window
//display the filename in the title of the window frame, otherwise the window will be blank (for now)
JFrame frame1= new JFrame();
theimage = theobject.load_picture("picture1.gif", frame1);
//"picture1.gif" is hardcoded, I want to call this using a method
frame1.setTitle(filename);
frame1.setSize(440,302);
frame1.setLocation(400,302);
frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame1.setVisible(true);
}
Any help is appreciated. Thanks
The value that is returned by the load_picture method can be sent directly to the showWindow method, or you can assign it to a variable:
String filename = "your/filename";
JFrame theFrame = new JFrame();
Project3 project = new Project3();
MyPanel.showWindow(project.load_picture(filename, theFrame);
From within the showWindow method, just call the load_picture method as follows:
Image tempImage = load_picture(filename, frame1);
From here you can do anything you like with the tempImage object.

Categories

Resources