1

There is this JFrame holding JComponent that being drawn 30 times a second. The problem appears to be with flashing or blinking effect when drawing the BufferedImage like it gets drawn on each other un-accordingly..

Also, There is a second problem wheres the Window constructor is executing really late, sometimes when the program actually need to use this object if EventQueue.invokeLater is applied, is it critical to have it there or leave it the way it is?

import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;

public class Window{

    private JFrame window;
    private CanvasComponent component;

    public Window(Input input){

        GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
        int hostMonitorWidth = gd.getDisplayMode().getWidth();
        int hostMonitorHeight = gd.getDisplayMode().getHeight();

        window = new JFrame();
        component = new CanvasComponent(hostMonitorWidth, hostMonitorHeight);

        window.setUndecorated(true);
        window.setBackground(new Color(0,0,0,200));
        window.setLayout(new GridLayout());
        window.setSize(hostMonitorWidth, hostMonitorHeight);
        window.getContentPane().add(component);

        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.setLocationRelativeTo(null);
        window.setVisible(true);
        window.requestFocus();
        window.setFocusableWindowState(true);

        window.addKeyListener(input);

    }

    public void draw(){
        component.draw();
    }

    private class CanvasComponent extends JComponent{

        public CanvasComponent(int hostMonitorWidth, int hostMonitorHeight){
            super.setSize(hostMonitorWidth, hostMonitorHeight);
            super.setBackground(new Color(0,0,0,0));
            super.setDoubleBuffered(true);
        }

        @Override
        public void paintComponent(Graphics g){
            super.paintComponent(g);
            if(GraphicsBatch == null) return;

            BufferedImage image = GraphicsBatch.getImage();
            g.drawImage(image,0,0,null);
        }

        public void draw(){
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    repaint();
                }});
        }
    }
}

Window.draw() is being called 30 times a sec.

Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132
homerun
  • 19,837
  • 15
  • 45
  • 70
  • 1
    Related answers and question: [Java: how to do double-buffering in Swing?](https://stackoverflow.com/questions/4430356/java-how-to-do-double-buffering-in-swing) You need to turn on double buffering. – Ferrybig Feb 12 '16 at 14:48
  • @Ferrybig i have already tried `setDoubleBuffered(true)` but it has no effect, how else can i apply double buffering? – homerun Feb 12 '16 at 14:54
  • Can we see the source of `GraphicsBatch.getImage();`? How are the images generated in here? (Cached image, Image from network, image loaded from file, etc) – Ferrybig Feb 12 '16 at 14:57
  • 1
    Set the `ImageObserver` from `null` to `this`, and consider making a member variable for your image and initializing it in the constructor; you can use this variable in `g.drawImage` so that you don't unnecessarily create and load another image each time `paintComponent` is executed. – TNT Feb 12 '16 at 15:03
  • 1
    `Window.draw()` _is being called 30 times a sec_. Where? On the [event dispatch thread](https://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html)? – trashgod Feb 12 '16 at 16:07
  • @Ferrybig Swing components are double buffered by default – MadProgrammer Feb 12 '16 at 20:42
  • @trashgod No. though on `CanvasComponent` it's in the EDT. However, i have tried running Window.draw() through the EDT and it has no effect. – homerun Feb 13 '16 at 15:26
  • @Ferrybig It's a class with buffered image and it's raster, nothing special. if it could help i can bring it on here. – homerun Feb 13 '16 at 15:27

0 Answers0