|
Quick Lists
|
|
Bug ID:
|
6709453
|
|
Votes
|
1
|
|
Synopsis
|
Screen flickers when a JFrame switches to fullscreen mode
|
|
Category
|
java:classes_awt
|
|
Reported Against
|
|
|
Release Fixed
|
6u14(b04)
|
|
State
|
11-Closed,
Verified,
bug
|
|
Priority:
|
3-Medium
|
|
Related Bugs
|
6587847
|
|
Submit Date
|
02-JUN-2008
|
|
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 :
customer Windows XP [Version 5.1.2600]
customer Windows 2003 Server
EXTRA RELEVANT SYSTEM CONFIGURATION :
My graphic card is customer 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.
Posted Date : 2008-06-02 07:59:26.0
|
|
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
|
|
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.
Posted Date : 2008-06-02 16:18:57.0
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.
Posted Date : 2008-06-17 21:39:55.0
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.
Posted Date : 2008-06-17 22:51:12.0
|
|
Comments
|
Submitted On 18-JUN-2008
stevpan
It works now. Thanks a lot for your clear explanation. To make the switching effect more reliable, I added a Thread.sleep(100) before each setVisble(true) statement. This way, it never flickers!
PLEASE NOTE: JDK6 is formerly known as Project Mustang
|
|
|
 |