使用java运行风扇
我需要模拟一个运行的风扇,有3个按钮(启动、反转、停止)和一个滚动条来控制速度。 我写了一个代码,但他们没有错误,但它不工作。 起初,类扩展了Jframe,出现了带有按钮和扇形弧的窗口,但当它扩展了Japplet时,它没有出现。 但这并不是双向的使用java运行风扇,java,multithreading,swing,user-interface,Java,Multithreading,Swing,User Interface,我需要模拟一个运行的风扇,有3个按钮(启动、反转、停止)和一个滚动条来控制速度。 我写了一个代码,但他们没有错误,但它不工作。 起初,类扩展了Jframe,出现了带有按钮和扇形弧的窗口,但当它扩展了Japplet时,它没有出现。 但这并不是双向的 package Ass3_10203038; import javax.swing.JFrame; import javax.swing.JPanel; import java.awt.Graphics; import javax.swing.JBu
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);
}
}
}
包Ass3_10203038;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入java.awt.Graphics;
导入javax.swing.JButton;
导入javax.swing.*;
导入java.awt.*;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.awt.adj;
导入java.awt.event.AdjustmentEvent;
导入java.awt.event.AdjustmentListener;
导入java.util.concurrent.locks.Lock;
导入java.util.concurrent.locks.ReentrantLock;
导入java.util.logging.Level;
导入java.util.logging.Logger;
公共类Ass3_10203038扩展JApplet实现可运行{
私人静电
Lock Lock=新的可重入锁();
图形风扇;
JButton start=新JButton(“start”);
JButton stop=新JButton(“stop”);
JButton reverse=新JButton(“reverse”);
JScrollBar速度=新的JScrollBar();
线程计时器=新线程();
int-thr=50;
int-strtpt=0;
JFrame=新JFrame();
@凌驾
公开募捐{
重新油漆();
while(true){
试一试{
睡眠(thr);
}捕捉(中断异常e){
e、 printStackTrace();
}
}
}
公共助理3_10203038(){
最终圆弧面板圆弧=新圆弧面板();
JPanel p=新的JPanel();
p、 设置大小(500500);
p、 添加(弧);
//p.设置尺寸(5000,5000);
p、 添加(开始);
p、 添加(停止);
p、 添加(反向);
p、 加(速度);
p、 setLayout(新的GridLayout());
框架。添加(p);
添加(框架);
帧。设置标题(“风扇”);
start.addActionListener(新ActionListener(){
已执行的公共无效操作(操作事件e){
timer.start();
对于(int x=strtpt;x-1;x--)
{if(x==0)
x=360;
其他的
弧。初始值(x);
弧。油漆组件(风扇);
strtpt=x;
}
}});
speed.addAdjustmentListener(新的AdjustmentListener(){
公共无效调整值已更改(调整事件ae){
试一试{
开关(thr){
案例调整事件单位增量:
线程睡眠(thr+=2);
打破
案例调整事件单位减量:
线程睡眠(thr-=2);
打破
}
int value=ae.getValue();
}捕获(中断异常例外){
Logger.getLogger(Ass3_10203038.class.getName()).log(Level.SEVERE,null,ex);
}
}
});
}
/**
*主要方法
*/
公共静态void main(字符串[]args){
Ass3_10203038窗口=新Ass3_10203038();
设置窗口大小(500500);
setLocation(50,50);//使框架居中
//frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setVisible(true);
}
}
//用于在配电盘上绘制圆弧的类
类ArcsPanel扩展了JPanel{
//画出风扇的四个叶片
公共int initializex(int x){
返回x;
}
公共组件(图形g){
超级组件(g);
int xCenter=getWidth()/2;
int yCenter=getHeight()/2;
int半径=(int)(数学最小值(getWidth(),getHeight())*0.4);
int x=xCenter-半径;
int y=圆心-半径;
{
g、 圆角弧(x,y,2*半径,2*半径,0+初始值x,30);
g、 圆角弧(x,y,2*半径,2*半径,90+初始值x,30);
g、 圆角弧(x,y,2*半径,2*半径,180+初始值x,30);
g、 圆角弧(x,y,2*半径,2*半径,270+初始值x,30);
}
}
}
这段代码有很多问题,我不会尝试解决所有问题。不过,我会列出我注意到的问题,并描述出问题所在
首先,您的代码会崩溃,出现一个异常:
java.lang.IllegalArgumentException: adding a window to a container
这发生在Ass3_10203038
构造函数中,您尝试将JFrame
添加到新的Ass3_10203038
实例(它是JApplet
,因此是一个容器)。由于JFrame
只保存JPanel
,因此可以通过直接将JPanel
添加到Ass3\u 10203038
实例来解决此问题。这将至少在作为小程序运行时显示您的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;
}
然而,由于timer
只是一个空白的线程
对象,所以这一行绝对不做任何事情(至少,对您的程序没有任何重要意义)。为了在线程中运行代码,您必须扩展thread
并重写run
方法,或者将Runnable
传递给thread
的构造函数。然而,我认为rawThread
s不会在这里取得任何进展,因为它们仍然不能真正解决计时问题。我建议您研究一下javax.swing.Timer
即使这样
timer.start();
g.fillArc(x, y, 2 * radius, 2 * radius, 0 + initializex(x), 30);
g.fillArc(x, y, 2 * radius, 2 * radius, 0 + x, 30);
/*
* 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);
}
}
}