作为我的编程作业的一部分,我必须在小程序中显示旋转的风扇。
这是我的代码(显示风扇的类):
import javax.swing.*;
import java.awt.*;
public class Fan extends JPanel
{
private int angle1 = -15;
private int angle2 = 75;
private int angle3 = 165;
private int angle4 = 255;
public Fan()
{
this.setSize(600, 400);
Runnable spinner = new SpinFan();
Thread thread1 = new Thread(spinner);
thread1.start();
}
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawOval(200, 150, 150, 150);
g.fillArc(210, 160, 130, 130, angle1, 30);
g.fillArc(210, 160, 130, 130, angle2, 30);
g.fillArc(210, 160, 130, 130, angle3, 30);
g.fillArc(210, 160, 130, 130, angle4, 30);
}
}
class SpinFan implements Runnable
{
@Override
public void run()
{
try
{
while(true)
{
angle1 = (angle1 + 1) % 360;
angle2 = (angle2 + 1) % 360;
angle3 = (angle3 + 1) % 360;
angle4 = (angle4 + 1) % 360;
System.out.println(angle1 + " " + angle2 + " " + angle3 + " " + angle4);
repaint();
Thread.sleep(10);
}
}
catch(InterruptedException ex)
{
System.out.println("Problem while putting thread to sleep.");
}
}
}
用于进一步处理的类(现在只有 Fan 的实例):
import java.awt.*;
import javax.swing.*;
public class FanControl extends JPanel
{
public FanControl()
{
add(new Fan());
}
}
最后,这是 Applet 类:
import java.awt.*;
import javax.swing.*;
public class FanApplet extends JApplet
{
public FanApplet()
{
add(new FanControl());
}
}
现在我已经尝试了很长一段时间的各种东西,所以请不要介意额外的注释掉的代码。 Fan.jav 类工作正常(如果我将其作为应用程序运行,将其放入框架中,我可以看到风扇旋转)。但我就是无法在小程序中让风扇旋转。但是,如果我将诸如 JButton 之类的东西添加到 Fan.java 类中的 Applet 中,它就会起作用。
我错过了什么?使用线程和小程序或 paintComponent()
和小程序时是否存在一些我似乎不知道的复杂情况。
当我将代码作为应用程序运行时,它工作正常。我可以看到旋转的风扇。这是代码:
import javax.swing.*;
import java.awt.*;
public class Fan extends JPanel
{
private int angle1 = -15;
private int angle2 = 75;
private int angle3 = 165;
private int angle4 = 255;
public Fan()
{
Runnable spinner = new SpinFan();
Thread thread1 = new Thread(spinner);
thread1.start();
}
public static void main(String[] args)
{
JFrame frame = new JFrame();
frame.add(new Fan());
frame.setSize(600, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawOval(200, 150, 150, 150);
g.fillArc(210, 160, 130, 130, angle1, 30);
g.fillArc(210, 160, 130, 130, angle2, 30);
g.fillArc(210, 160, 130, 130, angle3, 30);
g.fillArc(210, 160, 130, 130, angle4, 30);
}
class SpinFan implements Runnable
{
@Override
public void run()
{
try
{
while(true)
{
angle1 = (angle1 - 1) % 360;
angle2 = (angle2 - 1) % 360;
angle3 = (angle3 - 1) % 360;
angle4 = (angle4 - 1) % 360;
System.out.println(angle1 + " " + angle2 + " " + angle3 + " " + angle4);
repaint();
Thread.sleep(10);
}
}
catch(InterruptedException ex)
{
System.out.println("Problem while putting thread to sleep.");
}
}
}
}
最佳答案
while(true) .. repaint(); .. Thread.sleep(10);
这完全是错误的动画处理方式。
不要阻塞 EDT(事件调度线程)——发生这种情况时 GUI 将“卡住”。而不是调用 Thread.sleep(n)
实现 Swing Timer
用于重复任务或 SwingWorker
对于长时间运行的任务。请参阅Concurrency in Swing更多细节。
以下来源使用 Thread
在代码中定义,但将 GUI 更新放回 EDT。
但这里真正的问题是动画组件被添加到大小为 0x0 的小程序中。通过将父容器的布局更改为 BorderLayout
,我们可以拉伸(stretch)它以适应可用空间。
EG
import java.awt.*;
import javax.swing.*;
public class FanApplet extends JApplet
{
private int angle1 = -15;
private int angle2 = 75;
private int angle3 = 165;
private int angle4 = 255;
public FanApplet()
{
add(new FanControl());
}
class FanControl extends JPanel
{
public FanControl()
{
// by setting a BorderLayout and adding a component to the CENTER
// (default if no constraint specified) the child component will
// be stretched to fill the available space.
setLayout(new BorderLayout());
add(new Fan());
}
}
class Fan extends JPanel
{
public Fan()
{
//this.setSize(600, 400);
Runnable spinner = new SpinFan();
Thread thread1 = new Thread(spinner);
thread1.start();
}
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawOval(200, 150, 150, 150);
g.fillArc(210, 160, 130, 130, angle1, 30);
g.fillArc(210, 160, 130, 130, angle2, 30);
g.fillArc(210, 160, 130, 130, angle3, 30);
g.fillArc(210, 160, 130, 130, angle4, 30);
}
}
class SpinFan implements Runnable
{
@Override
public void run()
{
try
{
while(true)
{
angle1 = (angle1 + 1) % 360;
angle2 = (angle2 + 1) % 360;
angle3 = (angle3 + 1) % 360;
angle4 = (angle4 + 1) % 360;
System.out.println(angle1 + " " + angle2 + " " + angle3 + " " + angle4);
// This ensures that repaint() is called on the EDT.
Runnable r = new Runnable() {
public void run() {
repaint();
}
};
SwingUtilities.invokeLater(r);
Thread.sleep(10);
}
}
catch(InterruptedException ex)
{
System.out.println("Problem while putting thread to sleep.");
}
}
}
}
关于java - 在小程序上显示旋转的风扇,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16096125/