0

速度を制御するために、3つのボタン(開始、反転、停止)とスクロールバーを備えた実行中のファンをシミュレートする必要があります。私はコードを書きましたが、エラーはありませんが、機能していません。最初はクラス拡張Jframeとファンのボタンと円弧のあるウィンドウが表示されましたが、Jappletを拡張すると表示されませんでした。しかし、それは両方の方法で機能しませんでした。

package Ass3_10203038;

import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Graphics;
import javax.swing.JButton;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import  java.awt.Adjustable;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Ass3_10203038 extends JApplet implements Runnable {
private static
    Lock lock = new ReentrantLock();
Graphics fan;
JButton start = new JButton("Start");
JButton stop = new JButton("Stop");
JButton reverse = new JButton("Reverse");
JScrollBar speed = new JScrollBar();
Thread timer = new Thread();
int thr=50;
int strtpt=0;
 JFrame frame= new JFrame();

@Override
public void run() {
    repaint();
    while (true) {
        try {
            Thread.sleep(thr);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

  }

   public Ass3_10203038() {
    final ArcsPanel arcs = new ArcsPanel();

    JPanel p = new JPanel();

    p.setSize(500, 500);
    p.add(arcs);
  //  p.setSize(5000, 5000);
    p.add(start);
    p.add(stop);
    p.add(reverse);
    p.add(speed);
    p.setLayout(new GridLayout());

   frame.add(p);
  add(frame);

   frame.setTitle("Fan");
    start.addActionListener(new ActionListener(){
   public void actionPerformed(ActionEvent e){
  timer.start();

  for(int x=strtpt;x<362;x++)
 {if(x==361)
 x=0;
 else         
  arcs.initializex(x);
  arcs.paintComponent(fan);
 strtpt=x;
  }   


 }
 });

        stop.addActionListener(new ActionListener(){
 public void actionPerformed(ActionEvent e){

  lock.lock();

   timer.start();

}
});

         reverse.addActionListener(new ActionListener(){
  public void actionPerformed(ActionEvent e){
   timer.start();
    for(int x=strtpt;x>-1;x--)
    {if(x==0)
    x=360;

  else
    arcs.initializex(x);
      arcs.paintComponent(fan);
    strtpt=x;

     }


         }});

            speed.addAdjustmentListener(new AdjustmentListener(){
                    public void adjustmentValueChanged(AdjustmentEvent ae){
                        try {
                            switch (thr){
                                    case AdjustmentEvent.UNIT_INCREMENT:
                                   Thread.sleep( thr+=2);
                                break;

                                    case AdjustmentEvent.UNIT_DECREMENT:
                                      Thread.sleep(thr-=2);
                                        break;
                                            }
                            int value = ae.getValue();
                        } catch (InterruptedException ex) {
                            Logger.getLogger(Ass3_10203038.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }

            });

    }
   /**
   * Main method
   */
   public static void main(String[] args) {
    Ass3_10203038  window = new Ass3_10203038();

    window.setSize(500, 500);

    window.setLocation(50, 50); // Center the frame
     // frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.setVisible(true);

   }
  }

 // The class for drawing arcs on a panel
  class ArcsPanel extends JPanel {
   // Draw four blades of a fan

   public int initializex(int x){

  return x;
   }

public void paintComponent(Graphics g) {
    super.paintComponent(g);

    int xCenter = getWidth() / 2;
    int yCenter = getHeight() / 2;
    int radius = (int) (Math.min(getWidth(), getHeight()) * 0.4);


    int x = xCenter - radius;
    int y = yCenter - radius;

    {
        g.fillArc(x, y, 2 * radius, 2 * radius, 0+initializex(x), 30);
        g.fillArc(x, y, 2 * radius, 2 * radius, 90+initializex(x), 30);
        g.fillArc(x, y, 2 * radius, 2 * radius, 180+initializex(x), 30);
        g.fillArc(x, y, 2 * radius, 2 * radius, 270+initializex(x), 30);

    }

  }
   }
4

2 に答える 2

1

このコードにはかなりの問題があり、それらすべてに対処するつもりはありません。ただし、私が気づいたものをリストし、何が問題なのかを説明します。

まず、コードが例外でクラッシュします。

java.lang.IllegalArgumentException: adding a window to a container

これはコンストラクターで発生し、新しいインスタンス (つまりコンテナー)Ass3_10203038に を追加しようとします。はのみを保持するため、 をインスタンスに直接追加することでこれを回避できます。これにより、少なくともアプレットとして実行しているときに UI が表示されます。JFrameAss3_10203038JAppletJFrameJPanelJPanelAss3_10203038

次に、ボタンをクリックすると、 が生成されますNullPointerException。これは、パラメーターとしてpaintComponent渡して直接呼び出すために発生しますが、コード内で初期化することはないため、常に null になります。解決策として、画面に描画するために使用できるオブジェクトがないため、直接呼び出すべきではありません。ただし、Swing システムにはこのオブジェクトがあるため、直接呼び出す代わりに再描画を要求できます。fanGraphicsfanpaintComponentGraphicspaintComponent

arcs.repaint();

ただし、ボタンを押すと、プログラムは無限ループに入ります。何が起こるかというと、このループは決して終わらないということです:

for (int x = strtpt; x < 362; x++)
{
    if (x == 361)
        x = 0;
    else
        arcs.initializex(x);
    arcs.repaint();
    strtpt = x;
}

x が 362 に達することはないため、常にループし続けます。ファンを継続的に回転させたい場合、これはある程度理にかなっていますが、UI スレッドでこのループを実行しているため、ウィンドウ全体がフリーズします。それとは別に、このループにはタイミングがないため、ファンは非常に速く回転ます。コンピューターが実行できる限りの速さで、実際にはかなり高速です。

どうやら、Thread呼び出された を使用してこの問題を解決しようとしたようですtimer:

timer.start();

ただし、timerは単なる空のThreadオブジェクトであるため、この行はまったく何もしません (少なくとも、プログラムにとって重要なことは何もありません)。スレッドでコードを実行するには、メソッドを拡張Threadしてオーバーライドするか、 のコンストラクターにruna を渡す必要があります。しかし、まだタイミングの問題を実際に解決していないため、raw s でここまでたどり着けるとは思いません。を調べることをお勧めします。RunnableThreadThreadjavax.swing.Timer

これが邪魔にならないにもかかわらず、ファンブレードはまだ動きません. これは、paintComponentメソッドが実際に角度を入力として認識しないためです。initializex(x)上記のループとpaintComponentメソッドで呼び出して角度を渡そうとしているように見えますがinitializex、パラメーターを返す以外は何もしません。渡したものは何でも、すぐに元に戻ります。したがって、このpaintComponentメソッドでは、initializex(x)単純に x の値を返します。これは、コードの代わりに次のことを意味します。

g.fillArc(x, y, 2 * radius, 2 * radius, 0 + initializex(x), 30);

あなたも同じように書いたかもしれません

g.fillArc(x, y, 2 * radius, 2 * radius, 0 + x, 30);

まったく同じ効果があります。

これで、うまくいかなかったいくつかのことが説明されることを願っています。

于 2013-03-19T23:00:09.677 に答える
0

コードを修正しましたが、どうもありがとうございました頭の中でロジックを整理する必要がありました

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package assign3_10203038;

import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.image.ImageObserver;
import java.text.AttributedCharacterIterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollBar;

public class Assign3_10203038 extends JFrame {

private JButton start = new JButton("Start");
private JButton stop = new JButton("Stop");
private JButton reverse = new JButton("Reverse");
private JScrollBar speed = new JScrollBar();
private Thread timer;
private final ArcsPanel arcs;

 public Assign3_10203038() {
    arcs = new ArcsPanel();

    JPanel p = new JPanel();
    p.setSize(5000, 5000);
    p.add(arcs);
    p.add(start);
    p.add(stop);
    p.add(reverse);
    p.add(speed);
    p.setLayout(new GridLayout());
    add(p);

    start.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            timer = new Thread(arcs);
            timer.start();


        }
    });

    speed.addAdjustmentListener(new AdjustmentListener() {
        public void adjustmentValueChanged(AdjustmentEvent ae) {
            System.out.println(ae.getValue());
            arcs.speed(ae.getValue());
        }
    });


    reverse.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            arcs.reverse();

        }
    });

    stop.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            timer.stop();
        }
    });
}

