I am currently programming a gui with JavaFX 2.0, which is resizable. When the user resizes the window, a big rectangle resizes with it. Now I need to push the new boundaries of this rectangle on to an image which floats inside the rectangle and may not cross its borders.
I thought of updating the boundaries via a ChangeListener, but I don't want it to update the boundaries that often. The perfect solution would be a "ChangeIsOverListener" which updates the boundaries once at the end of a change.
Can anybody help me out?
Thanks in advance! :)
You may be able to trap mouse-down and mouse-up events on either side of the window resizing - but whether you see those events will depend on the AWT system and may depend on the O/S too.
Otherwise you will have to use a timer within the window sizing event to trip a separate event some number of ms after the last window sizing event, such that you consider the size to be "done" if it hasn't be changed in the last, say, 1/2 a second. The amount of time will be a compromise between the user's perceived lag and the number of resizes you want to process.
Maybe you could compare the size of the window every x milliseconds, and when it doesn't change in this time interval, you know that the change is over.
Related
I'm having a serious performance issue using a JLayer to do special drawing, but only under the AquaLookAndFeel on Macintosh. Using any other look and feel, the performance is fine.
Here's the scoop:
I have a test case that blurs the main window when a child dialog pops up above it. On most L&Fs it works fine. On Aqua, it takes five seconds to draw, and the screen is frozen the whole time. I can press OK to dismiss the dialog, but it doesn't respond until it's done drawing. And the reason it takes so long to draw is because Aqua is firing multiple paint events. For every component that might change its visual state, it fires a paint event. So it redraws the entire window, using the blur effect, once for each of the twelve JButtons or Checkboxes in the window. The blur effect takes about one third of a second to draw, but it takes about 5 seconds with all the repaints.
Under any other look and feel, only two paint events are fired, so the performance is acceptable.
To see this in action, run the test case at https://github.com/SwingGuy1024/Bugs/blob/main/AquaPaintBug.java
It lets you try it under different looks-and-feels. It runs fine on all but Aqua.
Has anyone else seen this? Does anyone know of a workaround? Is this a bug in Aqua, or am I missing something? If I can't use JLayer to enhance the drawing of a component, the JLayer is useless for drawing.
Note: I think this is partly caused by a PropertyChangeListener that gets set by the AquaRootPaneUI class, on a property called AquaFocusHandler.FRAME_ACTIVE_PROPERTY, which is defined as "Frame.active". This seems to get activated when the window's active state changes, which is what happens when a dialog opens up. This explains why it repaints all the JCheckBoxes, but doesn't explain why they each get a separate paint event.
How do I get the mouse position. I have tried:
int mouseX = MouseInfo.getPointerInfo().getLocation().x;
int mouseY = MouseInfo.getPointerInfo().getLocation().y;
But that does it for the whole screen. Anyway to do it relative to the JPanel/JFrame
If I'm only using Graphics JFrame and JPanel that is being repainted every millisecond, should I have buffers? Or will it be fine?
How do I add a mouseAcionEvent only to the frame so it gets X() and Y() of mouse but only in frame?
Use a MouseListener instead of MouseInfo. MouseListener will trigger events which are contextual to the component which raised them, which means you won't need to translate the events into the component space as the event will already be converted to within the component context.
See How to write a mouse listener for more details
How should I update my game rePaint() every millisecond or another way?
Use a javax.swing.Timer...
See How to use Swing Timers for more details...
Should I use buffers?
That will depend. Swing components are already double buffered, but if you use a more complex timing mechanism (AKA game loop), you might find it useful, even to roll your own.
I, personally, would start simple
How can I improve the way I thought out my code in the first place? Is it right having 10 loops or only all in 1 to reduce lag ect.
There are probably lots of things, but start with broader idea...
Breakdown entities to their own responsibilities, for example, the player should know where it is and how it should be painted. It could even know how it's suppose to move based on the current state of the game. This way you could create any number of entities, all with there own set of rules which are isolated and easily updated.
Devise a controller mechanism which is responsible for taking in keyboard and mouse events and simply updating the current state of the game model. That is, rather than going "the user pressed the 'left' key, move player to the left", it would simply raise a flag in the game model that the "left" state has been triggered (or untriggered) and the engine would, on the next update loop, ensure that each entity knew about the change
Don't use magic or hard coded numbers, instead provide some kind of ability to scale the scene. For example, you could decide what is shown on the screen based on the size of the window...
Apparently, my Java teacher at school doesn't know that the mouseMooved and mouseDragged events activate every few milliseconds. I had to find that myself while exercising events.
I am trying to make an applet in which you can draw stuff. Currently I can draw with a small filled circle. When I move the mouse too fast, big dots appear get drawn, instead of lines. That's because the mouseDragged event gets called every few milliseconds. I want to make the two events to get called EVERY time when the coordinates of the mouse change, no matter the speed.
I have no idea how to do that. Nor I know if the proper solution is by decreasing the interval between every capture, after overriding a certain method.
How can I capture the coordinates of the mouse's location absolutely every time they change?
EDIT:
Apparently I can't make the applet capture the coordinates every time they change. Can I decrease the time between the captures (can I increase the speed of capturing) somehow?
I've seen several applications window's only allow the user to resize it in the diagonal direction, so it must maintain its square shape.
Is it possible to specify this constrain using swing/java?
I haven't heard of anything built in to do that. You could add a componentListener and from the resize events in that trigger resizes of the window to keep it square.
Personally, I would attach a ComponentListener to the window and in the componentResized method check the new window size and set the width equal to the height or vice versa.
Probably not the most efficient way though...
You should be able to modify the resize event handlers to increase both dimensions rather than just the one.
Resizing of a JFrame is handled by the OS, so it will be difficult to control unless you use a ComponentListener as suggested by all the other answers.
However, if you are talking about a JWindow, then resizing is NOT supported automatically and you need to provide support for this. Resizing Components entry might help you get started. I think you would need to make two changes:
a) limit the dragging to the diagonals
b) change the "drag distance" to be the maximum of the width/height drag distance and use that value for both future calculations.
Since I don't know if this is your real requirement, I won't go into any more detail.
How would I go about writing my own scrollbar using standard Java 2D.
I really don't want to use swing, and I've already made up my own component parts for everything else such as buttons etc.
I'm not really looking for code, rather the math involved in the event changes and the drawing.
Why on earth would you want to write your own java GUI toolkit? You already have the choice of Swing and SWT, can you really do better than these two teams?
If you've already written the rest of the toolkit, I don't understand why the scrollbar would stump you. Without knowing anything about your event system, or how your custom components are structured, it's impossible to give much advise. I don't see this being particularly maths intensive - just maintain the height of the scrollable component, and the view it's in, and the scrollbar size should match the proportion of the component that is visible. The position of the scrollbar should match which part of the component is visible (this will have to be scaled). Specifically, what do you want to know?
Java is now open. I'd go look at the source for the Swing and/or SWT as they are already implemented. The math seems fairly straight forward. You have a Bar and a Container. To simplify we will only discuss length (the dimension in which the scrollbar moves). The container is of a certain length. The bar is of a length that is equal to or less than the container. It is useful to define the center and the two endpoints of the scrollbar. You can have the scrollbar start at 0 at the top and 1 at the bottom or 0 at the top and 100 at the bottom with the important part being defining your scrollbar in the same manner. Then you can check the endpoints for collision with the edge to stop the bar from moving. If the mouse is held down with the cursor over the coordinates inside the bar, the bar starts caring about where the cursor is and will paint the scrollbar and whatever the scrollbar is ultimately supposed to be affecting. So, you would take the page to be affected and map it to 0 and 1 * the scale in pixels of the scrollbar. Then you get to worry about the arrows at either end and how big of a jump each click is and dealing with mousedown events etc.etc. Use what is given don't reinvent the wheel.
While not Java2D, this straightforward code snippet might help:
http://processing.org/learning/topics/scrollbar.html