绘制时,对象不会出现在java小程序中。我应该如何正确使用AWT中的绘画/重绘方法?
我有一个小程序界面,可以在屏幕上画一个球,当按下run按钮时,它会从边缘反弹。还有其他功能,但它们需要第一个功能才能工作。当前按run时,不会发生任何事情。我认为我画的对象不对。我已经输入了绘制时,对象不会出现在java小程序中。我应该如何正确使用AWT中的绘画/重绘方法?,java,applet,awt,paint,Java,Applet,Awt,Paint,我有一个小程序界面,可以在屏幕上画一个球,当按下run按钮时,它会从边缘反弹。还有其他功能,但它们需要第一个功能才能工作。当前按run时,不会发生任何事情。我认为我画的对象不对。我已经输入了System.err.println()语句,并检查了控制台,当单击按钮时,程序会转到正确的方法。我只是不知道应该绘制对象的方法有什么问题 代码将近500行,但如果需要的话,我会把它粘贴到这个主体中。这里是:首先,您必须覆盖绘图面板的绘制:这是您绘制圆的地方。当前,该圆圈仅在按下运行按钮时出现,因为它被绘制在
System.err.println()
语句,并检查了控制台,当单击按钮时,程序会转到正确的方法。我只是不知道应该绘制对象的方法有什么问题
代码将近500行,但如果需要的话,我会把它粘贴到这个主体中。这里是:首先,您必须覆盖绘图面板的绘制:这是您绘制圆的地方。当前,该圆圈仅在按下运行按钮时出现,因为它被绘制在组件上。
在正常绘制过程中,小程序区域被绘制(这是您当前的
绘制
工作的地方),并且您添加的所有组件都被绘制在已经绘制的点上
在程序的开始处,点是null,因此paint无法正确绘制它-它会引发NullPointerException
您不必“缓存”图形实例:始终使用paint中提供给您的图形
如果希望圆移动,则必须创建另一个线程,使其更新值,然后计划重新绘制绘图面板
您不必重新绘制整个小程序,只需重新绘制绘图面板
如果你仍然需要帮助,请在评论中询问他们
编辑:
这是您的绘图面板
,其中绘制了圆点:
Panel drawingpanel = new Panel() {
public void paint(Graphics g) {
if (dot == null) {
return;
}
g.drawOval(dot.leftOf(), dot.topOf(), dot.widthOf(), dot.heightOf());
g.fillOval(dot.leftOf(), dot.topOf(), dot.widthOf(), dot.heightOf());
};
};
并且您的Bounce
applet不会覆盖paint()
方法
要实现动画,请将界面添加到implements
部分。
添加另一个字段:
volatile boolean running = false;
private Thread animationThread;
现在让我们实现简单的动画:
public void run() {
while (running) {
if (!showtails) {
dot.setColor(drawingpanel.getBackground());
}
update();// check if speed, size, or shape changed
draw();// draw next dot based on move(), or initial condition
pause();
move();// calculate and prepare the coordinates for the next
// iteration to be drawn
}
}
public void draw() {
drawingpanel.repaint();
}
public void pause() {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void move() {
dot.left--;
dot.top--;
}
最后一个细节是动作处理程序:
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if (source == this.runbutton) {
running = !running;
if (animationThread == null) {
animationThread = new Thread(this);
}
if (running) {
dot = new CircDot(100, 100, sizebar.getValue(), Color.RED);
animationThread.start();
}
} else
...
}
下面是它的工作原理。您的实现在操作处理程序中启动了run()
,并且没有将控件返回给EDT,因此您的应用程序出现挂起:它停止处理消息
现在,当单击Run按钮时,状态字段running
被反转,然后创建一个新线程(如果它尚未启动)。线程执行run()
方法。因此,执行while
正文中的操作,直到running
变为false
- 在调度绘制操作的
drawingpanel
上调用draw方法repaint()
。当消息队列为空时,系统将调用其paint
方法重新绘制面板
- pause方法调用Thread.sleep(500)
停止执行500毫秒。数字越小,圆点移动越快。这里的值在某种程度上取决于速度。永远不要实现带循环的暂停:您只是在浪费处理器时间而没有任何收益,并且无法预测需要多长时间
移动只会减少点的top
和left
坐标,使其移动到窗口的左上角
值得注意的是,running
被声明为volatile
,因为该字段是从多个线程访问的,没有其他同步手段。如果它不在那里,运行的动画可能看不到动作处理程序中EDT对它的修改。每次绘制对象时,必须将控制权返回到事件调度线程(EDT),程序才能在屏幕上实际绘制它并处理其他事件。@PaulTomblin Ok。我没有写任何东西在线程中运行。EDT是由AWT自动创建/处理的,还是我必须在某个地方手动实例化它,或者我可以使用一条语句将控制权交还给它?“我应该如何正确使用AWT中的绘制/重新绘制方法?”1)跳进时间机器,回到人们能够记住它的上一个千年当我在这里的时候。为了更快地获得更好的帮助,请发布一篇文章。您是如何编译您的类的?您使用的是Eclipse还是命令行?@ilango在Jcreator中编译,并在一个简单的网页中运行OK,因此如果我去看看我是否正确理解了这一点:没有显示任何内容,因为圆圈是绘制的,然后所有内容都放在它上面。我应该直接在绘图面板上绘图,是吗?null的初始条件不是无关紧要的吗,因为参数是在按下runbutton
时指定的?还是从一开始就画第一个点更好?关于你最后提出的3点,我只是不知道如何实现它们,但我确实理解你所说的。是的,圆圈是在小程序窗口上画的。然后,小程序包含绘制在其上方的子窗口。/*如果它是Swing组件和JApplet,那么在applet窗口中除了点(当它不为null时)之外,您不会看到任何东西*/不,即使未单击“运行”,也会完成绘制。因此,绘制方法不应抛出NullPointerException,请参阅添加的null检查。您的clear方法可以通过将dot字段置零并调用repaint:nothingspaint来实现。这取决于您是否立即绘制点或隐藏点,直到单击Run,您的程序在正确运行时不应引发异常。我已使用Thread使用简单动画更新了我的答案。另一种方法是使用定时器。