public static void main(String[] args) {
    Assign3_10203038 window = new Assign3_10203038();

    //  (new Thread(window)).start();
    window.setSize(500, 500);

    window.setLocation(50, 50); // Center the frame
    //  window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.setVisible(true);
}
}

class ArcsPanel extends JPanel implements Runnable {
// Draw four blades of a fan

int thr = 1000;
int i = -20;

public void run() {
    while (true) {
        starting_x = (starting_x + i) % 360;
        repaint();
        try {
            Thread.sleep(thr);
        } catch (InterruptedException ex) {
            Logger.getLogger(Assign3_10203038.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

public void reverse() {
    i = -i;
}

 public void speed(int p) {
    thr = 1000 - (p += p) * 5;

 }
 int starting_x;

 public void initializex(int x_val) {
    starting_x = x_val;
 }

 public void paintComponent(Graphics g) {
    super.paintComponent(g);

    int xCenter = getWidth() / 2;
    int yCenter = getHeight() / 2;
    int radius = (int) (Math.min(getWidth(), getHeight()) * 0.4);


 int x = xCenter - radius;
int y = yCenter - radius;

{
g.fillArc(x, y, 2 * radius, 2 * radius, 0 + starting_x, 30);
g.fillArc(x, y, 2 * radius, 2 * radius, 90 + starting_x, 30);
g.fillArc(x, y, 2 * radius, 2 * radius, 180 + starting_x, 30);
g.fillArc(x, y, 2 * radius, 2 * radius, 270 + starting_x, 30);

}

}
}
于 2013-03-24T21:41:20.937 に答える