gpt4 book ai didi

java - 使用java运行风扇

转载 作者:行者123 更新时间:2023-12-01 14:45:04 26 4
gpt4 key购买 nike

我需要模拟一个正在运行的风扇,有 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);

}

}
}

最佳答案

这段代码有很多问题,我不会尝试解决所有问题。不过,我将列出我注意到的问题并描述出现的问题。

首先,您的代码因异常而崩溃:

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

这发生在 Ass3_10203038 构造函数中,您尝试将 JFrame 添加到新的 Ass3_10203038 实例(这是一个 JApplet,从而成为一个容器)。由于 JFrame 仅包含 JPanel,因此您可以通过直接将 JPanel 添加到 Ass3_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 线程上运行此循环,它会卡住整个窗口。除此之外,风扇会非常快速旋转,因为在这个循环中没有计时 - 它会以计算机所能达到的速度运行,这确实非常快。

显然,您试图通过使用名为 timerThread 来解决此问题:

timer.start();

但是,由于 timer 只是一个空白的 Thread 对象,因此这一行绝对不执行任何操作(至少对您的程序没有任何重要作用)。为了在线程中运行代码,您必须扩展 Thread 并重写 run 方法,或者将 Runnable 传递给构造函数线程。然而,我认为原始线程不会让我们到达任何地方,因为它们仍然没有真正解决计时问题。我建议您查看javax.swing.Timer

即使解决了这个问题,您的风扇叶片仍然不会移动。这是因为您的 paintComponent 方法实际上从未将任何角度视为输入。看起来您尝试通过在上面所示的循环和 paintComponent 方法中调用 initializex(x) 来传递角度,但是 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);

效果完全相同。

我希望这可以解释一些出现的问题。

关于java - 使用java运行风扇,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15509774/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com