2017-02-20 5 views
0

Javaでカスタム読み込み画面を作成しようとしています(JProgressBarを使用していません)。今私はちょうど黒い矩形で左から右の画面をゆっくりと塗りつぶすローディングバーを作ってみました。これをテストするために、乱数を考慮する単純なプログラムを作った。ファクタリングコードを別のスレッドで実行し、グラフィックスに100ミリ秒ごとに1回の分解処理が行われるようにします。ただし、アプリケーションが10秒間応答しなくなり、その後も実行されることがあります。 Javaでカスタム読み込み画面を正しく実装するにはどうすればよいですか。ここでJavaでカスタム読み込み画面を正しく実装する方法

はコードです:ここでは

public class Factorer implements Runnable, Loadable { 

    private static Random r = new Random(); 

    private volatile int numOn; 

    private volatile int numsTotal; 

    public static void main(String[] args){ 

     Factorer fact = new Factorer(25); 

     LoadingFrame f = new LoadingFrame(fact); 
     fact.run(); 

    } 

    public Factorer(int nNums){ 

     numsTotal = nNums; 

    } 

    public void factorRandomNumber(){ 

     int randomNumber = r.nextInt(Integer.MAX_VALUE); 

     int n = randomNumber; 

     List<Integer> factors = new ArrayList<Integer>(); 

     for (int i = 2; i <= n; i++) { 

      while (n % i == 0) { 

       factors.add(i); 
       n /= i; 

      } 

     } 

    } 

    public void factorRandomNumbers(){ 

     for(numOn = 0; numOn < numsTotal; numOn++){ 

      factorRandomNumber(); 

     } 

    } 

    public float getProgress(){ 

     return ((float) numOn)/((float) numsTotal); 

    } 

    @Override 
    public void run() { 

     factorRandomNumbers(); 

    } 

} 

は、ロード可能なインタフェースである:ここで

public interface Loadable { 

    public float getProgress(); 

} 

は、グラフィックスクラスです:

public class LoadingFrame extends JFrame { 

    private static final long serialVersionUID = 8290713730328501888L; 

    private static final int WIDTH = 400; 
    private static final int HEIGHT = 400; 

    private Loadable loadable; 

    public LoadingFrame(Loadable l){ 

     super("Loading Test"); 

     this.loadable = l; 

     this.setSize(WIDTH, HEIGHT); 
     this.setResizable(false); 
     this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     this.setVisible(true); 

     Timer t = new Timer(100, new ActionListener(){ 

      @Override 
      public void actionPerformed(ActionEvent e) { 

       repaint(); 

      } 

     }); 

     t.start(); 

    } 

    @Override 
    public void paint(Graphics g){ 

     g.setColor(Color.BLACK); 

     g.fillRect(0, 0, (int) (loadable.getProgress() * (float) WIDTH), HEIGHT); 

    } 

} 
+3

['SplashScreen'](http://docs.oracle.com/javase/8/docs/api/java/awt/SplashScreen.html)を参照してください。速度については、それは完全にAWTベースです。チュートリアルの[スプラッシュスクリーンの作成方法](http://docs.oracle.com/javase/tutorial/uiswing/misc/splashscreen.html)も参照してください。 –

+0

@AndrewThompsonは、プログラムが既に起動した後、読み込み画面を表示したい場合は、その作業を行いますか? –

+0

AFAIUはい、私はそれを使ったことはありません。 –

答えて

1

私はファクタリングコードを実行します別のスレッドで

まあ、はい、いいえ。 Factorerクラスはrunnableを実装しますが、クラスを別のスレッドとして扱うことはありません。

代わりに、あなただけの使用:

fact.run(); 

あなたがどこかにあなたのコード内であなたが持っているでしょう、再利用可能な独立したスレッドとして、このクラスを使用しようとしている場合:

new Thread(new Factorer()).start(); 

実際にスレッドを開始します。

しかし、Event Dispatch Thread (EDT)とは別のスレッドでJVMが起動するため、コードは別のスレッドで実行されますが、設計よりもチャンスが多くなります。

また、Factorerクラスのロジックは機能しません。これは、getProgress()メソッドを呼び出すと常に同じ値が返されるためです。つまり、プログラムの開始時にfactoroRandomNumbers()の番号が1回実行され、numOnnumsTotalが最終値に初期化されます。

public void paint(Graphics g){ 

paint()をオーバーライドしないでください。 JPaneelでpaintComponent(...)をオーバーライドしてカスタムペインティングを行い、フレームをパネルに追加します。

タイマーロジックが正しくありません。あなたが行うのはrepaint()を呼び出すことですが、前に述べたように、返された値は決して変更されません。本当に必要なのは、getNextValue()のようなメソッドを呼び出すことです。このメソッドは、乱数を含むListから値を取得します。

スウィングの仕組みを理解するには、Swing Tutorialを読む必要があります。あなたは上のセクションで開始したいことがあります。

おそらく使用する方が簡単だろう絵画カスタム実行

  • Swingで

    1. 同時実行SwingWorker(Swingのセクションの同時実行で説明したように)。これにより、別のスレッドが作成されます。次に、ランダムな値を生成し、この値を「公開」するループコードがあります。この値が公開されると、値をフレームに再描画します。

  • 関連する問題