United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6709453 Screen flickers when a JFrame switches to fullscreen mode
JDK-6709453 : Screen flickers when a JFrame switches to fullscreen mode

Details
Type:
Bug
Submit Date:
2008-06-02
Status:
Closed
Updated Date:
2011-02-16
Project Name:
JDK
Resolved Date:
2009-05-15
Component:
client-libs
OS:
windows_xp
Sub-Component:
java.awt
CPU:
x86
Priority:
P3
Resolution:
Fixed
Affected Versions:
6u10
Fixed Versions:
6u14 (b04)

Related Reports
Backport:
Relates:
Relates:

Sub Tasks

Description
FULL PRODUCT VERSION :
java version "1.6.0_10-beta"
Java(TM) SE Runtime Environment (build 1.6.0_10-beta-b24)
Java HotSpot(TM) Client VM (build 11.0-b12, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]
Microsoft Windows 2003 Server

EXTRA RELEVANT SYSTEM CONFIGURATION :
My graphic card is Intel 865G, but I think this problem has nothing to do with graphic card.

A DESCRIPTION OF THE PROBLEM :
Screen flickers when a JFrame switches to fullscreen mode. My program works properly in J2SE5, J2SE6update2, J2SE6Update5, therefore I conclude that  it's J2SE6 Update 10's problem.

I guess the possible cause is: 1. the repaint event was not handled properly.
2. SetVisble(false) does not work propoerly.

I have to write a demo program to show this problem. hope it  will be helpful.



STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Save the source code as "AppMain.java"
2. Compile it.
3. Run it with J2SE6U10: "java AppMain"
4. Choose the Menu "File-->FullScreen(Esc to cancel)"


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The screen should switch to fullscreen immediately and smoothly.


ACTUAL -
The screen does not switch to full screen mode smoothly.
It flickers several times.


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.awt.*;
import java.util.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.util.*;


public class AppMain {

  public static void main (String[] args) {

  // define frame, its size and make it visible
  int arg0=-1;


  AppletFrame myFrame = new AppletFrame();

  myFrame.setVisible(true);

  } // end main method
} // end class


class AppletFrame extends JFrame implements ActionListener, WindowListener, MouseListener, MouseMotionListener, KeyListener {
  private MenuBar mb=null;
  private SpringLayout layout=null;
  private Dimension d0=null, d1=null;
  private boolean fullscreenOn=false;
  private int itemcounter=0;
  private boolean noSnapShot= true;
  private String[] xmlname;
  private String[] trackname;
  private int[] initTrack;
  private int trackCounter=1;
  private boolean fromlocaldir=false;
  private String[] localfilelist=null;
  private String autoplay="enable";
  private String strokemode="disable";
  private boolean debug=false;
  private ImageIcon jtvicon=null;
  private  JFileChooser _fileChooser1;

  public AppletFrame(boolean debug)
  {
	  super("SlidePlayer");  // use SlidePlay as window title
	  this.debug=debug;
	  initFrame();
  }
  public AppletFrame()
  {
	  super("SlidePlayer");  // use SlidePlay as window title
	  initFrame();
  }

  public void initFrame() {



    this.getContentPane().setBackground(Color.black);

    // define Menubar
    mb = new MenuBar();
//    mb.setFont(new Font("Helvetica", Font.PLAIN, 13));

    setMenuBar(mb);
    // Define File menu and with Exit menu item
    Menu fileMenu = new Menu("File");

    
    MenuItem exitMenuItem = new MenuItem("Exit");
    MenuItem fullscreenMenuItem = new MenuItem("Fullscreen (Esc to cancel)");
    


    //exitMenuItem.setAccelerator( KeyStroke.getKeyStroke("alt F4") );
    fileMenu.add(exitMenuItem);
    fileMenu.add(fullscreenMenuItem);



    // respond to file exit/fullscreen menu
    exitMenuItem.addActionListener(this);
    fullscreenMenuItem.addActionListener(this);



    // respond to window events
    addWindowListener(this);
    addKeyListener(this);    //  Respond to keystroke

    

    mb.add(fileMenu);
	
    JLabel t1= new JLabel("Hello");
    this.add(t1);

    this.setLayout(new BorderLayout());


    this.setPreferredSize(new Dimension(640, 480));

    pack();

    getContentPane().setBackground(Color.blue);
    d0= this.getSize();
	System.out.println("d0:"+ d0);

    
    setVisible(true); // usual step to make frame visible

    requestFocus();
    requestFocusInWindow();
    requestFocus();
    setResizable(false);
  



  } // end main


