Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7594735
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 30, 20262026-05-30T21:29:41+00:00 2026-05-30T21:29:41+00:00

i just started using double buffering and everything worked just fine until i wanted

  • 0

i just started using double buffering and everything worked just fine until i wanted to add a JScrollPane to the screen so i later on can do some camera movements. Everything shows up fine (my sprites) EXCEPT the ScrollBars of the JScrollPane. And i want them to be shown!

However if i resize the window, the scrollbars flicker, so i know they are there! I can even use them if i’m fast enough. How come they dont show up at rendering? 🙁

Here is a SSCCE of the problem:

public class BufferStrategyDemo extends JFrame
{
    private BufferStrategy bufferStrategy;
    private JPanel gameField;
    private JScrollPane scroll;

    public BufferStrategyDemo()
    {

        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        
        this.getContentPane().setPreferredSize(new Dimension(800, 600));
        this.pack();
        this.createBufferStrategy(2);

        this.gameField = new JPanel();
        this.gameField.setPreferredSize(new Dimension( 1400, 600 ));

        this.scroll = new JScrollPane( gameField );
        this.add( scroll, BorderLayout.CENTER );

        this.setVisible( true );
        this.bufferStrategy = this.getBufferStrategy();

        setupGameFieldContent();

        new Renderer( this, scroll , bufferStrategy ).start();
    }

    // Add some contents to gameField that shows up fine
    private void setupGameFieldContent()
    {
        // For ( all my sprites )
        //      gameField.add( sprite );

    }

    private class Renderer extends Thread
    {
        private BufferStrategy bufferStrategy;
        private JFrame window;
        private JScrollPane scroll;
        private Image imageOfGameField;

        public Renderer( JFrame window, JScrollPane scroll, BufferStrategy bufferStrategy )
        {
            this.bufferStrategy = bufferStrategy;
            this.window = window;
            this.scroll = scroll;
        }

        public void run()
        {
            while ( true )
            {
                Graphics g = null;
                try 
                {
                    g = bufferStrategy.getDrawGraphics();
                    drawSprites(g);
                } 
                finally { g.dispose(); }

                bufferStrategy.show(); // Shows everything except the scrollbars..
                Toolkit.getDefaultToolkit().sync(); 

                try { Thread.sleep( 1000/60 ) ; } 
                catch(InterruptedException ie) {}
            }
        }

