2016-10-17 3 views
2

このコードは以下のとおりですか? ArrayListに新しい楕円を200ミリ秒ごとに追加して表示し、1つずつ実行したいと考えています。 1つのパーティクルs.runner()を実行しているときにうまく動作します。それは私のすべての粒子を実行するように見えません。graphics2Dのリスト

MAIN:

import java.awt.EventQueue; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.ArrayList; 
import javax.swing.JFrame; 
import javax.swing.Timer; 

public class ExempelGraphics extends JFrame implements ActionListener { 
    Timer t; 
    private int inc = 0; 
    ArrayList<Surface> particle = new ArrayList<>(); 
    Surface s; 

    public ExempelGraphics() { 
     t = new Timer(10, this); 
     t.start(); 
     s = new Surface(10, 10); 
     initUI(); 
    } 

    private void initUI() { 
     add(s); 
     setSize(350, 250); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    } 

    public void actionPerformed(ActionEvent e) { 
//  s.runner(); 
     // add 
     if (inc++ % 20 == 0) { 
      particle.add(new Surface(10, 10)); 
     } 

     // display 
     for (int i = 0; i < particle.size(); i++) { 
      Surface p = particle.get(i); 
      p.runner(); 
     } 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       ExempelGraphics ex = new ExempelGraphics(); 
       ex.setVisible(true); 
      } 
     }); 
    } 
} 

グラフィックス:

import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import javax.swing.JPanel; 

public class Surface extends JPanel { 
    private int locX = 0; 
    private int locY = 0; 

    public Surface(int locX, int locY) { 
     this.locX = locX; 
     this.locY = locY; 
    } 

    public void runner() { 
     locX = locX + 1; 
     repaint(); 
    } 

    @Override 
    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     Graphics2D g2d = (Graphics2D) g; 
     g2d.setColor(Color.RED); 
     g2d.fillOval(locX, locY, 10, 10); 
    } 
} 

答えて

2

私はあなたがプログラム構造が壊れていると思います。ここで描画を行うJPanelは1つしかなく、paintComponentはオーバーライドされていて、Surfaceクラスは論理クラスであり、コンポーネントクラスではない、つまりJPanelを継承しないでくださいそれはpublic void draw(Graphics g)楕円を描く方法です。次に、JPanelにこれらのサーフェスのArrayListを保持させ、メインのJPanelのpaintComponentメソッドでサーフェスを反復処理し、それぞれのdrawメソッドを呼び出します。

また、タイマーの遅延は現実的ではなく、小さすぎます。 15ははるかに現実的です。

また、面内からrepaint()を呼び出さないでください。不要な再描画呼び出しが多すぎるためです。代わりに、すべてのSurfaceオブジェクトでランナーメソッドを呼び出した後、TimerのActionListenerから呼び出すことができます。

また、JFrameのcontentPaneにデフォルトの方法でコンポーネントを追加するたびに、以前に追加されたコンポーネントを隠すことにも注意してください。上記の推奨事項に従えば、JPanelを追加するだけなので、これは問題ではありません。例えば

import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.RenderingHints; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.ArrayList; 
import java.util.List; 
import javax.swing.*; 

@SuppressWarnings("serial") 
public class ExampleGraphics2 extends JPanel { 
    private static final int PREF_W = 650; 
    private static final int PREF_H = 500; 
    private static final int TIMER_DELAY = 20; 
    private List<Surface> surfaces = new ArrayList<>(); 

    public ExampleGraphics2() { 
     new Timer(TIMER_DELAY, new TimerListener()).start(); 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     Graphics2D g2 = (Graphics2D) g; 
     g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
     for (Surface surface : surfaces) { 
      surface.draw(g); 
     } 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     if (isPreferredSizeSet()) { 
      return super.getPreferredSize(); 
     } 
     return new Dimension(PREF_W, PREF_H); 
    } 

    private class TimerListener implements ActionListener { 
     private int index = 0; 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      index++; 
      index %= 20; 
      if (index == 0) { 
       surfaces.add(new Surface(10, 10)); 
      } 

      for (Surface surface : surfaces) { 
       surface.runner(); 
      } 
      repaint(); 
     } 
    } 

    private static void createAndShowGui() { 
     JFrame frame = new JFrame("Example Graphics 2"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(new ExampleGraphics2()); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(() -> createAndShowGui()); 
    } 
} 

package foo1; 

import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 

