Java Programming Notes # 1496
- Preface
- General
Background Information - Preview
- Discussion and
Sample Code - Run the Program
- Summary
- References
- Complete Program
Listings
Preface
Oh for the good old days
Do you have a secret longing for the "good old days" when you could
write a program that would take over the entire screen and wouldn’t be bothered
by a lot of pesky other programs competing for screen space. If so, those
days are back. In this lesson, I will show you how to use the Full-Screen Exclusive Mode API to
write programs that take over
the entire screen, as shown by the output from the animation program in
Figure 3.
Once your program has entered the Full-Screen Exclusive Mode, I will show
you how to use active rendering as opposed to passive rendering to
eliminate the overhead associated with passive rendering.
Viewing tip
You may find it useful to open another copy of this lesson in a
separate browser window. That will make it easier for you to
scroll back
and forth among the different listings and figures while you are
reading
about them.
Supplementary material
I recommend that you also study the other lessons in my extensive
collection of online Java tutorials. You will find those lessons
published
at Gamelan.com.
However, as of the date of this writing, Gamelan doesn’t maintain a
consolidated index of my Java tutorial lessons, and sometimes they are
difficult to locate there. You will find a consolidated index at www.DickBaldwin.com.
I also recommend that you pay particular attention to the lessons listed in
the References section of this document.
General Background Information
Display many programs concurrently
Recent history would indicate that in most cases, it is probably best to
have a multitude of programs running concurrently and sharing screen space, as
indicated by the typical screen shot of my computer in
Figure 1.
Dedicate display capacity to a single program
However, sometimes it might be best to dedicate the computational and display capacity of your computer screen to a single
program as shown in Figure 3. Dedicating the
display capacity to a single program can be achieved by writing the program so
that uses the Full-Screen Exclusive Mode API.
Active versus passive rendering
In addition to providing dedicated display space, the use of Full-Screen
Exclusive Mode makes it possible to employ active rendering as opposed to passive rendering of
the material on the screen. This eliminates some of the rendering
overhead, and should make the system more responsive when running simulation, game, and animation programs
where a responsive screen display is important.
Preview
A screen shot (showing the entire screen) of my computer screen during a typical working session is
shown in Figure 1.
Figure 1 |
As you can see, there were several different applications competing for space
on my screen when I captured the screen shot.
A sense of scale
I’m sure that you have no interest in what my computer
screen happened to look like while I was writing this lesson.
Figure 1 is
provided to give you a sense of scale (The purpose is similar to that of photographing
a small object
with a coin laying beside it so that the size of the object will be apparent.) Because of the narrow publication
format for this lesson, it was not possible for me to show screen shots in their full size.
Therefore, the size of the image in
Figure 1 was reduced from 1024×768 pixels to
470×353 pixels for publication purposes.
The output from the program named FullScreen01
(In the remainder of this lesson, I will often refer to the
Full-Screen Exclusive Mode simply
as the full-screen mode.)
One button and four labels
For illustration purposes, the JFrame object shown in Figure 2 has a
JButton object placed in the NORTH location, and has JLabel
objects with colored backgrounds placed in the other four locations managed by
the BorderLayout manager.
I will present and explain the code for the program named Layout01
later in this lesson.
A more substantive program
I will also present and explain a much more substantive program named
FullScreen02 in this lesson. A screen shot (showing the entire
screen) of the output from the program named
FullScreen02 is shown
in Figure 3.
Figure 3 |
Image resizing within the program
As you will see in the comments in the program, it is supposed to be possible
to cause the image file to be resized when it is loaded by the program.
I was unable to get that to work properly, but I didn’t spend much time
troubleshooting the problem.
Summary
In this lesson, I showed you how to use the Full-Screen Exclusive Mode API to
write programs that take over
the entire screen, as shown by the output from the animation program in
Figure 3.
I also showed you how to use active rendering as opposed to passive rendering to
eliminate the overhead associated with passive rendering.
References
The program named FullScreen02 is an update to a program named
Animate03, first published in the last lesson in the following list.
-
1450 Fun with Java: Sprite Animation, Part 1 -
1452 Fun with Java: Sprite Animation, Part 2 -
1454 Fun with Java: Sprite Animation, Part 3 -
1456 Fun with Java: Sprite Animation, Part 4 -
1458 Fun with Java: Sprite Animation, Part 5 -
1460 Fun with Java: Sprite Animation, Part 6 -
1462 Fun with Java: Sprite Animation, Part 7 -
1464 Fun with Java: Frame Animation -
1466 Fun with Java: Animated Sea Worms
The program named Animate03 uses material published in the earlier
lessons in the above list.
Complete Program Listings
Complete listings of the programs discussed in this lesson are shown in
Listing 26 and Listing 27 below.
/*FullScreen01.java This is a skeleton program that implements the Full-Screen Exclusive Mode The program places an undecorated non-resizable JFrame object on the screen in the Full-Screen Exclusive Mode. A JButton appears in the North location of the JFrame. Clicking the button causes the program to exit the full- screen mode, restore the original graphics mode, and terminate. The program places red, green, and white JLabels in the East, West, South, and Center locations solely to demonstrate that the graphics object is an undecorated non-resizable JFrame object. The program displays a list of the available graphics devices solely for information purposes in the command- line window. However, that window is hidden behind the full-screen version of the JFrame object and isn't visible until the full-screen mode is terminated. Even though the program displays a list of all of the graphics devices, it operates only on the first graphics device in the list. Tested using J2SE5.0 under WinXP. J2SE 1.4 or later is required for the setFullScreenWindow method of the GraphicsDevice object. **********************************************************/ import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; public class FullScreen01 extends JFrame implements ActionListener{ private GraphicsDevice graphicsDevice; private DisplayMode origDisplayMode; private JButton exitButton = new JButton( "Exit Full-Screen Mode"); public static void main(String[] args){ //Get and display a list of graphics devices solely for // information purposes. GraphicsEnvironment graphicsEnvironment = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsDevice[] devices = graphicsEnvironment.getScreenDevices(); for(int cnt = 0;cnt < 1;cnt++){ System.out.println(devices[cnt]); }//end for loop //Construct a full-screen object using // graphicsDevice 0. new FullScreen01(devices[0]); }//end main //Constructor public FullScreen01(GraphicsDevice graphicsDevice){ //Save a reference to the graphics device as an // instance variable so that it can be used later to // exit the full-screen mode. this.graphicsDevice = graphicsDevice; setTitle("This title will be hidden (undecorated)"); //Get and save a reference to the original display // mode as an instance variable so that it can be // restored later. origDisplayMode = graphicsDevice.getDisplayMode(); //Register an action listener on the exitButton. exitButton.addActionListener(this); //Place the exitButton in the JFrame getContentPane().add(exitButton, BorderLayout.NORTH); //Place four labels in the JFrame solely for the // purpose of showing that it is a full-screen // undecorated JFrame. JLabel eastLabel = new JLabel(" East "); eastLabel.setOpaque(true); eastLabel.setBackground(Color.RED); getContentPane().add(eastLabel,BorderLayout.EAST); JLabel southLabel = new JLabel("South",SwingConstants.CENTER); southLabel.setOpaque(true); southLabel.setBackground(Color.GREEN); getContentPane().add(southLabel,BorderLayout.SOUTH); JLabel westLabel = new JLabel(" West "); westLabel.setOpaque(true); westLabel.setBackground(Color.RED); getContentPane().add(westLabel,BorderLayout.WEST); JLabel centerLabel = new JLabel("Center",SwingConstants.CENTER); centerLabel.setOpaque(true); centerLabel.setBackground(Color.WHITE); getContentPane().add(centerLabel,BorderLayout.CENTER); if (graphicsDevice.isFullScreenSupported()){ // Enter full-screen mode witn an undecorated, // non-resizable JFrame object. setUndecorated(true); setResizable(false); //Make it happen! graphicsDevice.setFullScreenWindow(this); validate(); }else{ System.out.println("Full-screen mode not supported"); }//end else }//end constructor //The following method is invoked when the used clicks // the exitButton public void actionPerformed(ActionEvent evt){ //Restore the original display mode graphicsDevice.setDisplayMode(origDisplayMode); //Terminate the program System.exit(0); }//end actionPerformed }//end class |
/*FullScreen02.java Copyright 2006, R.G.Baldwin The purpose of this program is to demonstrate the use of the Full-Screen Exclusive Mode API for simulation and animation. This program is an update to the earlier program named Animate03 as described in the earlier lesson number Java1466. This program has been modernized to make use of the Swing Timer class as an animation timer, and also to use Active Rendering (as opposed to Passive Rendering) in Full-Screen Exclusive Mode. It has also been modernized to use generics. The program animates colored worms on a background image in Full-Screen Exclusive mode. See the discussion of Active Rendering versus Passive Rendering in The Java Tutorial at: http://java.sun.com/docs/books/tutorial/extra/fullscreen/ index.html Using Active Rendering, the program does not call the repaint method to ask the operating system to call the update method. Rather, the program invokes a method named activeRenderer, which draws the animated sprites on the screen without concern for sharing the screen with other applications. (There are no other applications on the screen in full-screen mode.) The program places an undecorated non-resizable JFrame object on the screen in Full-Screen Exclusive Mode. A JButton appears in the North location of the JFrame. Clicking the button causes the program to exit the full- screen mode, restore the original graphics mode, and terminate. A JPanel appears in the center of the JFrame object. The colored worms are animated as sprites on the JPanel. A background image is drawn on the JPanel at the beginning of each animation cycle. This image erases the sprites that were previously there creating a clean slate for drawing the sprites in their new positions. If the background image is eliminated, the worms turn into long tubes because the old sprite images are never erased. The background image that is used fits a 1024 x 768 screen in Full-Screen Exclusive mode. If the screen is a different size, a different size background image is needed. Tested using J2SE5.0 under WinXP. J2SE 1.4 or later is required for the setFullScreenWindow method of the GraphicsDevice object. J2SE 5.0 or later is required to support generics. **********************************************************/ import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; import java.util.*; class FullScreen02 extends JFrame implements ActionListener{ private GraphicsDevice graphicsDevice; private DisplayMode origDisplayMode; private JButton exitButton = new JButton( "Exit Full-Screen Mode Copyright 2006, R.G.Baldwin"); public static void main(String[] args){ //Get a list of available graphics devices. GraphicsEnvironment graphicsEnvironment = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsDevice[] devices = graphicsEnvironment.getScreenDevices(); //Construct a full-screen object using the first // graphics device in the array. Ignore the others, if // there are any. new FullScreen02(devices[0]); }//end main //-----------------------------------------------------// //Constructor public FullScreen02(GraphicsDevice graphicsDevice){ //Save a reference to the graphics device as an // instance variable so that it can be used later to // exit the full-screen mode. this.graphicsDevice = graphicsDevice; setTitle("This title will be hidden (undecorated)"); //Get and save a reference to the original display // mode as an instance variable so that it can be // restored later. origDisplayMode = graphicsDevice.getDisplayMode(); //Register an action listener on the exitButton. exitButton.addActionListener(this); //Place the exitButton at the top of the JFrame getContentPane().add(exitButton,BorderLayout.NORTH); //Create an animation panel and place it in the center // of the JFrame. getContentPane().add(new AnimationPanel()); if(graphicsDevice.isFullScreenSupported()){ // Enter full-screen mode witn an undecorated, // non-resizable JFrame object. setUndecorated(true); setResizable(false); graphicsDevice.setFullScreenWindow(this); validate(); }else{ System.out.println("Full-screen mode not supported"); }//end else }//end constructor //-----------------------------------------------------// //The following method is invoked when the used clicks // the exitButton public void actionPerformed(ActionEvent evt){ //Restore the original display mode graphicsDevice.setDisplayMode(origDisplayMode); //Terminate the program System.exit(0); }//end actionPerformed //-----------------------------------------------------// }//end class FullScreen02 //=======================================================// //This is a convenience class that makes it a little // easier to deal with the background image. Note that // much of the impetus for this class went away when the // animation program named Animate 03 was converted to // full-screen mode. Several convenience methods having to // do with the size of the background image were eliminated // at that time. class BackgroundImage{ private Image image; private Component component; public BackgroundImage(Component component,Image image){ this.component = component; this.image = image; }//end construtor public void drawBackgroundImage(Graphics g){ //Note that component is an ImageObserver in the // following statement. g.drawImage(image,0,0,component); }//end drawBackgroundImage() }//end class BackgroundImage //=======================================================// //An object of this class manages a collection of animated // sprites stored in an ArrayList object. (A Vector // object was used in the earlier version named Animate03.) // Note that this class also underwent some modernization // with respect to the use of generics as released in // J2SE 5.0. class SpriteManager{ private ArrayList <Sprite> theSprites = new ArrayList<Sprite>(); private BackgroundImage backgroundImage; private int panelWidth; private int panelHeight; //-----------------------------------------------------// public SpriteManager(BackgroundImage backgroundImage, int panelWidth, int panelHeight){ this.backgroundImage = backgroundImage; this.panelWidth = panelWidth; this.panelHeight = panelHeight; }//end constructor //-----------------------------------------------------// public Point getEmptyPosition(Dimension spriteSize){ Rectangle trialSpaceOccupied = new Rectangle( 0,0,spriteSize.width,spriteSize.height); Random rand = new Random(System.currentTimeMillis()); boolean empty = false; int numTries = 0; //Search for an empty position. If an empty position // can't be found after 100 tries, give up and allow // two sprites to occupy the same initial location. while(!empty && numTries++ < 100){ // Get a trial position trialSpaceOccupied.x = Math.abs( rand.nextInt() % panelWidth); trialSpaceOccupied.y = Math.abs( rand.nextInt() % panelHeight); // Iterate through existing sprites, checking if // position is empty boolean collision = false; for(int cnt = 0;cnt < theSprites.size();cnt++){ Rectangle testSpaceOccupied = theSprites.get(cnt).getSpaceOccupied(); if(trialSpaceOccupied.intersects( testSpaceOccupied)){ collision = true; }//end if }//end for loop empty = !collision; }//end while loop return new Point(trialSpaceOccupied.x, trialSpaceOccupied.y); }//end getEmptyPosition() //-----------------------------------------------------// //This method updates the state information for each of // the sprites. public void updateSprites(){ Sprite sprite; //Iterate through sprite list for(int cnt = 0;cnt < |
Copyright 2006, Richard G. Baldwin. Reproduction in whole or in part in any
form or medium without express written permission from Richard Baldwin is
prohibited.
About the author
Richard Baldwin is a
college professor (at Austin Community College in Austin, TX) and private
consultant whose primary focus is a combination of Java, C#, and XML. In
addition to the many platform and/or language independent benefits of Java and
C# applications, he believes that a combination of Java, C#, and XML will become
the primary driving force in the delivery of structured information on the Web.
Richard has participated in numerous consulting projects and he
frequently provides onsite training at the high-tech companies located in and
around Austin, Texas. He is the author of Baldwin’s Programming
Tutorials, which have gained a
worldwide following among experienced and aspiring programmers. He has also
published articles in JavaPro magazine.
In addition to his programming expertise, Richard has many years of
practical experience in Digital Signal Processing (DSP). His first job after he
earned his Bachelor’s degree was doing DSP in the Seismic Research Department of
Texas Instruments. (TI is still a world leader in DSP.) In the following
years, he applied his programming and DSP expertise to other interesting areas
including sonar and underwater acoustics.
Richard holds an MSEE degree from Southern Methodist University and has
many years of experience in the application of computer technology to real-world
problems.