我正在尝试使用图形在屏幕上显示图像,但屏幕无法加载
出现输出屏幕但仅显示黑屏而不显示图像
代码被正确编译,为什么我没有得到输出
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);
}
}
}
答案 0 :(得分:2)
让我们从背景信息开始......
JFrame
是JRootPane
的容器,其中包含contentPane
,JMenuBar
和JGlassPane
当您覆盖paint
等顶级容器的JFrame
时,您只绘制最底部的组件JRootPane
,然后将其内容绘制在顶部使它变得毫无意义。
有关详细信息,请参阅How to Use Root Panes
绘画也是一个复杂的操作,无法调用super.paint
将导致问题没有结束,请确保在绘画之前总是调用超级绘画方法,除非你真正了解它是如何工作的并准备好这样做&# 39;手动工作。
在Swing中,我们鼓励您从基于JComponent
的类扩展(JPanel
是首选)并覆盖其paintComponent
方法并在那里执行自定义绘制
此组件可以添加到窗口中,也可以设置为contentPane
,也可以根据需要添加到其他容器中。
有关详细信息,请参阅Painting in AWT and Swing和Performing 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。
我的建议是不要担心全屏支持,专注于使用普通窗口绘制图像并添加全屏支持。这使您可以在一组独立的功能中解决问题,使其更容易解决。