initial frame visibility

From my main application window, I create a new JFrame and initially it is, of course, not visible.  I then grab a screenshot of a portion of the screen and display inside the JFrame using a ImagePanel that I wrote......

public class ImagePanel extends JPanel() {

//constructor stuff here

public void paint(Graphics g) {

g.drawImage(theImage, 0, 0, this);

}

}

That is an excerpt of the pertinent parts.  In the main frame, I grab the content pane and add this component, then I show the frame.  What happens is that when the frame initially shows, for perhaps the first .1s it is the typical gray background which then flashes to the image which should be there.

How can I eliminate this flash?  Doesn't the double-buffering built into JComponent handle this?

Thanks,
David
lomidienAsked:
Who is Participating?
 
objectsCommented:
you need to wait until the filtering is complete

mt.waitForAll();

0
 
CEHJCommented:
How are you loading the image?
0
 
lomidienAuthor Commented:
Robot screenRobot = new Robot();
Image screenImage = screenRobot.createScreenCapture(new Rectangle(captureOrigin, captureDimension));

That takes the image from a portion of the screen defined by a x,y origin and w,h dimension.

Do I need a MediaTracker in there somewhere?

Thanks,
David
0
Cloud Class® Course: SQL Server Core 2016

This course will introduce you to SQL Server Core 2016, as well as teach you about SSMS, data tools, installation, server configuration, using Management Studio, and writing and executing queries.

 
CEHJCommented:
>>Do I need a MediaTracker in there somewhere?

You probably should. It sounds as if your frame is being shown before the image has finished loading.
0
 
InteractiveMindCommented:
For a nice example of the MediaTracker at work, see here: http://java.sun.com/j2se/1.5.0/docs/api/java/awt/MediaTracker.html
0
 
objectsCommented:
You can use a JLabel instead of needing a subclass, try something like this and see if it gets rid of your flashing:

Robot screenRobot = new Robot();
Image screenImage = screenRobot.createScreenCapture(new Rectangle(captureOrigin, captureDimension));
ImageIcon icon = new ImageIcon(screenImage);
JLabel imagePanel = new JLabel(icon);


Also in your ImagePanel class you should be overriding paintComponent() and not paint().
0
 
lomidienAuthor Commented:
I've tried the MediaTracker and I've tried using a JLable for the image...as well as changing the overriden method from paint to paintComponent.  I still have a noticeable flash.  But I have the following information now:

After I grab the screen image, I'm running it through a filter like this:

ImageFilter dimFilter = new DimImageFilter();
FilteredImageSource dimImageSrc = new FilteredImageSource(fadedScreenImage.getSource(), dimFilter);
fadedScreenImage = Toolkit.getDefaultToolkit().createImage(dimImageSrc);


The code for the filter class is below:

public class DimImageFilter extends RGBImageFilter {
   
    /** Creates a new instance of PauseFilter */
    public DimImageFilter() {
        // work with pixels whose indices are into a color table
        canFilterIndexColorModel = true;
    }
   
    public int filterRGB(int x, int y, int rgb) {
           
        // find out the red, green and blue color components
        int r = (rgb >> 16) & 0xff;
        int g = (rgb >> 8)  & 0xff;
        int b = (rgb)       & 0xff;

        //calculate the muted colors
        r = (r * 90)/100;
        g = (g * 90)/100;
        b = (b * 90)/100;

        return (rgb & 0xff000000) | (r<<16) | (g<<8) | (b);

    }
   
}

Calling .checkID from my MediaTracker shows the image to be unloaded.  How to mark this image as being complete after it has been through the filter?

For thoroughness, I'll post the code from the section as a whole here:  In this code sample, the call to MediaTracker returns false in both locations.

try{
            //take screenshot of selected area of screen
            screenRobot = new Robot();  //temporary robot for acquiring screenshot
            fadedScreenImage = screenRobot.createScreenCapture(new Rectangle(captureOrigin, captureDimension));
           
            //decrease brightness of image  by 10%                
            ImageFilter dimFilter = new DimImageFilter();
            FilteredImageSource dimImageSrc = new FilteredImageSource(fadedScreenImage.getSource(), dimFilter);
            fadedScreenImage = Toolkit.getDefaultToolkit().createImage(dimImageSrc);
           
            //track loading of image
            MediaTracker mt = new MediaTracker(this);
            mt.addImage(fadedScreenImage, 1);
            System.out.println(mt.checkID(1));

            //create undecorated JFrame and position it over portion of screen currently being captured
            fadedFrame = new JFrame();
            fadedFrame.setSize(captureDimension);
            fadedFrame.setUndecorated(true);
            fadedFrame.setLocation(captureOrigin.x-1, captureOrigin.y-1);
           
            //create image panel and position in in frame for display
            ImagePanel imagePanel = new ImagePanel(fadedScreenImage, this);
            JPanel cp = new JPanel();
            cp.setLayout(new BorderLayout());
            cp.setBorder(new LineBorder(Color.GRAY, 1));
            fadedFrame.setContentPane(cp);
            cp.add(imagePanel);
           
            //add action listener to image panel
            imagePanel.addMouseListener(new java.awt.event.MouseAdapter() {
                public void mouseClicked(java.awt.event.MouseEvent evt) {
                    fadedFrame.setVisible(false);
                    fadedFrame.dispose();
                }
            });
           
            //set pointer cursor
           
           
            //reset cursor position to be center of capture area
            int xPos = (captureDimension.width/2) + captureOrigin.x;
            int yPos = (captureDimension.height/2) + captureOrigin.y;
            screenRobot.mouseMove(xPos, yPos);            
           
            //show simulated overlay
            fadedFrame.setVisible(true);
            System.out.println(mt.checkID(1));
        }
        catch(Exception e) {
            //error handling code here - not yet implemented
            e.printStackTrace();
        }
