I have the following hierarchy with Swing:
JFrame
|
+---> several JPanes
one special JPane with a Canvas
|
+------> Many Shapes on the Canvas that are derived from JComponents
I am confused where to put the Mouse event handlers to detect whether one of the shapes has been clicked. All examples I found so far, attach the event handlers to the root JPane, but since I want to process the events on the circles themselves, it feels quite expensive to loop over all shapes, when a click event on a JPanes is detected.
What is the right approach to have "local" events on the Shapes?
Related
I'm trying to create an universalish tab widget in libGDX. It contains a button bar and a pane bar and a pane view.
Lets assume the tabwidget is as big as the screen, and we have 3 tabs. The buttonbar takes up the top part of the screen, and the panes are in the bottom part. The paneView is a WidgetGroup for event handling, it is as big as the tabwidget minus the buttonBar.
Everything works just fine until I add an a scrollpane as a tab widget. Since this scrollPane calls:
event.stop();
the subsequent events are not called.
Since events "bubble" up through actors, the lowest level actor is handled first calling the event handlers of its parents and siblings upwards. This means the scrollpane is always handled before the tabwidget.
Is there a way to intert the order of the input listeners? Have the tab input be handled first and then the scrollpane input? Or will I have to reimplement the scrollpane handlers to get around this issue?
I think that the way you want to implement this is rather impossible - how actors would know if the fling gesture you are performing is addressed to which?
The resolution that comes to my mind is to
Create new stage being input processor (if it will be second inputProcessor you will need InputMultiplexer )
Implement GestureDetector and then detect horizontal swipes and react with moving group - read this tutorial to get more information
In my opinion it is generally not good idea to modify libgdx sources but of course you can do it (by downloading LibGDX from Github and import it as project you will have access to all sources) although in this case it is definitely unnecessary.
The list of SWT constants in the SWT API supplies two very similar event types (for use with various event listeners):
Show
Paint
What's the difference? Wouldn't all 'Show' events require a 'Paint' event and all 'Paint' events require a 'Show' event?
According to this page:
Show:
The widget is becoming visible
Paint:
A control was asked to draw
So the main difference is the following:
SWT.Show is dispatched once the Widget becomes visible. SWT.Paint is called whenever the Widget changes state, i.e. when it has to be redrawn. For example when it is resized or the content changes.
To answer your last question. Every Show event is coupled with a Paint, but not every Paint is coupled with a Show.
To see how it works just attach two Listeners to a Shell that just print out "Show" or "Paint" and see when they are fired.
My question concerns how to handle with simultaneous mouse events with Swing.
Both a MouseMotionListener and a MouseListener are added to follow a JPanel.
I have an object whose rotation takes places according to the x and y coordinates of the mouse pointers location (implemented by mouseMoved method of MouseMotionListener).
I've also got a MouseListener that performs its actions according to implemented mouseReleased() method.
The object is rotating neatly according to MouseMotionListener but a problem arises when the mouse button is pressed. As the mouse is now moved the rotation stops as obviously the JPanel is now waiting the mouseReleased() method to be executed.
Any ideas what's the best way to make these events happen simultaneously so that both the rotation according to the mouse pointers coordinates and operations according to mouseReleased() can be performed concurrently without disrupting each other?
An old article going into swing threading specifics:
http://www.javaworld.com/javaworld/jw-08-2007/jw-08-swingthreading.html?page=1
Worth a read as to the whys and hows.
If you wanted to do two action in your application simultaneously, you will do it in diffrent threads
When you need to do something in diffrent threads in swing - you should use SwingWorker
For a school project I'm writing a BlackJack card game in JAVA.
After a few steps within the program, my whole computer system slows down/stutters and some areas within the JFrame turn black. No repainting seems te be happening.
I will give you some program details in words rather then submitting the code.
I have done some extensive extending of almost every GUI component to give it the look and feel that I want. Almost every child of JComponent that I use has got its paintComponent rewriten with custom image backgrounds and anti-aliasing where applicable.
In my (custom) JFrame I load an extended version of JPanel. This panel holds all the GUI components for that screen. When I want to switch screen (go to a different part of the program), I switch to another extended version of JPanel. I do this by removing all elements from the JFrame and add the new panel. These different panels implements ActionListeners and FocusListeners.
At this point my thoughts are leaning towards a thread handling issue. My theory for the moment is this: When a panel is constructed for display in the JFrame (each on different stages within te program), the previous constructed panels aren't realy 'destroyed', and the Listeners of those panels remain active.
My question for you people is, wether this theory holds ground... And in that case, is there a way to 'kill' these panels or at least stop the listening?
If my theory doesn't make sense, what else could be causing these symptoms? Could it be the extensive overwriting of the paintComponent methods?
Any ideas would be highly appriciated!
Regards Wilco
When a panel is constructed for display in the JFrame (each on different stages within te program), the previous constructed panels aren't realy 'destroyed', and the Listeners of those panels remain active.
No. Events are only dispatched to the component that has focus. It a comonents doesn't have focus then it won't received system generated events like KeyEvents and MouseEvents. So if a panel isn't visible then it won't receive events.
I switch to another extended version of JPanel. I do this by removing all elements from the JFrame and add the new panel.
This is not the best design. It is better to use a Card Layout which was designed for this purpose.
Almost every child of JComponent that I use has got its paintComponent rewriten with custom image backgrounds and anti-aliasing where applicable
Then you probably have problems with your custom painting. What happens when you just use the standard components without custom painting?
It is a bit strange for me but JPanel does not generate MouseEvents when cursor is on child components: JTextField and JToolBar but it generates MouseEvents when cursor is on JLabel. Could someone explaind me why? Is there any way to force JPanel to generate events even if mouse is on child components?
The event dispatcher will forward mouse events to the listeners registered to the component that is returned by the package-level getMouseEventTarget method in Container. This will be called on your JFrame, and, as the JavaDoc indicates, it:
Fetchs the top-most (deepest) lightweight component that is interested in receiving mouse events.
The event dispatcher then takes this top-most component (your JTextField, for example) and sends events to all of its listeners only. They do this in order to avoid having to broadcast these events to all of the components that may be layered within a Swing container. MouseEvents, as you can imagine, are very chatty, what with all of the mouseEntered, mouseDragged, and mouseMoved events that are dispatched for all of the MouseListener and MouseMotionListener implementations potentially out there. The processing to find all listeners and then fire events to all of them in the hierarchy would be time consuming.
The assumption is also that for classes like JTextField and JButton, etc., the default mouse handling is all that one would need. If you want to handle mouse actions differently (ie, changing color on a mouseEntered/mouseExited), you can add a MouseListener to these widgets as you need to.
For your processing, I would suggest simply adding your JPanel as a MouseListener to your top level components if you need to handled these events.
you may want to have the child components (JTextField, JToolBar, etc) listen for the mouse events from the jpanel and/or forward the mouse events to the child components.
Could someone explain why?
Component mouse events are handled by processMouseEvent(), which says
Mouse events are enabled when one of the following occurs:
A MouseListener object is registered via addMouseListener.
Mouse events are enabled via enableEvents.
You can use getMouseListeners() to see the difference.