2013-04-24 219 views
-1

我正在尝试实现一个简单的启动画面。因此,我有两个班级Loader,它是JFrameBackgroundJComponent的子项,用作GlassPane)的孩子来保存实际图像。在这张图片下面应该有一个小进度条。图片显示不正确

一旦图像加载,我就会显示窗口。这工作得很好。但它不会显示图像。滚动条占据整个框架。如果我手动缩小窗口并将其放回原位,将显示图像。

为什么图像不能立即显示?

下面的代码:

装载机

public class Loader extends JFrame{ 

    private static final int _WIDTH = 500; 
    private static final int _HEIGHT = 300; 

    private JProgressBar bar; 
    private Background bg; 

    public Loader(){ 
     super("Risiko Loader"); 
     this.setAlwaysOnTop(true); 
     Dimension window = Toolkit.getDefaultToolkit().getScreenSize(); 
     this.setBounds(window.width/2 - _WIDTH/2, window.height/2 - _HEIGHT/2, _WIDTH, _HEIGHT); 
     this.setUndecorated(true); 
     this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); 
     this.setResizable(false); 
     this.setFocusable(true); 
     this.setBackground(new Color(1.0f,0.0f,1.0f,1.0f)); 
     this.setFocusableWindowState(true); 

     this.setIcons(); 

     bar = new JProgressBar(); 

     bar.setSize(_WIDTH, 20); 
     bar.setLocation(0, _HEIGHT - 20); 
     bar.setValue(0); 
     bar.setMinimum(0); 
     bar.setMaximum(100); 

     this.add(bar); 

     bg = new Background(); 
     this.setGlassPane(this.bg); 
     this.bgIsReady(); 
    } 

    private void bgIsReady(){ 
     do { 
      try { 
       Thread.sleep(100); 
      }catch(Exception e){} 
     }while(this.bg.tracker.statusID(1, false) == MediaTracker.COMPLETE); 

     this.setVisible(true); 
     this.getGlassPane().setVisible(true); 
     this.getGlassPane().repaint(); 
     bar.setValue(50); 
    } 

    private void setIcons(){ 
     ArrayList<Image> icons = new ArrayList<>(); 
     icons.add(Toolkit.getDefaultToolkit().getImage(System.getProperty("user.dir") + File.separator + "images" + File.separator + "icon16.png")); 
     icons.add(Toolkit.getDefaultToolkit().getImage(System.getProperty("user.dir") + File.separator + "images" + File.separator + "icon32.png")); 
     this.setIconImages(icons); 
    } 

    public static void main(String [] args){ 

     Loader l = new Loader(); 
    } 
} 

而且背景

public class Background extends JComponent{ 
    private Image img; 

    public MediaTracker tracker; 

    public Background(){ 
     this.tracker = new MediaTracker(this); 
     String imgPath = System.getProperty("user.dir") + File.separator + "images" + File.separator + "splash.png"; 
     this.img = Toolkit.getDefaultToolkit().getImage(imgPath); 
     this.tracker.addImage(this.img, 1); 
    } 

    @Override 
    public void paintComponent(Graphics g) { 
     if(this.tracker.statusID(1, false) == MediaTracker.LOADING) {//not loaded 
      return; 
     } 
     // Draw the background image 
     g.drawImage(this.img, 1, 1, null); 
     System.out.println("p"); 
    } 
} 

回答

2

这也可能是这部分 -

do { 
    try { 
     Thread.sleep(100); 
    }catch(Exception e){} 
}while(this.bg.tracker.statusID(1, false) == MediaTracker.COMPLETE); 

您应该在while而不是MediaTracker.COMPLETE中检查MediaTracker.LOADING。现在可能发生的情况是,代码睡眠了100ms,检查了MediaTracker状态,它仍然是MediaTracker.LOADING,它不是COMPLETE,所以代码继续进行,并将您的框架,glassPane等设置为可见,而不会首先加载图像。加载你的图片必须花费超过100毫秒 - 否则你的问题将是你的框架永远不会出现。

在另一个说明 - 如果你想要“简单的启动画面” - 这是复杂的方式。

在Java 1.6+中有一个内置的SplashScreen类。

即使你想这个重建自己,你可以只使用一个JFrameBorderLayout,在BorderLayout.CENTERJLabel与图像的ImageIcon,并把JProgressBarBorderLayout.SOUTH作为一个更简单的选择。

+0

谢谢。不幸的是'MediaTracker.LOADING'部分没有改变我切换到你的'BorderLayout'解决方案的任何东西,并且它完美地工作。谢谢。 – 2013-04-24 18:21:35