  public void destroy()
  {
	System.exit(1);
  }


  public void actionPerformed(ActionEvent evt) {

    if (evt.getSource() instanceof MenuItem) {
      String menuLabel = ((MenuItem)evt.getSource()).getLabel();

      if(menuLabel.equals("Exit")) {
        // close application, when exit is selected
        dispose();
        System.exit(0);
      } // end if



      if(menuLabel.equals("Fullscreen (Esc to cancel)")) {

		setVisible(false);

		setMenuBar(null);
	      	dispose();
		setUndecorated(true);
 
		// switching to fullscreen mode
		GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().setFullScreenWindow(this);
 
		// getting display resolution: width and height
		int w = this.getWidth();
		int h = this.getHeight();


		setPreferredSize(new Dimension(w, h));
	  	getContentPane().setBackground(Color.blue);


		this.setVisible(true);
//		    requestFocus();
//		    requestFocusInWindow();
//		    requestFocus();
		repaint();

		fullscreenOn=true;


      } // end if
	}


  } // end ActionPerformed

   public void keyPressed(KeyEvent evt) {

    int key = evt.getKeyCode();
         // escape key to exit from fullscreen mode
	 if (key == KeyEvent.VK_ESCAPE) {   // switching to window when press Escape key
		if(fullscreenOn==true)
		{
		
		// switching to window mode
		setVisible(false);
		GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().setFullScreenWindow(null);

 		setMenuBar(mb);
	      	dispose();
		setUndecorated(false);

		this.setLayout(new BorderLayout());
		this.setPreferredSize(d0);
	    	pack();
 
		// window should be visible
		this.setVisible(true);
		fullscreenOn=false;
		repaint();
		}

	   }

   }

   public void keyReleased(KeyEvent evt) {}
   public void keyTyped(KeyEvent evt) {}


public void windowClosing(WindowEvent e) {
	System.exit(1);
    }
    
    public void windowClosed(WindowEvent e) {
        //This will only be seen on standard output.
    }
    
    public void windowOpened(WindowEvent e) {
    }
    
    public void windowIconified(WindowEvent e) {
    }
    
    public void windowDeiconified(WindowEvent e) {
    }
    
    public void windowActivated(WindowEvent e) {
    }
    
    public void windowDeactivated(WindowEvent e) {
    }

   

   public void mouseDragged(MouseEvent e) {}

   public void mouseMoved(MouseEvent e) {}

// detect double click and single click
   public void mouseClicked( MouseEvent e ) {}

   public void mouseEntered( MouseEvent e ) { }
   public void mouseExited( MouseEvent e ) { }
   public void mousePressed( MouseEvent e ) { }
   public void mouseReleased( MouseEvent e ) { }

} // end class



---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
No workaround so far.  I have to use J2SE6 Update 5

Release Regression From : 6u5
The above release value was the last known release where this 
bug was not reproducible. Since then there has been a regression.

                                    

Comments
EVALUATION

Note that according to one of the logs posted by the user this issue
is reproducible on releases prior to 6u10:
the debug output is:
[W] GetFlagValues: DDraw screen locking is disabled (W2K, XP+)
InitDirectX
[V] CheckRegistry: Found Display Device 0: Intel(R) 82865G Graphics Controller
CreateDevice: lpGUID=0x0 hMon=0x0
DDSetupDevice
[E] CheckDDCreationCaps: previous surface creation failure detected
[E] DDSetupDevice: Failed to setup ddraw device 

The earlier log shows that with 6u10 the d3d pipeline is disabled:
 OS Version = OS_WINSERV_2003
[E] D3DPPLM::CheckOSVersion: Windows 2000 or earlier (or a server) OS detected,
failed

This means that we'd use GDI for FSEM, and that code didn't change much
between 6u10 and earlier releases.
                                     
2008-06-02
EVALUATION

This indeed looks like a regression in 6u10 but the cause is not yet
clear since the fullscreen enter/exit for the GDI case didn't change
between the releases.

The problem first appeared in b05, but the only relevant fix seems to be
  6607230: D3D: infinite wait is possible in D3DScreenUpdateManager.runUpdateNow()
