This discussion is archived
5 Replies Latest reply: Mar 26, 2010 5:14 AM by 794044 RSS

JButton flickering in fullscreen+unfocusable?

794044 Newbie
Currently Being Moderated
Hello,

I'm trying to make a fullscreen game, in this game I want to add JButtons on specified times. The problem now is that the JButton either flickers when I hover over it or doesn't even show...
Also when I click it (which works...) my program gets focused on the JButton, making it impossible to use my Keyboard Keys for my main purposes...

I use the following code to go fullscreen:
package snake;



/*
 *
 * Author = Man Ik Weet!
 */

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

public class ScreenManager {

    private GraphicsDevice vc;

    //here vc acces to monitor screen
    public ScreenManager() {
        GraphicsEnvironment e = GraphicsEnvironment.getLocalGraphicsEnvironment();
        vc = e.getDefaultScreenDevice();
    }

    //get all compatible DM
    public DisplayMode[] getCompatibleDisplayModes() {
        return vc.getDisplayModes();
    }

    //compares DM passing to vc DM and see if they match
    public DisplayMode findFirstCompatibleMode(DisplayMode modes[]) {
        DisplayMode goodModes[] = vc.getDisplayModes();
        for (int x = 0; x < modes.length; x++) {
            for (int y = 0; y < goodModes.length; y++) {
                if (displayModesMatch(modes[x], goodModes[y])) {
                    return modes[x];
                }
            }
        }
        return null;
    }

    //get current DM
    public DisplayMode getCurrentDisplayMode() {
        return vc.getDisplayMode();
    }

    //checks if two modes match eachother
    public boolean displayModesMatch(DisplayMode m1, DisplayMode m2) {
        if (m1.getWidth() != m2.getWidth() || m1.getHeight() != m2.getHeight()) {
            return false;
        }
        if (m1.getBitDepth() != DisplayMode.BIT_DEPTH_MULTI && m2.getBitDepth() != DisplayMode.BIT_DEPTH_MULTI && m1.getBitDepth() != m2.getBitDepth()) {
            return false;
        }
        if (m1.getRefreshRate() != DisplayMode.REFRESH_RATE_UNKNOWN && m2.getRefreshRate() != DisplayMode.REFRESH_RATE_UNKNOWN && m1.getRefreshRate() != m2.getRefreshRate()) {
            return false;
        }
        return true;
    }

    //make frame fullscreen
    public void setFullScreen(DisplayMode dm) {
        JFrame f = new JFrame();
        f.setUndecorated(true);
        f.setIgnoreRepaint(true);
        f.setResizable(false);
        f.setDefaultCloseOperation(f.EXIT_ON_CLOSE);
        vc.setFullScreenWindow(f);

        if (dm != null && vc.isDisplayChangeSupported()) {
            try {
                vc.setDisplayMode(dm);
            } catch (Exception ex) {
            }
        }
        f.createBufferStrategy(2);
    }

    //we will set Graphics object = to this
    public Graphics2D getGraphics() {
        Window w = vc.getFullScreenWindow();
        if (w != null) {
            BufferStrategy s = w.getBufferStrategy();
            return (Graphics2D) s.getDrawGraphics();
        } else {
            return null;
        }
    }

    //updates display
    public void update() {
        Window w = vc.getFullScreenWindow();
        if (w != null) {
            BufferStrategy s = w.getBufferStrategy();
            if (!s.contentsLost()) {
                s.show();
            }
        }
    }

    //returns full screen window
    public Window getFullScreenWindow() {
        return vc.getFullScreenWindow();
    }

    //get width of window
    public int getWidth() {
        Window w = vc.getFullScreenWindow();
        if (w != null) {
            return w.getWidth();
        } else {
            return 0;
        }
    }

    //get height of window
    public int getHeight() {
        Window w = vc.getFullScreenWindow();
        if (w != null) {
            return w.getHeight();
        } else {
            return 0;
        }
    }

    //get out of fullscreen
    public void restoreScreen() {
        Window w = vc.getFullScreenWindow();
        if (w != null) {
            w.dispose();
        }
        vc.setFullScreenWindow(null);
    }

    //create image compatible with your monitor
    public BufferedImage createCompatibleImage(int w, int h, int t) {
        Window win = vc.getFullScreenWindow();
        if(win!=null){
            GraphicsConfiguration gc = win.getGraphicsConfiguration();
            return gc.createCompatibleImage(w,h,t);
        }
        return null;
    }

    public void addComponent(Component comp){//stuff I tried myself... not really working...
        Window w = getFullScreenWindow();
        w.add(comp);
    }
}
The initialiser of it:
package snake;

/*
 *
 * Author = Man Ik Weet!
 */
import java.awt.*;

public abstract class Core {

    private static DisplayMode modes[] = {
        /*new DisplayMode(1024, 768, 32, 0),
        new DisplayMode(1024, 768, 24, 0),
        new DisplayMode(1024, 768, 16, 0),*/
        new DisplayMode(800, 600, 32, 0),
        new DisplayMode(800, 600, 24, 0),
        new DisplayMode(800, 600, 16, 0),/*
    new DisplayMode(640, 480, 32, 0),
    new DisplayMode(640, 480, 24, 0),
    new DisplayMode(640, 480, 16, 0)*/};
    private boolean running;
    protected ScreenManager s;
    private int FPStimeToSleep = 1000 / 50;

