How to Assign different keys to SWING Action? [duplicate] - java

People here keep suggesting to me to use Key Binding instead of KeyListener in Java 2D games.
What are the advantages and disadvantages of each one? Is Key Bindings really better for 2D games?

KeyListener is a much lower level API which requires the component that it is registered to be focused AND have keyboard focus. This can cause issues when you have other components within your game that may grab keyboard focus, for example.
KeyListener is generally more difficult to maintain and extend or change, as typically, all the key events are channelled through a single listener, so ALL the game controls originate from this single position.
(Now imagine you want to add other controls, such as buttons or even joystick or controllers to mix - you suddenly have any number of input hubs you need to consider, keep up to date and in sync :P)
The Key Bindings API has been designed to provide re-usable Actions which can be used in a variety of different parts of the Swing API, while this makes desktop application development easier, it can also make it easier when developing games...
Apart from the fact that you now gain control over the focus level that the events are generated, you also gain the flexibility to defining configurable key's which can be mapped to different actions
For example...
You define an Up Action, which moves you character up. This is divorced from any event. That means, the Action does not care how it is triggered, only what it should do when it is triggered.
You are now free to define the keystroke which would trigger this action. The great part about this, is suddenly have the ability to provide customisation to the user, so they can actually define the key stroke they want for the action - for example, without having to design some kind of key mapping system of your own.
It also means that you can use the same Action (and even the same instance) in a variety of different ways. For example, you can bind the Action to a key stroke and add it to button and if you're brave enough to try, even bind it another input device (like a joystick or controller)...but you'd need to build the API yourself to achieve it, but it means you suddenly have a single API concept for all your user input, for example...

Key bindings were introduced later. They map actions to specific keys whereas a listener simply listens for which keys are pressed. To be honest, it doesn't really matter which one you use, but it's always preferable to use key bindings.
There are many libraries also available which have their advantages/disadvantages. Key bindings should be fine though for a 2D game. However, please note that using the Java API is not recommended for game development. If you ever want to build 3D, or content rich 2D games, it's much better to use OpenGL. Try LWJGL or JOGL (LWJGL is preferred generally) or you can use a game engine such as Slick2D or LibGDX.

Related

JFrame Close to Background and Listen to Keys

