Making GUIs

I can mostly agree with you. And like I said, I’m not trying to be condescending. But in this case, his statements were incorrect. I’m not trying to be rude or start a flamewar; I’m trying to explain that the things he wants already exist in Swing. I even wrote a little program in the name of sharing information, and I will happily take a look at any code he has that’s confusing him.

I don’t think anybody is ganging up on The Commander. But some of what he said does sound like a misunderstanding of how the model works, and we’re trying to correct that.

If you have any suggestions on how to go about this more delicately, I’m definitely all ears and will edit my last post as you see fit. I’m treating this like a technical forum, so I understand that my responses can be a bit short. It’s in the name of getting to the point, not in being condescending.

i did learn alot from this tho’ :slight_smile:

The “You can.” answers seem passive aggressive to the max. Not even one line saying how you would ever do that. Doesnt seem very helpful - all you are doing is saying “you are wrong”.

Thats like some would say “I wish there was a way to take water and break it down into hydrogen and oxygen gas” and your answer is “You can.” instead of saying “well this can be accomplished via electrolysis which uses an electrolyte, electrodes and current.”

I don’t think that you understand the problem, which is to paint Swing components inside the game loop, not rendering inside an empty JPanel. There should be a swingComponent.paint(g) in there.

setIgnoreRepaint only stops the operating system (OS) events from calling paint, not internal changes to the menu. See the java docs:

[quote]Sets whether or not paint messages received from the operating system should be ignored. This does not affect paint events generated in software by the AWT, unless they are an immediate response to an OS-level paint message.
This is useful, for example, if running under full-screen mode and better performance is desired, or if page-flipping is used as the buffer strategy.
[/quote]
So for example, if the game logic calls setText(String) on an in-game GUI JLabel, then inside the JLabel.setText method repaint is called, which posts an even to the EventQueue, which will occur on the EDT even though setText was called from the game loop thread, conflicting with the painting of that button in my game loop thread.
Stopping this is difficult, as basil said it requires ‘interception’ of the event on the EDT which is not easy. I thought it was impossible since no-one has shown how it is done without reflection hacks, but I’m open to being proved wrong. nsigma is the only person who has offered reasonable advice, and even then I wonder if it’s possible.

nsigma at least understands the problem and offers some directions to the solution. The run-your-game-loop-on-the-EDT solution is obvious and isn’t the solution I’m after which is painting the GUI in my own thread.
How do you push your own EventQueue? I note that there is Toolkit.getEventQueue but no Toolkit.setEventQueue()?
I would like to see your EDT-event interception idea work. As I said, no-one has demonstrated this being done that I have ever found.

Thanks, it’s nice to be beloved! I’ll be the first person to admit that I’m wrong, but so far it seems that people either don’t understand the problem or dismiss it as not being a problem.

I would like to treat the GUI like everything else in a game: with an update and a paint method. I thought that is what we would all want ???

[quote]Like I’ve said several times now, this is not just a Swing thing. Almost every GUI library (including OpenGL, Android, JavaFX, libGDX, and JMonkeyEngine) uses this model. I promise that the people behind these libraries have put more thought into it than you or I.
[/quote]
If every GUI library has an EDT like Swing, I’m surprised. I think it’s a design deficiency because it’s inflexible. According to the principal of loose-coupling, Swing’s event system, painting and logic should be separable, but clearly they aren’t.

[quote]Edit: And like Cas says, none of this really matters. If you really think you need to go through all of this rigmarole with active rendering and threading in Swing: you’re either wrong, or you should be using a different library that handles it for you.
[/quote]
On the whole I like the swing libary and it’s what I know. If I could re-use it in my games I would. But the way it enforces everything to be done on the EDT is quite irritating. I will try libgdx’s scene2d.ui, nifty or TWL for my next projects.

That tutorial guide gives no working examples, and even worse, it seems to indicate that active-rendering swing components from a non-EDT game loop thread in a thread safe way is impossible, since it says:

[quote]Don’t put drawing code in the paint routine. You may never know when that routine may get called! Instead, use another method name, such as render(Graphics g), which can be called from the paint method when operating in windowed mode, or alternately called with its own graphics from the rendering loop.
[/quote]
It seems to indicate that a swing component’s paint method can be called at any time from the EDT (with or without setIgnoreRepaint) and therefore you can’t truly paint swing components in your own game loop thread.

