0

私がやろうとしているのは、アプリケーションを実行するとスレッドが開始され、画像が 3 秒間 (3000ms) 表示された後、スレッドの実行が停止するようにすることです。

イメージのパスが正しく、イメージ ファイルが存在し、スレッド自体が実行されます。ただし、画像が表示されないようです。何が間違っている可能性がありますか?これが私のコードです:

package org.main;

import java.awt.Graphics;
import java.awt.Image;

import javax.swing.ImageIcon;
import javax.swing.JPanel;

public class Splasher extends JPanel implements Runnable {
    private static final long serialVersionUID = 1L;
    Image image;
    ImageIcon splash = new ImageIcon("res/splash.png");
    public static Thread DrawSplash = new Thread(new Splasher());

    public Splasher() {
        setFocusable(true);
        image = splash.getImage();  
        repaint();
    }
    boolean hasRan = false;
    public void run() {
        try {
            System.out.println("Drawing Splash Screen");
            repaint();
            Thread.sleep(3000);
            System.out.println("Repainted");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void paint(Graphics g) {
        g.drawImage(image, 0, 0, null);
    }

    public Image getImage() {
        return image;
    }
}
4

2 に答える 2

2

あなたの質問から行くには十分ではありません。

スプラッシュ スクリーンが何かに接続されている場合や、Thread.

ですから、問題は何でもかまいません...

VishalKがすでに指摘した他のすべてに加えて、私はpublic static Thread DrawSplash = new Thread(new Splasher())悪い考えだと付け加えます. スレッドが再入可能でない場合は、s を使用しないstatic Threadでください。つまり、同じスレッドを 2 回実行できます。

Timerこれは、いくつかのSwing を使用して、「フェード」スプラッシュ スクリーンを示す小さな例です。

これは、Java 7 を使用していることを前提としています。Java 6 で動作させる方法はありません。そのコードは投稿していません。

public class TestSplashScreen01 {

    public static void main(String[] args) {
        new TestSplashScreen01();
    }

    public TestSplashScreen01() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                SplashScreen splash = new SplashScreen();
                splash.start();

            }
        });
    }

    public class SplashScreen extends JWindow {

        private SplashPane splash;

        public SplashScreen() {
            setBackground(new Color(0, 0, 0, 0));
            splash = new SplashPane();
            add(splash);
            pack();
            setLocationRelativeTo(null);
        }

        public void start() {
            splash.start();
        }

        public class SplashPane extends JPanel {

            private BufferedImage splash;
            private Timer timer;
            private float alpha = 0f;
            private int duration = 1000;
            private long startTime = -1;

            public SplashPane() {
                try {
                    splash = ImageIO.read(getClass().getResource("/res/SokahsScreen.png"));
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
                timer = new Timer(3000, new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        fadeOut();
                    }
                });
                timer.setRepeats(false);
            }

            protected void fadeOut() {
                Timer fadeInTimer = new Timer(40, new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        long now = System.currentTimeMillis();
                        long runTime = now - startTime;
                        alpha = 1f - ((float) runTime / (float) duration);
                        if (alpha <= 0.01f) {
                            alpha = 0f;
                            ((Timer) (e.getSource())).stop();
                            SwingUtilities.invokeLater(new Runnable() {
                                @Override
                                public void run() {
                                    dispose();
                                }
                            });
                        }
                        repaint();
                    }
                });
                startTime = System.currentTimeMillis();
                fadeInTimer.setRepeats(true);
                fadeInTimer.setCoalesce(true);
                fadeInTimer.start();
            }

            protected void fadeIn() {
                Timer fadeInTimer = new Timer(40, new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        long now = System.currentTimeMillis();
                        long runTime = now - startTime;
                        alpha = (float) runTime / (float) duration;
                        if (alpha >= 1f) {
                            alpha = 1f;
                            ((Timer) (e.getSource())).stop();
                            timer.start();
                        }
                        repaint();
                    }
                });
                startTime = System.currentTimeMillis();
                fadeInTimer.setRepeats(true);
                fadeInTimer.setCoalesce(true);
                fadeInTimer.start();
            }

            public void start() {
                if (!SplashScreen.this.isVisible()) {
                    alpha = 0f;
                    SplashScreen.this.setVisible(true);
                    SwingUtilities.invokeLater(new Runnable() {
                        @Override
                        public void run() {
                            fadeIn();
                        }
                    });
                }
            }

            @Override
            public Dimension getPreferredSize() {
                return splash == null ? super.getPreferredSize() : new Dimension(splash.getWidth(), splash.getHeight());
            }

            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                if (splash != null) {
                    Graphics2D g2d = (Graphics2D) g.create();
                    g2d.setComposite(AlphaComposite.SrcOver.derive(alpha));
                    int x = (getWidth() - splash.getWidth()) / 2;
                    int y = (getHeight() - splash.getHeight()) / 2;
                    g2d.drawImage(splash, x, y, this);
                    g2d.dispose();
                }
            }
        }
    }
}

