Flickering occurs when Active Rendering with JPanel, not sure why as I've done this before (couldn't find source code of that project however).

Relevant Code:

Graphics g = projectDCWindow.getWindowGraphics(); // Gets the Graphics Object from a JFrame

g.setColor(Color.BLACK);
g.fillRect(0, 0, (int) ProjectDCInfo.getDefaultWindowSize().getWidth(), (int) ProjectDCInfo.getDefaultWindowSize().getHeight()); // Clears the screen

projectDCGSM.get().render(g); // Game State Manager which simply draws to the Graphics Object

g.dispose();

This is where I draw to the Graphics Object, drawX and drawY are being updated

g.setColor(Color.BLUE);
g.fillRect(drawX, drawY, 100, 200);

The JFrame Code

private JFrame projectDCWindow;

protected ProjectDCWindow()
{
    projectDCWindow = new JFrame(WINDOW_TITLE);

    projectDCWindow.setPreferredSize(getDefaultWindowSize());
    projectDCWindow.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

    projectDCWindow.addWindowListener(new WindowAdapter()
    {
        @Override
        public void windowClosing(WindowEvent e)
        {
            ProjectDC.getInstance().requestClose();
        }
    });

    projectDCWindow.addComponentListener(new ComponentAdapter()
    {
        @Override
        public void componentResized(ComponentEvent e)
        {
            onResize(projectDCWindow.getWidth(), projectDCWindow.getHeight());
        }
    });

    projectDCWindow.pack();
    projectDCWindow.setLocationRelativeTo(null);
    projectDCWindow.setVisible(true);
}

private void onResize(int newWidth, int newHeight)
{
    ProjectDCInfo.setWindowSize(newWidth, newHeight);
}

public Graphics getWindowGraphics()
{
    return projectDCWindow.getGraphics();
}

Recommended Answers

All 8 Replies

Doing a getGraphics and drawing to that will never work. You have to cooperate with Swing's double buffering. The ONLY way to draw in Swing is to override paintComponent.
I would post you an example, but I'm away from my usual machine right now. There's an article on Oracle's site about painting in AWT and swing that explains the right way to do it.
http://www.oracle.com/technetwork/java/painting-140037.html#swing

Yeah, I'm not sure how to do it based on reading most of the link you provided. Would you be able to whip up a quick example?

I did it before without a Timer, but I don't remember how.

Maybe this link will remind you of when you last helped me? DaniWeb Thread

You definitely should use a timer

Using a Timer will limit Updates/Frames or both... I'd rather not use a Timer if I really don't need to, which I don't believe I do

The only way to paint is by overriding paintComponent etc
You have no direct control over how often or when paintComponent will be called - it may be triggered by window activity, it may coalesce paints if it's busy etc

For smooth movement it's essential that the underlying model updates at regular intervals, regardless of screen updates.

So you update the model in its own thread at regular intervals at least as fast as your desired fastest frame rate.
After each model update you request a screen update, and Swing will do its best. If it can't keep up it will coalesce consecutive points, but the movement will still look steady. Given two or more CPUs you will be running at fastest rate your hardware can achieve.

The code to manage that is trivial, just a few lines. I've posted versions of it here a few times, but I can't access them from here.

J

Alright, FOUND MY CODE :DDDD
7.5m FPS :D

JPanel

private GameStateManager gameStateManager;

    public ProjectDCPanel()
    {
        setIgnoreRepaint(true);
        setDoubleBuffered(true);
    }

    @Override
    protected void paintComponent(Graphics g)
    {
        g.setColor(Color.BLACK);
        g.fillRect(0, 0, (int) ProjectDCInfo.getDefaultWindowSize().getWidth(), (int) ProjectDCInfo.getDefaultWindowSize().getHeight());

        gameStateManager.render(g);
    }

    public void setGameStateManager(GameStateManager gameStateManager)
    {
        this.gameStateManager = gameStateManager;
    }

Window Repaint Call

public void repaintPanel()
    {
        projectDCRenderingPanel.repaint();
    }

And just call repaintPanel from the rendering gameloop

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.