How to stop the auto-repaint() when I resize the J

2019-02-28 00:01发布

I am still learning Java, if someone can help me I will be very happy!

Sorry for bad english, I am spanish! I am making a tile game, the game uses the classic "game loop" that cap the engine at 60fps The loop sleep and then call repaint(); This works fine! But..

The problem is that repaint event is called when the JFrame is resized or maximized! For example when the JFrame is maximized/resized the game render at 10000fps but when they dont, the game render at the speed I set, so there is a way to disable Automatic repaint and make it work ONLY when the "component.repaint()" is called from my code?

The problem here is not the "game loop", the problem is that the repaint is called automatic when resize/maximized rendering the game at more fps!

public class Handling {
static private int fps=0;
static private int fpsfinal=0;
static int frames = 60;
static int frames_skip = 1000 / frames;
static long ticknext = GetTickCount();
static long ticksleep = 0;

public static void Run() {
    for(;;){
        Main.getDevice().repaint();
        fps++;
        ticknext += frames_skip;
        ticksleep = ticknext - GetTickCount();
        if(ticksleep >= 0) {
            try {
                Thread.sleep(ticksleep);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

public static long GetTickCount(){
    return System.currentTimeMillis();
}

public static int GetFPS(){
    fpsfinal=fps;
    fps=0;
    return fpsfinal-2;
}

import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.ImageObserver;

import javax.swing.*;
public class Game extends JPanel{
private static final long serialVersionUID = 1L;
static boolean dir=true;

@Override 
public void paintComponent(Graphics g){
    super.paintComponent(g);        
    int layout=Main.layout;
    Graphics2D g2d = (Graphics2D) g;
    g.setFont(Resources.GetFont(0));    
    Camera.UpdateCameraAxis();
    Camera.DoCamera();
    Cursor.MouseLoop(); 
    if (layout==0){
        this.setBackground(new Color(210,247,255));
        for(int xx=Math.max( etc....

2条回答
forever°为你锁心
2楼-- · 2019-02-28 00:47

so when the JFrame isn't maximized

I don't know why this would cause a problem since only one repaint request should be generated.

or (resizing)

I can see this being a problem since repaint will be invoked for every pixel you resize the frame by. In this case maybe you can use:

Toolkit.getDefaultToolkit().setDynamicLayout(false); 

Now the components will validated after resizing is complete.

this.setBackground(new Color(210,247,255));

Don't use code like the above since changing the background causes repaint() to be invoked which will invoke the paintComponent() method again. Painting methods are for painting only.

查看更多
Ridiculous、
3楼-- · 2019-02-28 00:47

"How to stop the auto-repaint() when I resize the Jframe"

Short answer, you don't control it. Longer answer, you need to make sure you aren't doing any thing that changes the state (you are using to paint), in the paintComponent method. For example:

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    Random random = new Random();
    int x = random.nextInt(100);
    int y = random.nextInt(100);
    int size = random.nextInt(100);
    g.drawRect(x, y, size, size);
}

What happens here is that every times the GUI repaints, which is not under your control, the rectangle will resize, without you wanting it to. So if you want the rectangle to only repaint when you tell it to, you need to make sure you only manipulate the state (i.e. x, y, size) from outside the paintComponent method, and only use that state to paint. Something like

Random random = new Random();
int x, y, size;
...
void reset() {
    x = random.nextInt(100);
    y = random.nextInt(100);
    size = random.nextInt(100);
}
...
Timer timer = new Timer(25, new ActionListener(){
    @Override
    public void actionPerformed(ActionEvent e) {
        reset();
        repaint();
    }
}).start();
...
@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);

    g.drawRect(x, y, size, size);
}
查看更多
登录 后发表回答