although it mostly deals with d3d-related issue and the problem mostly
manifests when d3d pipeline is disabled. When I backed out the fix the
problem still reproduced.

It looks like what causes the flickering is making the window invisible
(and disposing of it) prior to entering and after the exiting of the
fs mode. If the test is changed not to do that (of course that would mean
that it can't be made undecorated) then the flickering stops.

So at least that's a work around for now:
use a different "full-screen only" frame, which can be undecorated.
When entering FS, hide the current frame, enter FS with another frame,
then reverse on exit.

Another fix which may be relevant is
  6505819: Provide traverseIn method for sun.awt.EmbeddedFrame
since it does some things with focus management, and this flickering certainly
may look like focus fighting:
  http://sa.sfbay.sun.com/projects/awt_data/6u5/6505819.3/

When I added a FocusListener to the frame in the test I found that in 6u10 b04
the following sequence of actions:
  - when frame shows up, select File/Enter FS, then
  - select File/Exit
results in just 2 focusGained events (one is when the frame appears
initially, another when it is brought into full screen mode):
focusGained      // frame is shown
focusLost        // frame is disposed
focusGained      // frame is set as fs window

In 6u10 b05 however I see one extra focus gained/lost event which could have
attributed to the flickering:
focusGained
focusLost
focusGained
focusLost
focusGained

I have added modified test case which shows the problem very well
(FlickeringJFrameFullScreenTest).

Reassigning to AWT team for further investigation.
                                     
2008-06-17
WORK AROUND

Change the code in actionPerformed in the test to this:
...
            if(menuLabel.equals("Fullscreen (Esc to cancel)")) {

                setVisible(false);
                setMenuBar(null);
                dispose();
                setUndecorated(true);

                EventQueue.invokeLater(new Runnable() {
                    public void run() {
                        // switching to fullscreen mode
                        GraphicsEnvironment.getLocalGraphicsEnvironment().
                            getDefaultScreenDevice().
                                setFullScreenWindow(AppletFrame.this);
                        // getting display resolution: width and height
                        int w = AppletFrame.this.getWidth();
                        int h = AppletFrame.this.getHeight();

                        setPreferredSize(new Dimension(w, h));
                        getContentPane().setBackground(Color.blue);

                        fullscreenOn=true;
                    }
                });
            } // end if
                                     
2008-06-17
EVALUATION

I dug a little deeper and it looks like I jumped the gun a bit with my
previous evaluation.

For some reason the following bug is listed as fixed in b06 but I can see
that it is present in b05's source bundles:
  6587847: PIT: D3D: FullScreen window fails to render AWT components, WinXP

The fix for this bug is the cause of this flickering.

When the d3d pipeline isn't enabled we add a WindowListener to the fs window
so that we can handle display mode restoration, window minimization/maximization
in the event the full screen window is alt-tabbed out or if it loses
the focus because of something else.

Prior to this fix it was not possible to alt+tab out of fullscreen 
application unless it was running with the d3d or ddraw pipeline.
It was even worse when the app changed the display mode..

This window listener minimizes the fullscreen window on window deactivation.

Unfortunately in this particular case the soon to be full-screen window
is first disposed of, which makes it to be deactivated. Note that this is
done in response to the menu action, so we're on the EDT. 

Then it is made a full screen window (still from the same event handler 
on the EDT), at which time we add our window listener. Then the handler 
is finished and EDT resumes its work.

Sometime later we receive and handle the deactivation event caused by the
dispose/setVisible(false), so the handler minimizes the full screen window.

Again some time later another window activation event comes (from when it
was made full screen), so we de-iconize it again. That's why we get the 
flickering.

It's not yet clear how to make this work properly but it is now clear
how to work around the problem:
dispose the window, make it undecorated when responding to the menu action, then
post another event on the EDT which would change it to the FS mode (using
invoke later). This event will be placed after the deactivation event from the
first activity.
(see the Work Around field)

Since AWT graciously agreed to handle non-d3d full screen issues, I'm leaving
it assigned to AWT.
                                     
2008-06-17
SUGGESTED FIX

http://sa.sfbay.sun.com/projects/awt_data/6u14/6709453/
                                     
2010-11-30
EVALUATION

http://hg.openjdk.java.net/jdk7/build/jdk/rev/23a3e724ee9d
                                     
2010-12-25



Hardware and Software, Engineered to Work Together