注意:

この例の問題点は、start を呼び出すと、プログラムが引き続き実行されることです。これには、関係者にスプラッシュ スクリーンが完了したことを伝える何らかの種類のリスナーが必要になります。

または、装飾されていないモーダルを使用することもできますJDialog

于 2013-02-16T21:35:40.217 に答える
1

コードで行った多くの間違い...

  1. Image を描画paintする代わりにメソッドをオーバーライドしました。paintComponent
  2. コンポーネント ( )Threadのイメージの描画と削除に使用しました。代わりにjavax.swing.Timerを使用してください。SwingJPanel
  3. を使用する必要がありますjavax.swing.Timerが、それでも基本的な間違いは、静的スレッドを作成し、Splasherその中で現在のオブジェクトではなく新しいオブジェクトを渡したことです。
  4. の Graphics を変更するたびに、明示的にComponent呼び出す必要があります。repaintたとえば、3 秒後に画像を非表示にしたい場合は、3 秒後にメソッドを呼び出す必要があり、その画像を削除するメソッドrepaint内に適切なロジックを記述する必要があります。paintComponent

これは、あなたが探していることを正確に実行しているコードの修正版です。それを見てください。

import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentAdapter;

import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.JFrame;
import javax.swing.Timer;
import javax.swing.SwingUtilities;

public class Splasher extends JPanel {

    private static final long serialVersionUID = 1L;
    Image image;
    ImageIcon splash = new ImageIcon("apple.png");
    MyComponentListener componentListener ;
    Timer timer ;

    public Splasher() 
    {
        componentListener = new MyComponentListener();
        setFocusable(true);
        image = splash.getImage();  
        timer = new Timer(3000, new LoadAction());
        addComponentListener(componentListener);
     }
    boolean hasRan = false;

    @Override
    public void paintComponent(Graphics g) 
    {
        super.paintComponent(g);
        if (image == null && timer !=null )
        {
            g.clearRect(0, 0, getWidth(), getHeight()) ;
            timer.stop();
            removeComponentListener(componentListener);
        }
        else
        {
            g.drawImage(image, 0, 0, null);
        }
    }
    public Image getImage() 
    {
        return image;
    }
    private class MyComponentListener extends ComponentAdapter
    {
        @Override
        public void componentResized(ComponentEvent evt)
        {
            System.out.println("Resized..");
            timer.start();
        }
    }
    private class LoadAction implements ActionListener 
    {
        public void actionPerformed(ActionEvent evt)
        {
            System.out.println("Drawing Splash Screen");
            repaint();
            image = null;
            repaint();
            System.out.println("Repainted");
        }

    }
    public static void main(String st[])
    {
        SwingUtilities.invokeLater ( new Runnable()
        {
            @Override
            public void run()
            {
                JFrame frame = new JFrame("Splash:");
                frame.getContentPane().add(new Splasher());
                frame.setSize(300,500);
                frame.setVisible(true);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            }
        });
    }
}

Java での Paint メカニズムについては、次のチュートリアルもご覧ください。 http://docs.oracle.com/javase/tutorial/uiswing/painting/closer.html

于 2013-02-16T21:52:04.507 に答える