        private void drawSprites( Graphics g )
        {
            Graphics2D g2d=(Graphics2D)g;

            //Also tried using the JPanels (gameField) createImage with same result
            imageOfGameField = this.scroll.createImage(800, 600 ); 
            Graphics screen = (Graphics2D)imageOfGameField.getGraphics();

            /**
             * For all my sprites, draw on the image
            for ( Sprite current : sprites )
                screen.drawImage( current.getImage(), current.getX(), current.getY(), current.getWidth() , current.getHeight(), null);
            */

            g2d.drawImage( imageOfGameField, 0, 0 , null );

        }
    }
}
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-30T21:29:42+00:00Added an answer on May 30, 2026 at 9:29 pm

    Drawing is performed on whole frame area, not on gameField. Actually, the only cause of temporary JScrollPane appearing is that it calls paintImmediately somewhere in mouse-drag handler.

    The first thing that comes to mind is to replace JPanel with Canvas, as I_Love_Thinking wrote, then get bufferStategy from that canvas instance and use it for rendering. But unfortunately it not works as expected. Lightweight JScrollPane can’t properly drive heavyweight Canvas. Canvas refuses to draw content outside area (0, 0, viewport_width, viewport_height). This is known bug and it will not fixed. Mixing mixing heavyweight components with lightweight is bad idea.

    Replacing JScrollPane with heavyweight ScrollPane seems working. Almost. There are noticeable rendering artifacts on scroll bars under some circumstances.

    At this point, I’ve decided to stop beating the wall and give up. Scroll panes are the source of numerous problems and not worth to use for lazy scrolling. It is time to look on scrolling from another view. The Canvas is not game field itself, but window that we use to observe game world. This is well-known rendering strategy in gamedev. The size of canvas is exactly as observable area. When scrolling needed, we just render the world with some offset. The value for offset may be taken from some external scrollbar.

    I suggest next changes:

    1. Throw away JScrollPane
    2. Add canvas directly to frame.
    3. Add single horizontal JScrollBar under canvas.
    4. Use value of scrollbar to shift rendering.

    The example is based on your code. This implementation not respects resizing of frame. In real life some places need to be synchronized with size of viewport (that what scrollpane did before for us). Also, example violates Swing threading rules and reads value of scrollbar from rendering thread.

    import java.awt.BorderLayout;
    import java.awt.Canvas;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Toolkit;
    import java.awt.image.BufferStrategy;
    import java.awt.image.BufferedImage;
    
    import javax.swing.JFrame;
    import javax.swing.JScrollBar;
    
    public class BufferStrategyDemo extends JFrame {
        private BufferStrategy bufferStrategy;
        private Canvas gameField;
        private JScrollBar scroll;
    
        public BufferStrategyDemo() {
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            getContentPane().setLayout(new BorderLayout());
            getContentPane().setPreferredSize(new Dimension(800, 600));
    
            gameField = new Canvas();
            gameField.setIgnoreRepaint(true);
            gameField.setPreferredSize(new Dimension(800, 580));
            getContentPane().add(gameField, BorderLayout.CENTER);
    
            scroll = new JScrollBar(JScrollBar.HORIZONTAL);
            scroll.setPreferredSize(new Dimension(800, 20));
            scroll.setMaximum(1400 - 800); // image width - viewport width
            getContentPane().add(scroll, BorderLayout.SOUTH);
    
            this.pack();
    
            gameField.createBufferStrategy(2);
            bufferStrategy = gameField.getBufferStrategy();
    
            new Renderer().start();
        }
    
        private class Renderer extends Thread {
            private BufferedImage imageOfGameField;
    
            public Renderer() {
                // NOTE: image size is fixed now, but better to bind image size to the size of viewport
                imageOfGameField = new BufferedImage(1400, 580, BufferedImage.TYPE_INT_ARGB);
            }
    
            public void run() {
                while (true) {
                    Graphics g = null;
                    try {
                        g = bufferStrategy.getDrawGraphics();
                        drawSprites(g);
                    } finally {
                        g.dispose();
                    }
    
                    bufferStrategy.show(); 
                    Toolkit.getDefaultToolkit().sync();
    
                    try {
                        Thread.sleep(1000 / 60);
                    } catch (InterruptedException ie) {
                    }
                }
            }
    
            private void drawSprites(Graphics g) {
                Graphics2D g2d = (Graphics2D) g;
    
                Graphics g2d2 = imageOfGameField.createGraphics();
                g2d2.setColor(Color.YELLOW); // clear background
                g2d2.fillRect(0, 0, 1400, 580); // again, fixed width/height only for SSCCE
                g2d2.setColor(Color.BLACK);
    
                int shift = -scroll.getValue(); // here it is - get shift value
    
                g2d2.fillRect(100 + shift, 100, 20, 20); // i am ugly black sprite
                g2d2.fillRect(900 + shift, 100, 20, 20); // i am other black sprite
                                                         // located outside of default view
    
                g2d.drawImage(imageOfGameField, 0, 0, null);
                
                g2d2.dispose();
            }
        }
        
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
                public void run() {
                    BufferStrategyDemo mf = new BufferStrategyDemo();
                    mf.setVisible(true);
                }
            });
        }
    }
    

    And another example, mostly based on code from Java Games: Active Rendering article. It properly synchronized with value of JScrollBar and size of Canvas. Also, it does painting directly to Graphics, obtained from BufferStrategy instance (instead of intermediate BuffereImage object). The result is something like this:

    Active Rendering Demo

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Have just started using Google Chrome , and noticed in parts of our site,
Have just started using Visual Studio Professional's built-in unit testing features, which as I
I just started using GNU Emacs as my text editor and I am concerned
I just started using the WPF WebBrowser that is included in Net 3.5 SP1.
I just started using SVN, and I have a cache directory that I don't
I just started using CCNet, and in the process of getting my build projects
I just started using TestDriven.NET to debug on my tests, here is my setup
I just started using jqModal as I need support for nested modals. I'm noticing
I just started using git with github. I followed their instructions and ran into
I just started using the MVCContrib grid in a test project. I'm having a

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.