如何获取Java输出屏幕?

时间:2017-01-26 07:14:05

标签: java swing awt

我正在尝试使用图形在屏幕上显示图像,但屏幕无法加载

出现输出屏幕但仅显示黑屏而不显示图像

代码被正确编译,为什么我没有得到输出

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);
        }

    }
}

1 个答案:

答案 0 :(得分:2)

让我们从背景信息开始......

JFrameJRootPane的容器,其中包含contentPaneJMenuBarJGlassPane

RootPane

当您覆盖paint等顶级容器的JFrame时,您只绘制最底部的组件JRootPane,然后将其内容绘制在顶部使它变得毫无意义。

有关详细信息,请参阅How to Use Root Panes

绘画也是一个复杂的操作,无法调用super.paint将导致问题没有结束,请确保在绘画之前总是调用超级绘画方法,除非你真正了解它是如何工作的并准备好这样做&# 39;手动工作。

在Swing中,我们鼓励您从基于JComponent的类扩展(JPanel是首选)并覆盖其paintComponent方法并在那里执行自定义绘制

此组件可以添加到窗口中,也可以设置为contentPane,也可以根据需要添加到其他容器中。

有关详细信息,请参阅Painting in AWT and SwingPerforming Custom Painting

ImageIcon使用后台线程加载它的图像,因此即使它返回,图像也可能无法实现(或完全加载)。当您使用g.drawImage(bg,0,0,null);,将null作为ImageObserver传递时,它会阻止容器知道图像何时发生更改并允许其自动重新绘制自己。

很酷的是,所有基于Component的类都实现了ImageObserver,因此几乎所有可以绘制的内容都可以充当ImageObserver

“公约”鼓励将this作为ImageObserver传递。

通常,更好的解决方案是使用ImageIO,当它加载图像时,不会返回,直到图像完全实现。

有关详细信息,请查看Reading/Loading an Image

Thread.sleep(10000);在Swing中使用是危险的。它有可能阻止UI更新或响应其他输入和事件,使您的程序看起来好像它已挂起,因为它有。但在你的情况下,这意味着你违反了Swing的单线程规则。

Swing是一个单线程环境,你永远不应该执行任何可能阻止事件调度线程的操作,你永远不应该从EDT的上下文之外更新UI。

有一些解决方案可以帮助您,Swing Timer用于生成在EDT内调度的定期事件,SwingWorker用于执行支持更新UI的长时间运行操作。

有关详细信息,请参阅The Event Dispatch Thread

我的建议是不要担心全屏支持,专注于使用普通窗口绘制图像并添加全屏支持。这使您可以在一组独立的功能中解决问题,使其更容易解决。