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构造函数中,您尝试将 a 添加JFrame到新Ass3_10203038实例(这是 a JApplet,因此是容器)。由于JFrameonly 持有 a JPanel,因此您可以通过直接将 the 添加JPanelAss3_10203038实例来解决此问题。当作为 Applet 运行时,这至少会显示您的 UI。

接下来,单击一个按钮将生成一个NullPointerException. 发生这种情况是因为您paintComponent直接调用,fan作为Graphics参数传入 - 但您从未初始化fan代码中的任何内容,因此它始终为空。作为一种解决方案,您不应该paintComponent直接调用,因为您没有Graphics用于在屏幕上绘制的对象。不过 Swing 系统有这个对象,所以我们可以要求它重新绘制而不是paintComponent直接调用:

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和覆盖该run方法,或者将 a 传递RunnableThread. 但是,我认为 rawThread不会让我们到达任何地方,因为它们仍然没有真正解决时间问题。我建议你调查一下javax.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 回答