Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I am trying to display images on the screen using Graphics but the screen doesn't load

The output screen appears but only show The black screen and not the images

The code gets compiled properly so why am i not getting the output

package game;

import java.awt.*;
import javax.swing.JFrame;

public class Screen {
    private GraphicsDevice vc;

    public Screen(){
       GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
       vc=env.getDefaultScreenDevice();
    }

    public void setFullScreen(DisplayMode dm, JFrame window){
        window.setUndecorated(true);
        window.setResizable(false);
        vc.setFullScreenWindow(window);

        if(dm !=null && vc.isDisplayChangeSupported()){
            try{
                vc.setDisplayMode(dm);
            }catch(Exception ex){}
        }
    }

    public Window getFullSCreenWindow(){
        return vc.getFullScreenWindow();
    }

    public void resotreScreen(){
        Window w= vc.getFullScreenWindow();
        if(w!=null){
            w.dispose();
        }
        vc.setFullScreenWindow(null );
    }


}



package game;

import java.awt.*;
import javax.swing.ImageIcon;

import javax.swing.JFrame;

class Images extends JFrame{
    public static void main(String[] args){
       DisplayMode dm = new DisplayMode(800,600,16,DisplayMode.REFRESH_RATE_UNKNOWN);

       Images i = new Images();
       i.run(dm);

    }

    private Screen s;
    private Image bg;
    private Image pic;
    private boolean loaded;
    public void run(DisplayMode dm){
        setBackground(Color.BLUE);
        setForeground(Color.WHITE);
        setFont(new Font("Arial",Font.PLAIN,24));

        loaded =false;

        s = new Screen();

        try{
            s.setFullScreen(dm, this);
            loadpics();
            try{
                Thread.sleep(10000);
            }catch(Exception ex){}
        }finally{
               s.resotreScreen();
        }

    }

    public void loadpics(){
        bg = new ImageIcon("C:\Users\Dhruv\Downloads\Ronaldo.jpg").getImage();
        pic =new ImageIcon("C:\Users\Dhruv\Downloads\Messi.jpg").getImage();

        loaded= true;
        repaint();
    }
    public void paint(Graphics g){
        if(g instanceof Graphics2D){
            Graphics2D g2 =(Graphics2D)g;
            g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        }

        if(loaded){
            g.drawImage(bg,0,0,null);
            g.drawImage(pic,170,180,null);
        }

    }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
113 views
Welcome To Ask or Share your Answers For Others

1 Answer

Let's start with background information...

A JFrame is a container for a JRootPane, which contains the contentPane, JMenuBar and JGlassPane

RootPane

When you override paint of top level container like JFrame, you are only painting the bottom most component, the JRootPane and it's contents are then painted over the top, making it kind of pointless.

See How to Use Root Panes for more details

Painting is also a complex operation, failing to call super.paint will cause no end of issues, make sure you always call the super paint method before painting unless you really understand how it works and are prepared to do it's job manually.

In Swing you are instead encouraged to extend from a JComponent based class (JPanel been the preferred) and override its paintComponent method and perform your custom paint there

This component can either be added to the window or set as the contentPane or added to some other container depending on your needs.

See Painting in AWT and Swing and Performing Custom Painting for more details.

ImageIcon uses background thread to load it's images, so even though it returns, the image might not be realised (or fully loaded). When you use g.drawImage(bg,0,0,null);, passing null as the ImageObserver, it prevents the container from knowing when the image changes and allowing it to automatically repaint itself.

What's cool is, all Component based classes implement ImageObserver, so pretty much anything which can paint can act as an ImageObserver.

Convention would encourage to pass this as the ImageObserver.

Generally, a better solution is to use ImageIO, which when it loads images, won't return until the image is fully realised.

Have a look at Reading/Loading an Image for more details.

Thread.sleep(10000); is a dangerous thing to use in Swing. It has the potential to stop the UI from been updated or respond to other input and events, making your program appear as if it's hung, because it has. But in your case, it means you're violating the single thread rules of Swing.

Swing is a single threaded environment, you should never perform any action which might block the Event Dispatching Thread and you should never update the UI from outside the context of the EDT.

There are solutions available to help you, Swing Timer for generating periodical events which are dispatched within the EDT and SwingWorker for performing long running operations which have support for updating the UI.

See The Event Dispatch Thread for more details.

My recommendation is to not worry about the full screen support, focus on getting the images painting using a normal window and the add the full screen support. This allows you to solve problems within an isolated set of functionality, making it much easier to solve.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...