public class Surface { 
    private int locX = 0; 
    private int locY = 0; 

    public Surface(int locX, int locY) { 
     this.locX = locX; 
     this.locY = locY; 
    } 

    public void runner() { 
     locX = locX + 1; 
    } 

    public void draw(Graphics g) { 
     Graphics2D g2d = (Graphics2D) g; 
     g2d.setColor(Color.RED); 
     g2d.fillOval(locX, locY, 10, 10); 
    } 
} 
0

ありがとう!

私は自分でコードを実装しました。おそらくもっと良くないかもしれませんが、理解するのは簡単です:-)。私は今、サーフェスクラスの新しいパネルを作成せず、メインクラスのpaincomponentを実行しています。それは今働く

私はもう一つの質問がある。

私は常にメインmehtodにこのように書いて:

public static void main(String[] args) { 
    EventQueue.invokeLater(new Runnable() { 

     @Override 
     public void run() { 
      ExempelGraphics ex = new ExempelGraphics(); 
      ex.setVisible(true); 
     } 
    }); 

私はあなたが書いた気づい:

public static void main(String[] args) { 
    SwingUtilities.invokeLater(() -> createAndShowGui()); 
} 

を違いは何ですか?自分の書く方法を実装しようとしましたが失敗しました:-)申し訳ありません。私は純粋なJavaにかなり新しいです。とにかくHERESに(あなたのメインメソッドで)私の完全なコード

メイン:

import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.RenderingHints; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.ArrayList; 
import java.util.List; 
import javax.swing.*; 

@SuppressWarnings("serial") 

public class ExempelGraphics extends JPanel implements ActionListener { 

    Timer t; 

    private int index = 0; 

    private List<Surface> surfaces = new ArrayList<>(); 

    public ExempelGraphics() { 
     t = new Timer(10, this); 
     t.start(); 
    } 

    @Override 
    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     Graphics2D g2 = (Graphics2D) g; 

     g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
     for (Surface surface : surfaces) { 
      surface.theRunner(g); 
     } 
    } 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     index++; 
     if (index % 20 == 0) { 
      surfaces.add(new Surface(10, 10)); 
     } 

     for (Surface surface : surfaces) { 
      surface.runner(); 
     } 
     repaint(); 
    } 

    private static void initGUI() { 
     JFrame frame = new JFrame("Titel"); 

     frame.getContentPane().add(new ExempelGraphics()); 
     frame.setSize(300, 300); 
     frame.setVisible(true); 
    } 


    public static void main(String[] args) { 
     SwingUtilities.invokeLater(() -> initGUI()); 
    } 
} 

表面クラス:

import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 

public class Surface { 
    private int locX = 0; 
    private int locY = 0; 

    public Surface(int locX, int locY) { 
     this.locX = locX; 
     this.locY = locY; 
    } 

    public void runner() { 
     locX = locX + 1; 
    } 

    public void theRunner(Graphics g) { 
     Graphics2D g2d = (Graphics2D) g; 
     g2d.setColor(Color.RED); 
     g2d.fillOval(locX, locY, 10, 10); 
    } 
} 
0

Okej。わかりました。私はそれを私の古いやり方をやってみましたが、コンストラクタでinitGUIを実行しているにStackOverflowError

なっている。さらに下 のpublic static無効メイン(文字列[] args)

JFrame frame; 

public ExempelGraphics() { 
    t = new Timer(10, this); 
    t.start(); 
    initGUI(); 
} 

public void initGUI() { 
    frame = new JFrame("Titel"); 
    frame.getContentPane().add(new ExempelGraphics()); 
    frame.setSize(300, 300); 
    frame.setVisible(true); 
} 

をし、{ EventQueue.invokeLater (新しいRunnableを(){

 @Override 
     public void run() { 
      ExempelGraphics ex = new ExempelGraphics(); 
      ex.setVisible(true); 
     } 
    }); 

私はあなたの答えを受け入れることを確認:)は(私はすでにかかわらupvoted)

+0

質問の回答は投稿しないでください。これは別の新しい問題です。しかしここで何をやっているのか - コンストラクタでは、クラスの別のインスタンスを作成するメソッドを呼び出します。このメソッドは、そのコンストラクタを呼び出して、クラスの別のインスタンスを作成します。そのコンストラクタを呼び出すクラスは、そのコンストラクタを呼び出すクラスの別のインスタンスを作成します。あなたは不必要に再帰しています。 –

関連する問題