By the way, it’s great to be part of a forum where we can debate interesting topics like this.

And I say this in the friendliest way (eyeballs @Riven :wink: ) - What’s so damn special about your own thread? Do you complain that main() doesn’t run in your own thread? Now, I’m not 100% sure this is the way to go, or that AWT wouldn’t kick up a fuss about it, but it would be the simplest way - just make sure to manually drain and dispatch the event queue!


public static void main (final String[] args) {
  EventQueue.invokeLater(new Runnable() {
    public void run() {
      actualMain(args);
    }
  }
}

If you’re stuck with using another thread, I have doubts, as you do, about active rendering from another thread while the EDT is still processing events - not just on the paint() thing, but also because models aren’t thread-safe. So, custom queue …

Try some Google-fu on “extends EventQueue”! :smiley: There are lots of projects using event queue interception for various reasons - the one I’m most familiar with is in NetBeans because I work with the RCP a lot (this doesn’t re-dispatch to another thread, but times and warns on long running events)

The method you’re looking for is called push(), but it’s on EventQueue itself. You don’t replace the Toolkit queue, you push another on top of it.

settting a new event-queue : [icode]Toolkit.getDefaultToolkit().getSystemEventQueue().push(new EventQueue());[/icode].

Fair enough. I wasn’t trying to be passive aggressive, but the onus usually isn’t on us to prove every little misunderstanding wrong. When we get people making posts like “teh jav is suck, C++ is faster and you can use it for games” - we usually just tell them that they’re wrong and leave them to their own research, right? If they have specific code showing specific benchmarks we can talk about that, but generally we just tell them “you’re wrong, here’s some links explaining why, now if you have some code, please post it.”

And that’s exactly what I did here. I’m not saying CK is a novice or a troll, in fact I quite like the dude, but I feel like I’m being scolded for telling somebody they’re technically incorrect- on a technical forum.

Can we take another look at the conversation from my perspective?

Post 11: CK: Everything must be done on the event dispatch thread rather than your game loop thread, which is quite irritating.
Post 13: CK: I don’t see why painting, logic and event processing should be restricted to the same thread. It seems like it wasn’t thought out very well by the Sun swing engineers.
Post 16: Me: Here’s a link to an explanation about why the EDT works the way it does.
Post 18: CK: That way Swing components could be used in a ‘direct-rendering’ game loop thread, rather than the current requirement where everything to do with them must be done on the EDT.
Post 21: Me: You can.
Post 22: CK: I’ve never heard of anyone doing it, because I presume that it’s impossible.
Post 25: Me: You can absolutely do that.
Post 32: CK: Show me how you can make Swing render in your own thread without the event dispatch thread (EDT).
Post 38: Me: You can, and here’s some code.
Post 39: Riven: don’t gang up on CK

If it were anybody else, we would have required code to support the claims. But instead, the onus is on us to discount what appears to be a simple misunderstanding of Swing’s model. That seems backwards. It’s like me making a post that says libGDX sucks because you can’t render images- and then requiring other people to post code that proves me wrong.

Anyway, I was going to make a longer post explaining each of my “you can” statements with another code example, but basil_ and nsigma have already covered the basics- and I don’t want to appear to be ganging up on anybody.

I hope there are no hard feelings, and I apologize if I came off as passive aggressive or condescending. That was not my intention. Chit-Chat Monster, here I come.

Thank you, I’ll try that and report back. It certainly looks like the solution I’m after, which is great.

There’s nothing special about my main game loop thread. But what’s so special about the GUI library? I just don’t think that a GUI library needs to bundle a thread with itself and force me to do all event handling, painting and logic on it. I mean, what if the physics, lighting, AI and scripting also insisted on running all their code on their own threads? It’d be a nightmare. I don’t see what’s so special about a GUI when all it’s supposed to do is update and paint like everything else ???

[quote]If you’re stuck with using another thread, I have doubts, as you do, about active rendering from another thread while the EDT is still processing events - not just on the paint() thing, but also because models aren’t thread-safe. So, custom queue …
[/quote]
It seems as though Swing model updates are also just events on the EventQueue, so I should be able to intercept them if EventQueue.push() works out.

By the way, I stumbled on this java.net forum thread which was written by the Swing dev’s Scott Violet and Dmitri Trembovetski:
https://www.java.net/node/644028
Dmitri says that the context-switching from calling invokeLater is expensive in the last post. So perhaps there’s also a performance reason why rendering from a single thread is a better idea.

Thanks for your advice nsigma, much appreciated.

There’s nothing special about it. It’s just designed primarily to be an OS-event-driven UI library for normal UIs, for which its design is perfectly optimal.

FWIW I’ve got my own UI library I use for making games UIs. It executes in the main loop, and renders in the main loop, and doesn’t even use “events” (just a horribly complex load of state machines). As soon as I want to do anything asynchronous, I have to punt it out into another thread and I am only allowed to interact with my own UI in the main thread. It’s a solution you’ll end up with time and time again - it’s best to accept that’s the way it works.

At least with static import and lambda Runnables now it’s nowhere near as fiddly and ugly as it used to look:


invokeLater(()->{ setText("Finished!"); });

Cas :slight_smile:

Thanks, and no hard feelings either. I think it’s great that a solution might have been found. If I had to pay for all the experts who participated in this thread it would surely cost thousands! 8)