Working on a new personal project with jframe. My goal is to close the frame in an ActionListener to the background, and when specific keys are pressed (Ctrl+Shft+L), I want to open the frame back up.
I'm not sure how I can do this keeping CPU usage low. I know I can set the frames visibility to false and then probably use a generic ActionListener for the keys however I have a few problems (and questions).
Is this the best way to do it? I'm trying to keep the CPU usage as low as possible.
Will the ActionListener even work while the frame's not visible?
How do I listen to multiple key presses? I have an idea but it doesn't sound like it will work.
Well, the problem is that java is designed to be platform independent.
Too achieve that, there have to be some limitations for the programms written in this programming language.
You want to capture keystrokes even if your window/programm doesn't have the focus set on it.
In fact what you need to write is some kind of global keylistener.
You can't do such things in java. In fact you have to choose a much more machine-oriented programming language like c/c++ to achieve what you want.
In java such stuff is only possible using the Java Native Interface (short JNI).
Using JNI it is possible to write a library for hooking the keyevents in for example c/c++ and call the librarys' methods using a java programm.
JNativeHook ( https://github.com/kwhat/jnativehook ) is using this exact approach. But well, i haven't tried this framework so i can't tell if it's working.
But i once used this and it worked fine for me: http://softk.de/opensource/jglobalkeylistener.html
You can just download the source and don't panic even if the site is written in german, the source-code is documented in english and even the comments within the code are in english.
PS: if that doesn't work, it may help you to google for things like "java global keylogger", because thats exactly what a keylogger is doing (well it obviously also logs the keys) and i think there will be much more stuff that may help you.
Greetings, Loki
Is this the best way to do it? I'm trying to keep the CPU usage as low as possible.
As previously mentioned, use JNativeHook. It is the only cross-platform solution and it will be much faster and less intensive than a polling approach like while (1) { GetAsyncKeyState(...); Sleep(5); } The biggest performance bottleneck with JNativeHook is the OS, not the library.
Will the ActionListener even work while the frame's not visible?
It will not work unless the frame has focus, but the native library will provide other events that do fire out of focus, so you could make it work by fabricating your own ActionEvent's from the NativeInputEvent listeners. Just make sure you set the library to use the Swing event dispatcher as it does not by default!
How do I listen to multiple key presses? I have an idea but it doesn't sound like it will work.
What do you mean by "multiple key presses?" If you mean auto-repeat when a key is held down, that is handled by sending multiple Key Pressed events after the auto repeat delay is exceeded at an interval of the auto repeat rate. You many also receive multiple Key Typed events if that event produces a printable character. When the key is released, a single key release event will be dispatched. If you mean a sequence of keys or multiple keys at the same time, you will need to do your own tracking or checks in the native input listener, but it should be possible.
Basic Modifier Example: Note that JNativeHook library has both a left and right mask for the modifier keys. I assume you want to use a combination of either the left or the right which makes this a tad more complicated.
public void nativeKeyPressed(NativeKeyEvent e) {
// If the keycode is L
if (e.getKeyCode() == NativeKeyEvent.VK_L) {
// We have a shift mask and a control mask for either the left or right key.
if (e.getModifiers() & NativeInputEvent.SHIFT_MASK && e.getModifiers() & NativeInputEvent.CTRL_MASK) {
// Make sure you don't have extra modifiers like the meta key.
if (e.getModifiers() & ~(NativeInputEvent.SHIFT_MASK | NativeInputEvent.CTRL_MASK) == 0x00) {
....
}
}
}
}

Is there a way for fuzzing Swing applications?

Back in the old days, PalmOS had an emulator that could generate random events ("tap here, enter garbage in that text field, ...") for testing how applications would handle them (called "Gremlins"). This is a bit like fuzzing, but for a GUI. Is there an easy (existing) way to do that in a Java Swing application?
Edit:
Please note that I don't want to be able to specify, which events are fired. I'd like some code to automatically generate and fire random (as in "Math.random()") events. The probability that the events do something useful or find a bug is pretty small. But that is offset by firing many events.
Try FEST. It simplifies the process of functional-testing Swing GUIs by allowing to access Swing components by name and then interacting with them.
An example from FEST site:
dialog.comboBox("domain").select("Users");
dialog.textBox("username").enterText("alex.ruiz");
dialog.button("ok").click();
dialog.optionPane().requireErrorMessage()
.requireMessage("Please enter your password");
Edit:
Alternatively, what you are trying to achieve, should be really straightforward using Math.random(), a loop, findBomponentAt(int, int) and Robot class. Especially Robot class mitght be of use, as it has methods for spoofing mouse and keyboard events

How do I listen for specific Java key events based on screen context?

I'm working on a small Java game with a few other people and I'm a bit stuck with regards to key events. I found a code snippet online that handles keyboard input for a 2D game. What I'm confused about is how to respond to certain key events based on which part of the game you're in. For example, if you're at the main menu, W, A, S, and D shouldn't work, but if you're in the game they should.
The only solution I've been able to come up with so far is just to use an enum and a switch to determine which keys should be listened for. This would work but I'm not sure if there's a better way to do it.
How do I listen for specific Java key events based on screen context?
Creating a class for each game state ('main menu', 'ready screen', 'playing state', etc.) would allow you to implement common KeyListener boilerplate once in a superclass and game state specific listeners and logic.
From memory the Slick library provides an API supporting this approach.

Questions: controlling a Swing GUI from an external class and separating logic from user interface

UPDATE: I'm using Netbeans and Matise and it's possible that it could be Matise causing the problems I describe below.
UPDATE 2: Thanks to those who offered constructive suggestions. After rewriting the code without Matise's help, the answer offered by ignis worked as he described. I'm still not sure how the code the Netbeans code generator interfered.
Though I've been programming in Java for awhile I've never done any GUI programming until now. I would like to control a certain part of my program externally (updating a jTextArea field with output from an external source) without requiring any user action to trigger the display of this output in the jTextArea.
Specifically, I want this output to begin displaying on startup and to start and stop depending on external conditions that have nothing to do with the GUI or what the user is doing. From what I understand so far you can trigger such events through action listeners, but these action listeners assume they are listening for user activity. If I must use action listeners, is there a way to trick the GUI into thinking user interaction has happened or is there a more straightforward way to achieve what I want to do?
Also, I'd really like to know more about best practices for separating GUI code from the application logic. From the docs I've come across, it seems that GUI development demands more of a messy integration of logic and user interface than, say, a web application where one can achieve complete separation. I'd be very interested in any leads in this area.
There is no need to use listeners. GUI objects are just like any other objects in the program, so actually
you can use the listener pattern in any part of the program, even if it is unrelated to the GUI
you can invoke methods of objects of the GUI whenever you want during the program execution, even if you do not attach any listeners to the objects in the GUI.
The main "rule" you must follow is that every method invocation performed on objects of the GUI must be run on the AWT Event Dispatch Thread (yes, that's true for Swing also).
http://download.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html
So you must wrap code accessing the GUI objects, into either
javax.swing.SwingUtilities.invokeLater( new Runnable() { ... } )
or
javax.swing.SwingUtilities.invokeAndWait( new Runnable() { ... } )
http://download.oracle.com/javase/6/docs/api/javax/swing/SwingUtilities.html
About "separating GUI code from the application logic": google "MVC" or "model view controller". This is the "standard" way of separating these things. It consists in making the GUI code (the "view") just a "facade" for the contents (the "model"). Another part of the application (the "controller") creates and invokes the model and the view as needed (it "controls" program execution, or it should do that, so it is named "controller"), and connects them with each other.
http://download.oracle.com/javase/tutorial/uiswing/components/model.html
For example, a JFoo class in the javax.swing package, that defines a Swing component, acts as the view for one or more FooModel class or interface defined either under javax.swing or one of its subpackages. You program will be the "controller" which instantiates the view and an implementation of the model properly (which may be one of the default implementations found under those packages I mentioned, or a custom implementation defined among your custom packages in the program).
http://download.oracle.com/javase/1.4.2/docs/api/javax/swing/package-summary.html
That's a really good question, IMHO... one I asked a couple of years ago on Sun's Java Forums (now basically defunct, thanx to Oracle, the half-witted pack of febrile fiscal fascists).
On the front of bringing order to kaos that is your typical "first cut" of an GUI, Google for Swing MVC. The first article I read on the topic was JavaWorld's "MVC meets Swing". I got lucky, because it explains the PROBLEMS as well as proposes sane solutions (with examples). Read through it, and google yourself for "extended reading" and hit us with any specific questions arrising from that.
On the "simulated user activity" front you've got nothing to worry about really... you need only observe your external conditions, say you detect that a local-file has been updated (for instance) and in turn "raise" a notification to registered listener(s)... the only difference being that in this case you're implementing both the "talker" and the "listener". Swings Listener interface may be re-used for the messaging (or not, at your distretion). Nothing tricky here.
"Raising" an "event" is totally straight forward. Basically you'd just invoke the "EventHappened" method on each of the listeners which is currently registered. The only tricky bit is dealing with "multithreaded-ness" innate to all non-trivial Swing apps... otherwise they'd run like three-legged-dogs, coz the EDT (google it) is constantly off doing everything, instead of just painting and message brokering (i.e. what it was designed for). (As said earlier by Ignis) The SwingUtilies class exposes a couple of handy invoke methods for "raising events" on the EDT.
There's nothing really special about Swing apps... Swing just has a pretty steep learning curve, that's all, especially multithreading... a topic which I had previously avoided like the plague, as "too complicated for a humble brain like mine". Needless to say that turned out to be a baseless fear. Even an old idiot like myself can understand it... it just takes longer, that's all.
Cheers. Keith.
This doesn't exactly answer your question, but you might be interested in using Netbeans for Java GUI development. You can use GUI in Netbeans to do Java GUI development.
Here's a good place to get started -
http://netbeans.org/kb/trails/matisse.html

How can I best apply OOP principles to games and other input-driven GUI apps?

Whenever I try to write graphical programs (whether a game or really any GUI app) I always wind up with one or two god classes with way too many methods (and long methods, too), and each class having far too many responsibilities. I have graphics being done at the same time as calculations and logic, and I feel like this is a really bad way to go about organizing my code. I want to get better at organizing my code and abstracting out responsibilities to different classes. Here's an example of where I'd like to start - I want to write a Minesweeper clone, just sort of as practice and to try to improve my software engineering skills. How would I go about making this nice and object-oriented? For the sake of discussion, let's just say I'm using Java (because I probably will, either that or C#). Here's some things I would think about:
should each tile inherit from JButton or JComponent and handle drawing itself?
or should the tiles just be stored as some non-graphical MinesweeperTile object and some other class handles drawing them?
is the 8-segment display countdown timer (pre-Vista, at least) a separate class that handles drawing itself?
when the user clicks, do the tiles have mouse event listeners or does some other collision detection method loop through the tiles and check each one to see if it's been hit?
I realize that there's not just one way to write a GUI application, but what are some pretty basic things I can start doing to make my code more organized, manageable, object-oriented, and just over all write better programs?
edit: I guess I should add that I'm familiar with MVC, and I was originally going to incorporate that into my question, but I guess I didn't want to shoehorn myself into MVC if that's not necessarily what I need. I did searched for topics on MVC with GUI apps but didn't really find anything that answers my specific question.
edit2: Thanks to everyone who answered. I wish I could accept more than one answer..
Here is a simple (but effective) OO design to get you started:
First create a Game object that is pure Java/C# code. With no UI or anything else platform specific. The Game object handles a Board object and a Player object. The Board object manages a number of Tile objects (where the mines are). The Player object keeps track of "Number of turns", "Score" etc. You will also need a Timer object to keep track of the game time.
Then create a separate UI object that doesn't know anything about the Game object. It is completely stand alone and completely platform dependent. It has its own UIBoard, UITile, UITimer etc. and can be told how to change its states. The UI object is responsible for the User Interface (output to the screen/sound and input from the user).
And finally, add the top level Application object that reads input from the UI object, tells the Game what to do based on the input, is notified by the Game about state changes and then turns around and tells the UI how to update itself.
This is (by the way) an adaption of the MVP (Model, View, Presenter) pattern. And (oh by the way) the MVP pattern is really just a specialization of the Mediator pattern. And (another oh by the way) the MVP pattern is basically the MVC (Model, View, Control) pattern where the View does NOT have access to the model. Which is a big improvement IMHO.
Have fun!
use a MVC framework that handles all the hard organization work for you. there's a ton of MVC framework topics on SO.
using high quality stuff written by others will probably teach you faster - you will get further and see more patterns with less headache.
I'm not suggesting this is the only way to do it, but what I would suggest is something like the following. Other people, please feel free to comment on this and make corrections.
Each tile should inherit from something and handle drawing itself. A button seems like the best solution because it already has the button drawing functionality (pressed, unpressed, etc) built in.
Each tile should also be aware of its neighbors. You would have eight pointers to each of its eight neighbors, setting them to null of course if there is no neighbor. When it goes to draw, it would query each neighbor's IsMine() function and display the count.
If none of its neighbors are a mine, it would then recurse into each neighbor's Reveal() method.
For the 7-segment display, each digit is its own class that handles drawing. Then I would make a CountdownSegmentDigit class that inherits from this class, but has additional functionality, namely CountDown(), Set(), and Reset() methods, as well as a HitZero event. Then the display timer itself is a collection of these digits, wired up to propagate zeroes left. Then have a Timer within the timer class which ticks every second and counts down the rightmost digit.
When the user clicks, see above. The tile itself will handle the mouse click (it is a button after all) and call its Reveal() method. If it is a mine, it will fire the MineExploded event, which your main form will be listening to.
For me, when I think of how to encapsulate objects, it helps to imagine it as a manufacturing process for physical parts. Ask yourself, "How can I design this system so it can be most efficiently built and reused?" Think about future reuse possibilities too. Remember the assembly process takes small pieces and builds them up into larger and larger pieces until the entire object is built. Each bit should be as independent as possible and handle its own logic, but be able to talk to the outside world when necessary.
Take the 7-segment display bit, you could have another use for it later that does not count down. Say you want a speedometer in a car or something. You will already have the digits that you can wire up together. (Think hardware: stock 7-segment displays that do nothing but light up. Then you attach a controller to them and they get functionality.)
In fact if you think hard enough, you might find you want CountUp() functionality too. And an event argument in HitZero to tell whether it was by counting up or down. But you can wait until later to add this functionality when you need it. This is where inheritance shines: inherit for your CountDownDigit and make a CountUpOrDownDigit.
Thinking about how I might design it in hardware, you might want to design each digit so it knows about its neighbors and count them up or down when appropriate. Have them remember a max value (remember, 60 seconds to a minute, not 100) so when they roll over 0, they reset appropriately. There's a world of possibilites.
The central concern of a Graphic User Interface is handling events. The user does X and you need to response or not respond to it. The games have the added complexity in that it needs to change state in real time. In a lot of cases it does this by transforming the current state into a new state and telling the UI to display the results. It does this in a very short amount of time.
You start off with a model. A collection of classes that represents the data the user wants to manipulate. This could represent the accounts of a business or vast frontiers of an unknown world.
The UI starts with defining a series of forms or screens. The idea is that is for each form or screen you create a interface that defines how the UI Controller will interact with it. In general there is one UI Controller classes for each form or screen.
The form passes the event to the UI Controller. The UI Controller then decides which command to execute. This is best done through the Command design pattern where each command is it own class.
The Command then is executed and manipulate the model. The Command then tells the UI Controller that a screen or a portion of a screen needs to be redraw. The UI Control then looks at the data in the model and uses the Screen Interface to redraw the screen.
By putting all the forms and screen behind a interface you can rip out what you have and put something different in. This includes even not having any forms at all but rather mock objects. This is good for automated testing. As long as something implements the Screen Interface properly the rest of the software will be happy.
Finally a game that has to operate in real time will have a loop (or loops) running that will be continually transforming the state of the game. It will use the UI Controller to redraw what it updated. Commands will insert or change information in the model. The next time the loop comes around the new information will be used. For example altering a vector of a object traveling through the air.
I don't like the MVC architecture as I feel it doesn't handle the issues of GUIs well. I prefer the use of a Supervising Controller which you can read about here. The reason for this is that I believe automated tests are one of the most important tools you have. The more you can automate the better off you are. The supervising presenter pattern makes the forms a thin shell so there is very little that can't be tested automatically.
Sorry to say it, but it seems you have mess in your head trying to improve your coding too much in one step.
There is no way to answer your question as such, but here we go.
First start with OOP, think about what objects are required for your game/GUI and start implementing them a little at a time, see if there are chances to break up these objects further, or perhaps reunite some objects that make no sense on their own, then try to figure out if you have repeated functionality among your objects, if you do, figure out if this repeated functionality is a (or many) base class or not.
Now this will take you a few days, or weeks to really grok it well, then worry about dividing your logic and rendering.
I have some tutorials that are written in C#. It discusses this very same topic. It is a starting point for a RogueLike game.
Object Oriented Design in C# Converting Legacy Game
Object Oriented Design: Domain Type Objects
Object Oriented Design: Rethinking Design Issues
BROKEN LINK - Object Oriented Design: Baby Steps in Acceptance Testing

Categories