How to render custom JTable cell in background? - java

Suppose my custom rendering takes long time. By what means can I render cells in background? Probably I need to receive event when some cell becomes visible, then render it in separate thread, then actually paint.
How to accomplish this?
UPDATE
I know the render should be fast. But it does not in my case. So, I need extra layer between presentation and model, which will contain some sort of cache. For example, images of prerendered cells. The question is about how to hook this layer to the object.

A render should be as fast as possible. A render should't do complex computation, just paint the model, not calculate it every time.
Renders are called from EDT (Event Dispatch Thread), and I think, without more information, that maybe you should calculate the model in a separate thread, and the render just paint the model in the EDT.
If the model is still not available, you could disable the component for example.
Post the code for more precise solution please.

Related

Drawing frequently updated Graphics inside a complex Swing UI without blocking Event Dispatch Thread

I'm developing a plugin for an old application that uses the Swing UI toolkit. As far as I know, Swing's philosophy is that everything executes on the Event Dispatch Thread. I need to integrate a JPanel where it repaint()s itself every 16ms.
I think this will cause the EDT to be flooded with redrawing that JPanel and making other events wait longer, (mentioned in the Javadocs) which could slow down the app. I'm already seeing slowdowns in a test instance of the application.
The way I see it now there are 2 solutions:
Render everything to an image, then render that to the screen, this way, long computations can be rendered by a background thread and the EDT takes care of drawing a simple image, reducing latency.
Make repaint calls only when the user is actually doing something.
What is a performant way to draw dynamic, frequently-updated content inside a Swing UI without blocking the EDT and the rest of the UI?
The animation, processing changes painting complex modelling objects on a Graphics/Graphics2D can indeed be separated. Whether SwingWorker, SwingTimer, event driven.
You can use a BuffferedImage with getGraphics and at the end of Graphics2D drawing do a disposeGraphics. Take a compatible image type as the Graphics of the screen.
Then the actual painting will just do a drawImage in the paintComponent update event handling.
Log processing times, and repaints - for optimization. This profiling is crucial to knowing performance bottlenecks.
Often costly things can be improved. Like using affine transformations, preloaded images of course, and so on. Like doing light-weight drawing instead of tiny JComponent hierarchies. Like pruning invisible parts.

How to repaint only dirty region in Swing?

Does repainting dirty region only improve performance?
If the answer is yes, how to do it?
Originally I use repaint() to call paintComponent(Graphics); however, recently I aware that repaint() is actually repaint(0,0,width,height), which repaints everything each time. If I use repaint() with parameters to specify the dirty region, in what way will it pass such data to paintComponent(Graphics)?
If I use repaint() with parameters to specify the dirty region, in what way will it pass such data to paintComponent(Graphics)?
The "clip bounds" or the Graphics object will be set to the specified region
1.Does repainting dirty region only improve performance?
Why? Do you have a painting problem. Don't micro optimize the code, unless you have a reason to do so. The code will be harder to maintain and debug. You will be adding extra logic to determine which regions need to be repainted.
Also, remember that multiple repaint requests get merged into a single request. So if you make a request to repaint the top/left corner of a component and the immediately request a repaint of the bottom/right, these two request will be merged into an area that includes both regions, which means the entire component will be repainted. So you have done extra work for nothing.
To repaint only "dirty" regions of a large JComponent you will need to use the RepaintManager. You can get the current RepaintManager with:
RepaintManager rm = RepaintManager.currentManager(component);
You can even replace the RepaintManager with your own custom version. Additional details can be found on Oracle's website.

Split game loop and render in JavaFX simulation

I'm running a game/simulation on JavaFX and when I started it seemed reasonable to add an AnimationTimer to perform the tick updates. My Entity's are composed of a Polygon that holds their shape and position. I added the Polygon's to the scene via a Group and everything renders like magic. However, since it's an simulation, I now want to run millions of ticks with no rendering, to advance to the future and see the results. The problem is, since my Entity's (x,y) positions are inside the Polygon, every time handle() is called in the animation, it seems that the screen is updated.
What is the proper way to split the game loop and render, to be able to call render only after some amount of ticks?
I thought of creating my own MyPolygon class to hold the simulation data, and then when the time comes to draw, create on the fly one Polygon per Entity, but that seems also overkill for me (but maybe I'm wrong).
Also, I'm not sure how to change the ticks per second rate on the AnimationTimer. So I'm not sure it is suited for this specific need.
It seems like a very simple design choice, so there has to be a proper way to do it with JavaFX...

Integrating logic into paintComponent

I am currently studying Swing and have hit a mental roadblock. I know when I want to paint to a JPanel I need to call the paintComponent method. I have read several places that logic should not be located within your paintComponent block. If I want a timer to determine when something is painted, would I not have to call paintComponent from another method of another class and create an instance of that class that also extends JPanel within the paintComponent?
I think what I am trying to avoid is the following...
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawImage(blah,blah,blah);
if(timesUP==true){
paintSomethingElse(g);
}
repaint();
}
Instead I get the impression I should be creating a completely different method for the logic of the if statement and somehow paint from a separate method.
What am I not understanding?
Has this already been specifically answered? I was unable to find an answer that helped me really understand how to separate the two efficiently allowing multiple graphics to be drawn on the same JPanel.
It depends. If the logic is related to the actual painting process, there's no reason why you couldn't put it into the paintComponent method.
What you want to avoid is putting logic in the paintComponent that changes the state of the paint process, as paintComponent could be called for any number of reasons, many of which you don't have control over.
The paintComponent method should paint the current state of the component, that's all, it should not be involved in changing or updating that state (this could actually lead to an infinite repaint loop which will consume your CPU cycles)
I have also had to make a Java Swing application which had a lot of painting to do - the JPanel had to paint multiple custom components which moved around on the screen as the user interacted with them.
The paintComponent method is there for drawing and that should be the end of it. Conditional painting is, from my side, doable in the paintComponent as long as you are not waiting for conditions, setting states of other objects or anything which might on the one hand slow you down a lot and on the other send you into waiting for ever. I call the logic here reaction logic.
On the other hand, don't forget that the repainting can be triggered externally, any time you might need it. This way you can separate the logic from painting to some extent. Use listeners, create your own events, but keep action logic out of the paintComponent. You can easily find a way to set states before entering the painting, so that when you decide to paint, you only react to the state.
Don't forget: if you are multi-threading, painting might get messy if you work on half-set states of objects. Thread carefully!
If the logic is very complex and may be too slow for calling from inside the paintComponent (all GUI of your app is stalled while this method is running), you should define a separate update method to prepare precomputed boolean flags, coordinates, images and other values that paintComponent could use to produce the final view quickly enough.
Such update method can run in a separate thread. You should call repaint() or (if layout may change) invalidate() at the end of this method. Use a separate object for all prepared values and make sure that painting thread and updating thread do not access the same instance a once.
If the logic is fast enough, I see no problem in defining it inside the paintComponent method. If the logic is complex but still fast enough, define it in some methods that are called from paintComponent directly.

How to get mouse position and buffer?

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...

Categories

Resources