- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我需要模拟一个正在运行的风扇,有 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 线程上运行此循环,它会卡住整个窗口。除此之外,风扇会非常快速旋转,因为在这个循环中没有计时 - 它会以计算机所能达到的速度运行,这确实非常快。
显然,您试图通过使用名为 timer
的 Thread
来解决此问题:
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/
在 C/C++ 中是否有 Windows 标准方法来执行“启动风扇”、“降低速度”等操作? 我怀疑它可能是 ACPI,但我是一个虚弱的凡人,无法阅读那种文档。 编辑:例如Windows 7 允许您在电
我是一名优秀的程序员,十分优秀!