0
 
lomidienAuthor Commented:
Ok, so I at least get mt.checkID(1) to report true.  I've changed the code to use a JLabel like you suggest.  If I do not run the image through a filter, I get no flash, but with the filter in place, I get a .1s-.2s flash which, as you well know, is irritating to the users eyes.

Thanks,
David
0
 
objectsCommented:
you shouldn't need to use MediaTracxker if using a JLabel, not sure why you are still getting a flash though. Can u post a compileable exable that demonstrates the problem that I can run here.
0
 
lomidienAuthor Commented:
Ok, I combined the relevent sections into this sample class.

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageFilter;
import java.awt.image.RGBImageFilter;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;

public class TestCase extends JPanel {
   
    /** Creates a new instance of TestCase */
    public TestCase() {    
        try{
            //take screenshot of selected area of screen
            Robot screenRobot = new Robot();  //temporary robot for acquiring screenshot
            Point captureOrigin = new Point(10,10);
            Dimension captureDimension = new Dimension(760, 600);
            Image fadedScreenImage = screenRobot.createScreenCapture(new Rectangle(captureOrigin, captureDimension));
           
            //decrease brightness of image                    
            ImageFilter dimFilter = new DimImageFilter();
            FilteredImageSource dimImageSrc = new FilteredImageSource(fadedScreenImage.getSource(), dimFilter);
            fadedScreenImage = Toolkit.getDefaultToolkit().createImage(dimImageSrc);
           
            //track loading of image
            MediaTracker mt = new MediaTracker(this);
            mt.addImage(fadedScreenImage, 1);

            //create undecorated JFrame and position it over portion of screen currently being captured
            JFrame fadedFrame = new JFrame();
            fadedFrame.setSize(captureDimension);
            fadedFrame.setUndecorated(true);
            fadedFrame.setLocation(captureOrigin.x-1, captureOrigin.y-1);
           
            //objects test code
            mt.waitForAll();
            System.out.println(mt.checkID(1));
            ImageIcon icon = new ImageIcon(fadedScreenImage);
            JLabel imagePanel = new JLabel(icon);
           
            //create image panel and position in in frame for display
//            ImagePanel imagePanel = new ImagePanel(fadedScreenImage, this);
            JPanel cp = new JPanel();
            cp.setLayout(new BorderLayout());
            cp.setBorder(new LineBorder(Color.GRAY, 1));
            fadedFrame.setContentPane(cp);
            cp.add(imagePanel);

            //reset cursor position to be center of capture area
            int xPos = (captureDimension.width/2) + captureOrigin.x;
            int yPos = (captureDimension.height/2) + captureOrigin.y;
            screenRobot.mouseMove(xPos, yPos);            
           
            //show simulated overlay
            fadedFrame.setVisible(true);
        }
        catch(Exception e) {
            //error handling code here - not yet implemented
            e.printStackTrace();
        }
       
    }

    public static void main(String[] args) {
        TestCase test = new TestCase();      
    }
   
    class DimImageFilter extends RGBImageFilter {
   
    /** Creates a new instance of PauseFilter */
    public DimImageFilter() {
        // work with pixels whose indices are into a color table
        canFilterIndexColorModel = true;
    }
   
    public int filterRGB(int x, int y, int rgb) {
           
        // find out the red, green and blue color components
        int r = (rgb >> 16) & 0xff;
        int g = (rgb >> 8)  & 0xff;
        int b = (rgb)       & 0xff;

        //calculate the muted colors
        r = (r * 90)/100;
        g = (g * 90)/100;
        b = (b * 90)/100;

        return (rgb & 0xff000000) | (r<<16) | (g<<8) | (b);

    }
   
}
   
}

Thanks,
David
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.