2016-04-20 10 views
0

私はそれぞれ別のスレッドにある4つの車オブジェクトを作成しようとしていますが、それぞれの車をユーザーが入力する異なる速度で移動させる方法を理解することはできません。ここjavaでマルチスレッドを使用していますか?

public class Racecar extends JApplet { 

public Racecar() { 
    setLayout(new GridLayout(5, 1)); 
    JPanel panel1 = new JPanel(); 
    JLabel car1 = new JLabel("Car 1:"); 
    panel1.add(car1); 
    JTextField jtfcar1 = new JTextField(3); 
    panel1.add(jtfcar1); 
    JLabel car2 = new JLabel("Car 2:"); 
    panel1.add(car2); 
    JTextField jtfcar2 = new JTextField(3); 
    panel1.add(jtfcar2); 
    JLabel car3 = new JLabel("Car 3:"); 
    panel1.add(car3); 
    JTextField jtfcar3 = new JTextField(3); 
    panel1.add(jtfcar3); 
    JLabel car4 = new JLabel("Car 4:"); 
    panel1.add(car4); 
    JTextField jtfcar4 = new JTextField(3); 
    panel1.add(jtfcar4); 
    add(panel1, BorderLayout.NORTH); 

    JPanel panel2 = new JPanel(); 
    panel2.setBorder(BorderFactory.createLineBorder(Color.black)); 
    DrawCar car = new DrawCar(1); 
    panel2.add(car); 
    add(panel2); 

    JPanel panel3 = new JPanel(); 
    panel3.setBorder(BorderFactory.createLineBorder(Color.black)); 
    DrawCar car10 = new DrawCar(2); 
    panel3.add(car10); 
    add(panel3); 

    JPanel panel4 = new JPanel(); 
    panel4.setBorder(BorderFactory.createLineBorder(Color.black)); 
    DrawCar car11 = new DrawCar(3); 
    panel4.add(car11); 
    add(panel4); 

    JPanel panel5 = new JPanel(); 
    panel5.setBorder(BorderFactory.createLineBorder(Color.black)); 
    DrawCar car12 = new DrawCar(4); 
    panel5.add(car12); 
    add(panel5); 

} 

public static void main(String[] args) { 
Racecar applet = new Racecar(); 
applet.init(); 
applet.start(); 
JFrame frame = new JFrame(); 
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
frame.setTitle(""); 
frame.getContentPane().add(applet, BorderLayout.CENTER); 
frame.setSize(400, 320); 
frame.setVisible(true); 


    // Create tasks 
Runnable race1 = new DrawCar(1); 
Runnable race2 = new DrawCar(2); 
Runnable race3 = new DrawCar(3); 
Runnable race4 = new DrawCar(4); 

// Create threads 
Thread thread1 = new Thread(race1); 
Thread thread2 = new Thread(race2); 
Thread thread3 = new Thread(race3); 
Thread thread4 = new Thread(race4); 

// Start threads 
thread1.start(); 
thread2.start(); 
thread3.start(); 
thread4.start(); 
} 

} 

そして、私のDrawCar方法である:

public class DrawCar extends JPanel implements ActionListener, Runnable { 
private int delay = 10; 
private Timer timer = new Timer(delay, this); 
private int x1 = 20; 
private int y1 = 22; 
int r = (int)(Math.random()*256); 
int q =(int)(Math.random()*256); 
int b = (int)(Math.random()*256); 
Color color = new Color(r, q, b); 

public DrawCar(int x) { 
timer.start(); 
} 

public void actionPerformed(ActionEvent e) { 
    repaint(); 
} 

protected void paintComponent(Graphics g) { 
super.paintComponent(g); 
g.setColor(color); 
g.fillRoundRect(x1, y1, 75, 20, 10, 10); 
g.fillArc(x1, y1 - 10, 50, 15, 0, 180); 
g.fillOval(x1 + 2, y1 + 10, 20,20); 
g.fillOval(x1 + 40, y1 + 10, 20, 20); 
if(x1 > getWidth()) { 
    x1 = -100; 
} 
    x1 += 1; 

repaint(); 
} 

public Dimension getPreferredSize() { 
    return new Dimension(400, 320); 
    } 

private class TimerListener implements ActionListener { 

public void actionPerformed(ActionEvent e) { 
    repaint(); 
} 
} 

public void run() { 

    try { 

    //int x = Racecar.getSpeed(); 

    Thread.sleep(1500); 

    } 
    catch (InterruptedException ex) { 
    } 

} 

} 
+0

