-1

シンプルなスプラッシュ画面を実現しようとしています。したがって、実際のイメージを保持する と の子 ( の子、 として使用)である2Loaderつのクラスがあります。そして、この画像の下に小さな進行状況バーがあるはずです。JFrameBackgroundJComponentGlassPane

画像が読み込まれるとすぐにウィンドウを表示しています。これはうまくいきます。しかし、それは画像を表示しません。Scrollbar はフレーム全体を使用します。ウィンドウを手動で縮小して前面に戻すと、画像が表示されます。

画像がすぐに表示されないのはなぜですか?

コードは次のとおりです。

ローダ

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.LOADINGwhile代わりに をチェックする必要がありMediaTracker.COMPLETEます。おそらく今起こっていることは、コードが 100 ミリ秒スリープし、MediaTrackerステータスをチェックし、まだMediaTracker.LOADINGであり、そうではないCOMPLETEため、コードが先に進み、画像が最初にロードされずにフレーム、glassPane などを表示するように設定することです。画像の読み込みには 100 ミリ秒以上かかる必要があります。そうしないと、フレームが表示されないという問題が発生します。

別の注意点として、「単純なスプラッシュ画面」を作成しようとしている場合、これは非常に複雑です。

Java 1.6+には組み込みのSplashScreenクラスがあります。

これを自分で再作成したい場合でも、 with を使用しJFrameて、画像のwithをBorderLayoutに配置し、より簡単なオプションとしてを配置することができます。JLabelImageIconBorderLayout.CENTERJProgressBarBorderLayout.SOUTH

于 2013-04-24T17:54:03.973 に答える