    //stop method
    public void stop() {
        running = false;
    }

    //call init and gameloop
    public void run() {
        try {
            init();
            gameLoop();
        } finally {
            s.restoreScreen();
        }
    }

    //set to full screen
    public void init() {
        s = new ScreenManager();
        DisplayMode dm = s.findFirstCompatibleMode(modes);
        s.setFullScreen(dm);

        Window w = s.getFullScreenWindow();
        w.setBackground(Color.GREEN);
        w.setForeground(Color.WHITE);
        running = true;
    }

    //main gameloop
    public void gameLoop() {
        long startTime = System.currentTimeMillis();
        long cumTime = startTime;

        while (running) {
            long timePassed = System.currentTimeMillis() - cumTime;
            cumTime += timePassed;

            update(timePassed);

            Graphics2D g = s.getGraphics();
            draw(g);
            g.dispose();
            s.update();

            try {
                Thread.sleep(FPStimeToSleep);
            } catch (Exception e) {
            }
        }
    }

    public void setFPS(int fps) {
        FPStimeToSleep = 1000 / fps;
    }

    //update animation
    public void update(long timePassed) {
    }

    //draws to the screen
    public abstract void draw(Graphics2D g);

    public void add(Component comp) {
        s.addComponent(comp);//being called by my coding class to add the button
    }
}
  • 1. Re: JButton flickering in fullscreen+unfocusable?
    DarrylBurke Guru Moderator
    Currently Being Moderated
    Are you constructing, showing and otherwise changing the state of all Swing components on the EDT?
    [http://java.sun.com/docs/books/tutorial/uiswing/concurrency/index.html]
    [http://java.sun.com/products/jfc/tsc/articles/threads/threads1.html]
    [http://java.sun.com/products/jfc/tsc/articles/threads/threads3.html]

    db
  • 2. Re: JButton flickering in fullscreen+unfocusable?
    794044 Newbie
    Currently Being Moderated
    I am TRYING to show them... but that only works flickerly...
    what is EDT?

    EDIT: My main code is like this:
    public class Main extends Core implements KeyListener, MouseListener {
        Button test;
    
        public static void main(String[] args) {
            new Main().run();
        }
    
        public void init() {
            super.init();
            super.setFPS(20);
            Window w = s.getFullScreenWindow();
            w.addKeyListener(this);
            w.addMouseListener(this);
    
            test = new Button();
            test.setBounds(50, 50, 100, 100);
            test.setFocusable(false);
            test.setIgnoreRepaint(true);
            test.setVisible(true);
            add(test);
            }
    
        @Override
        public void draw(Graphics2D g) {
             g.drawImage(image,0,0,this);
        }
    
        public void keyTyped(KeyEvent e) {
            if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
                stop();
            }}
    
      public void keyPressed(KeyEvent e) {
            if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
                stop();
            }}
    
        public void keyReleased(KeyEvent e) {
        }
    
    public void mouseClicked(MouseEvent e) {)
    
        public void mousePressed(MouseEvent e) {}
    
        public void mouseReleased(MouseEvent e) {}
    
        public void mouseEntered(MouseEvent e) {
        }
    
        public void mouseExited(MouseEvent e) {
        }
    }
    EDIT2: I'm sorry that I don't know alot of Java, I'm not a real pro or something, I'm following video tutorials and stuff...

    Edited by: The_Pointer on Mar 22, 2010 1:48 PM

    Edited by: The_Pointer on Mar 22, 2010 1:56 PM
  • 3. Re: JButton flickering in fullscreen+unfocusable?
    DarrylBurke Guru Moderator
    Currently Being Moderated
    what is EDT?
    I give you 3 links and you still want someone here to tell you?

    Change your main method to
    public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
        
        @Override
        public void run() {
          new Main().run();
        }
      });
    }
    See if that makes a difference.

    db
  • 4. Re: JButton flickering in fullscreen+unfocusable?
    794044 Newbie
    Currently Being Moderated
    it did make sense... the following:
    now the flicker has gone, even as the possibility to click on it... and my exit doesn't work either anymore...

    EDIT: I found out what the problem is!: The JButton does get drawn (I made a JButton), however, the Graphics2D seems to draw itself over the JButton... now the way how to fix this...
    EDIT2: The JButton appears to be drawn on the foreground, but not on the background, as it is double buffered (and thus switching from fore to back) the Jbutton flickers... This is though when I do NOT have a background image that overwrites it... if I DO have a background image the button is not visible because the background image gets drawn over it...
    I made it 1 fps, one frame it's visible when I'm clicking on it, the other frame it is not; it is only visible when I click on it (so when it changes image and repaints) but disappears the following frame again...
    I'm going to sleep now

    Edited by: The_Pointer on Mar 22, 2010 2:32 PM

    Edited by: The_Pointer on Mar 22, 2010 2:36 PM
  • 5. Re: JButton flickering in fullscreen+unfocusable?
    794044 Newbie
    Currently Being Moderated
    I have found my answer...:

    I was using the BETA release of Java 7; this contained a BUG that made showing the component harder; I have the same problem in an Applet; downgraded and now it works!

    Thanks for help though