JDK-6709453 : Screen flickers when a JFrame switches to fullscreen mode
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 6u10
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2008-06-02
  • Updated: 2011-02-16
  • Resolved: 2009-05-15
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6 JDK 7
6u14 b04Fixed 7Fixed
Related Reports
Relates :  
Relates :  
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 http://hg.openjdk.java.net/jdk7/build/jdk/rev/23a3e724ee9d
25-12-2010

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

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
17-06-2008

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.
17-06-2008

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.
17-06-2008

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.
02-06-2008