-1

我正在尝试实现一个简单的闪屏。因此,我有两个类,Loader它们是的子类JFrameBackground(的子类JComponent,用作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");
    }
}
4

1 回答 1

2

大概就是这部分——

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

您可能应该检查MediaTracker.LOADINGinwhile而不是MediaTracker.COMPLETE. 现在可能发生的情况是代码休眠了 100 毫秒,检查MediaTracker状态,它仍然MediaTracker.LOADING是 ,而不是COMPLETE,所以代码继续并设置您的框架、玻璃窗格等可见,而无需先加载图像。加载图像的时间必须超过 100 毫秒 - 否则你的问题将是你的框架永远不会出现。

另一方面——如果你想制作“一个简单的闪屏”——这太复杂了。

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

即使您想自己重新创建它,您也可以使用 a JFramewith BorderLayout,将 a JLabelwith anImageIcon图片放入BorderLayout.CENTER,然后将JProgressBarinBorderLayout.SOUTH作为更简单的选项放入。

于 2013-04-24T17:54:03.973 回答