But there was obviously a misunderstanding which is evident in the code you posted. You were talking about direct-rendering inside an empty JPanel which is pretty simple, there was no swingComponent.paint(Graphics2D) going on so there were no Swing GUI components (except the empty JPanel) being actively rendered. Whereas I was talking about drawing Swing components on top of the game graphics at 60Hz.

I thought this was obvious, and I also thought that you and PrinceC would only talk with such authority on the topic if you had actually achieved active rendering with Swing components painted on top of the game graphics without involving the EDT. Therefore I figured that sharing your secret and posting code would not be hard. But that’s fine, it was just a misunderstanding about what ‘direct rendering’ meant. Next time I’ll be more specific.

I think your system is perfect, it’s exactly what I would want in a GUI library too. No bundled EDT thread, and you probably have an update and paint method, with no locks since you do all the work in your own single thread. Swing should be able to be used like this, there was no need to tie the GUI component library to the EDT. Let the programmer manage his own threading problems. Yet for some reason you disagree with me ???

I’m going to butt out of this one, but I’ll just say that what you’re talking about is still possible, if not as simple as the one-line change you might be hoping for.

I understand your requirement, and the code I posted was meant as a bare minimum. You’d still use that basic idea for the more complicated stuff you’re talking about.

I will also say that trying to bend Swing this way is probably a horrible idea. I make my living as a Swing developer, so I absolutely feel your pain and desire for Swing to be easier to throw on top of other stuff.

I wonder if it’s easier to use JavaFX that way?

There is indeed a little confusion here as to what you were trying to do, which is now clearer. Basically hijacking Swing to render itself on top of some other scene maybe rendered by LWJGL, am I right? Which is indeed possible, though what you probably want to actually be doing is rendering the Swing UI to a BufferedImage and then blitting that on top of the GL scene. It’s fiddly though and requires some fun with event queues as hinted back along… and at the end of the day you’ll have a fugly Swing UI on top of your pretty game which sort of defeats the point :expressionless:

The libgdx UIs seem very capable - see Spine for an example of a UI made entirely in libgdx and rendered with OpenGL. No Swing involved!

Cas :slight_smile:

back to the OP : can we use swing to create a GUI with libGDX ?

Yes, but why?

There are libraries that can do it for you a hundred times more fancy.
Here is one i found a year ago or so, but haven’t tried in a game yet
http://l33tlabs.org/

why not ? swing is pretty complete, mature and not too hard to use. works out of the box.

would be nice to not reinvent the wheel or bring in more 3rd party dependencies :slight_smile:

This isn’t really an answer to KevinWorkman’s question, I don’t think. But it does involve using JavaFX on Android, and I thought it looked interesting. Has anyone else sized up this strategy for running JavaFX on Android?

https://bitbucket.org/javafxports/android/wiki/Home
https://blogs.oracle.com/jfxprg/entry/javafx_on_android

Maybe this isn’t a total hijack. The subject line of this thread is “Making GUIs” after all.

Sheesh, wth are you guys doing in this thread?