I am making a card game with a java applet. I have a class that extends JApplet. Now I am trying to draw 104 images on applet, but when I drag one image and move, my entire applet is blinking. Throughout the execution of my program, I am calling the repaint method in mousedragged and mousepressed, because it is required to repaint the image on the applet after dragging it.
I know my paint method is running every time I drag a card and move the mouse across the screen, and that's why my 104 cards redraw on applet every time. I think this is the reason for blinking in my applet.
I have tried many times but not solving. How can I prevent this blinking?
Look into double buffering and BufferStrategy.
Once upon a time you'd do it yourself by painting to an offscreen image then drawing the offscreen image to your applet in a single go - but these days you can use BufferStrategy. Here's a tutorial on how to do it the old fashioned way. BufferStrategy javadoc shows you how to use the new way.
Related
I am developing an image editor capable of drawing ovals on an image. I am able to successfully add an image into a JScrollPane and draw on it using the fillOval() function. But each and every time I move the scroll bar all the drawn ovals disappear. Since the image to be uploaded is often large in size scroll bars cannot be disabled. I have incorporated the image in a JLabel. Please help.
I am able to successfully add an image into a JScrollPane and draw on it using the fillOval() function. But each and every time I move the scroll bar all the drawn ovals disappear.
This suggests to me that you're not drawing correctly. Since you've not shown us how you're drawing, we can only guess, but perhaps you're calling getGraphics() on a component and using an unstable Graphics instance. If so, you'll be better off calling getGraphics() on a BufferedImage itself, and drawing on it. Either that or drawing in the paintComponent method of your JComponent.
If this doesn't help, please provide more information on exactly what you're doing, preferably by creating and posting a Minimal, Complete, and Verifiable Example Program. We don't want to see your whole program, but rather you should condense your code into the smallest bit that still compiles, has no extra code that's not relevant to your problem, but still demonstrates your problem.
i've got a question about drawing animations in Java (SWT).
I try to draw an animation of some process.
When i use canvas.redraw() program firstly erases everything that has been drawn and then draws again.
My program draws about 1000 of rectangles per time step (this big quantity is necessary) so animation doesn't looks smooth - it blinks all the time.
Is there a way to make it look smoother, for example to paint new objects over old ones, without erasing them (that would look better anyway)?
The solution for flickering when doing custom painting is to use double buffering. The SWT Canvas object has built-in double-buffering, use it by adding the flag to the styles in the constructor:
Canvas myCanvas = new Canvas (parentComposite, SWT.DOUBLE_BUFFERED);
I am currently making a path-laying Tile game in Java where I am using a JLayeredPane with multiple layers. The game runs fine, but everytime the repaint method is called, the entire pane flickers.
Right now I have the game running on a timer where every tick automatically moves the character one tile at a time along the path in which I have laid out. Naturally, I would need to update the screen in order to reflect the changes to the user, but the problem is that the repaint method forces a redraw on all layers of the LayeredPane. Every tick would cause a flicker on the map area of the screen. While it is bearable, I would just like to get rid of it so it looks nicer.
I have researched on the use of double buffering and have even set the option to double buffer the pane to true as well (e.g. pane.setDoubleBuffered(true)), but have had no luck with various implementations. Is there a way to just draw the entire pane with all layers for every tick in an outside buffer, then copy it in one go over to the main screen?
Thank you
I am making a game in Java. Basically, I have two different "planes" of updating that I need to take care of the. The base layer is the actual game painting itself. It is simply a JPanel that covers the entire JFrame, and is drawn to using its Graphics object.
I use a fixed timestep to take care of these first graphical updates. I have overwritten the paintComponent() method to do absolutely nothing, as I have written a custom render(float interpolation) method that takes care of that, as to prevent unwanted updates.
However, this panel can take no input beyond primitive mouse clicks and keyboard input. I need the ability to create various menus, text boxes, etc, that are also on the screen. Like various abilities, or even the "Menu" button that usually appears in the upper left corner of most games.
To take care of that input, such as creating buttons, I have a second JPanel that has setOpaque(false) applied to it. Then I create various Swing components that I might need, such as a JButton.
To contain the two JPanels, I use a JLayeredPane, and set their layers appropriately, as seen below. This way the input layer should always be on top of the actual game layer.
The code below shows how I create and add the Swing components to each other. addLoginDialog() is a method that adds a Swing component for the login. It has been tested and works properly, and isn't the problem.
private void initComponents()
{
//This code is inside of the JFrame
wholePane = new JLayeredPane();
add(wholePane);
guiPanel = new GUIPanel();
guiPanel.setOpaque(false);
gamePanel = new RPGPanel();
gamePanel.setOpaque(false);
wholePane.add(gamePanel, JLayeredPane.DEFAULT_LAYER);
wholePane.add(guiPanel, JLayeredPane.POPUP_LAYER);
guiPanel.addLoginDialog();
}
So when I run the code, I get horrible flickering. This is the code that is run from my fixed timestep ~60 times per second.
public void handleRepaint()
{
//I don't use repaint() for the game drawing so I can be sure that fps is controlled.
Graphics g = gamePanel.getGraphics();
gamePanel.render(g);
g.dispose();
wholePane.repaint();
}
The problem is, I think, that the two different systems of updating the screen are clashing. The standard paintComponent() system is great for more static screens, but when I need to update consistently and keep track of the fps, I can't have updates going off randomly.
However, for the input layer, I only want to update as Swing normally does. When the mouse moves over a button, when I component is moved or is resized, etc.
Also, note the way the screen flickers: The Background image goes blank and then comes back again repeatedly. The input panel is always there, but is actually painted behind the game drawing, which shouldn't happen, because it is put in the default layer. The reason I know it isn't completely disappearing is because the game painting is partially transparent, so I can see underneath it, and the buttons I added are still there.
My main question is, how can I stop the flickering? Why is the game drawing being drawn on top of the input components when the game drawing is being done on the Panel that is in a lower layer in the JLayeredPane? And I supposed most importantly, what is causing the flickering? Thank you for any help.
Why is the game drawing being drawn on top of the input components
when the game drawing is being done on the Panel that is in a lower
layer in the JLayeredPane?
Mostly because you've circumvented how Swing works.
Let's start with the fact that the Graphics context is a shared resource (typically there is a single Graphics context per native peer), that is, every component gets the same context, this means, when you use your own painting routine, you are basically painting over every thing else.
The RepaintManager is responsible for making decisions about what and when something should be painted. So what you now have is two artist fighting over the same canvas, wanting to paint on it simultaneously, which is just making a mess.
Add into the fray that Swing's painting process is not thread safe and you end up with a complete mess.
If you absolutely must have control, then you need to remove Swing's painting engine from the equation.
Start by taking a look at Passive vs. Active Rendering
ps- There is also hard ware acceleration benefits to using a BufferStrategy
I have a program that bounces an arbitrary number of balls around a predefined window. It relies on a Swing Timer to update the balls according to a delay set by the user. My problem is this: the balls lag much more than they should under modest circumstances. The weird thing is that the balls move smoothly if there is another action being performed (e.g. mouse click or mouse moving around the screen). Does anyone know what would cause this?
The weird thing is that the balls move smoothly if there is another action being performed (e.g. mouse click or mouse moving around the screen).
Based on that statement, I would guess that your problem is not properly calling repaint() on JPanel or other java.awt.Component subclass which is displaying the balls. You need to call Component.repaint() whenever your code changes the position of the balls.
Not sure if this might help: have you considered double buffering? (that is doing all expensive paint operations in an 'off-image' and copying that image into the visible area when done).