* * "私は別のスレッドでそれぞれ4つの車のオブジェクトを作成しようとしている" 役立つだろう - まあありますがそこに問題があります。代わりに、すべての車を更新する単一のスレッド、各車がオブジェクトであって、各サイクルでどのくらいの変更が発生するかを決定する独自の速度プロパティを持つ必要があります – MadProgrammer

答えて

0

あなたは彼らの速度は、通常のようにしたい場合は動作しません独自のスレッドでそれぞれの車を実行する

はここに私のメインのプログラムです。 OSが任意のスレッドをスケジュールする時期と頻度については保証されていません。車Aは車Bの2倍のスケジュールになっている可能性があるので、たとえ同じ速度であっても、A車がはるかに速くなるように見えます。

また、スレッドはスイングと互換性がないことに注意してください。

あなたがスレッドを使用する必要がある場合は、それを行う方法についてのチュートリアルを参照してください。私の意見でhttp://docs.oracle.com/javase/tutorial/essential/concurrency/simple.html

あなたはこの作業のために、すべてのスレッドを使用しないでください - ちょうどループの中で車を更新します。スレッドを使用する必要がある場合は、少なくとも1つのスレッドを使用してすべての車を更新します。

4

私はまあすぐそこに問題があります別のスレッド

にそれぞれ4つの車のオブジェクトを作成しようとしています。いくつかの理由があります。スイングはスレッドセーフではないため、UIとの同期が外れている可能性のある異なるスレッド間の競合状態や不正な読み取り/書き込みを危険にさらしています。

代わりに、すべての車を更新する1つのスレッドが必要です。各車はオブジェクトであり、各サイクルでどれだけの変更が発生するかを決定する独自の速度プロパティを持ちます。

車ごとにJPanelを作成するのではなく、すべての車のペイントを担当していたJPanelという単一のタイヤを使用します。これにより、パフォーマンスが向上しますが、扱いがさらに容易になります。

詳細については、Concurrency in Swingをご覧ください。

スイングのシングルスレッドの性質のため、スレッドを使用する代わりにHow to use Swing Timersも見ています。

これは非常に悪い考えです...

protected void paintComponent(Graphics g) { 
    super.paintComponent(g); 
    //... 
    if(x1 > getWidth()) { 
     x1 = -100; 
    } 
    x1 += 1; 
    repaint(); 
} 

絵画ので、あなたのオブジェクトが原因で速くない移動することができ、あなたがコントロールしていないその多くが異なる理由の多くのために発生する可能性がありますどのようなスレッドはやっていますが、コンポーネントが塗りつぶされるたびにシステムが何をしているのかによって、基本的には制御できません。

ペイントはペイント用です。それ以外の方法はありません。ペイント方法内でコンポーネントの状態を更新しないでください。

また、あなたがpaintメソッド内から(直接または間接的に)repaintを呼び出すことはありません、これは最終的に、すべてのCPUサイクルを消費します暴走再描画サイクルを引き起こす非常に迅速に起こっています。

たぶんもっと

Race

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Point; 
import java.awt.Rectangle; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.ArrayList; 
import java.util.List; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.Timer; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class Test { 

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

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

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     private List<Car> cars; 

     public TestPane() { 
      cars = new ArrayList<>(4); 
      Color[] colors = new Color[]{Color.RED, Color.GREEN, Color.BLUE, Color.MAGENTA}; 
      int yPos = 0; 
      int speed = 1; 
      for (Color color : colors) { 
       Car car = new Car(new Point(0, yPos += 30), speed++, color); 
       cars.add(car); 
      } 
      Timer timer = new Timer(40, new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        for (Car car : cars) { 
         car.update(getSize()); 
        } 
        repaint(); 
       } 
      }); 
      timer.start(); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(200, 200); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D) g.create(); 
      for (Car car : cars) { 
       car.paint(g2d); 
      } 
      g2d.dispose(); 
     } 

    } 

    public class Car { 
     private Point location; 
     private Dimension size; 

     private int speed; 
     private Color color; 

     public Car(Point location, int speed, Color color) { 
      this.location = location; 
      this.speed = speed; 
      this.color = color; 

      size = new Dimension(20, 20); 
     } 

     public void update(Dimension bounds) { 
      location.x += speed; 
      if (location.x + size.width > bounds.width) { 
       location.x = bounds.width - size.width; 
       speed = 0; 
      } 
     } 

     public void paint(Graphics2D g2d) { 
      g2d.setColor(color); 
      g2d.fill(new Rectangle(location, size)); 
     } 

    } 

} 

...のようなものが

関連する問題