Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/selenium/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JLabel';s设置内部位置,以防止移动不平稳_Java_Swing_For Loop_Jlabel - Fatal编程技术网

Java JLabel';s设置内部位置,以防止移动不平稳

Java JLabel';s设置内部位置,以防止移动不平稳,java,swing,for-loop,jlabel,Java,Swing,For Loop,Jlabel,我正在使用一个小精灵的标签进行一些测试,但我想每个按键移动精灵10像素。现在,我可以做到这一点,但现在我试图让它平滑地移动10个像素,所以我尝试了下一个代码: for(int i = 0; i < 100; i++){ x++; container.setLocation(x, y); System.out.println(x); try { Thread.sleep(10); } ca

我正在使用一个小精灵的标签进行一些测试,但我想每个按键移动精灵10像素。现在,我可以做到这一点,但现在我试图让它平滑地移动10个像素,所以我尝试了下一个代码:

for(int i = 0; i < 100; i++){
        x++;
        container.setLocation(x, y);
        System.out.println(x);
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
for(int i=0;i<100;i++){
x++;
容器设置位置(x,y);
系统输出println(x);
试一试{
睡眠(10);
}捕捉(中断异常e){
e、 printStackTrace();
}
}
现在的问题是,sprite只在for循环结束时移动,但是控制台显示X值在每次迭代中的变化。有什么想法/帮助吗?
谢谢

如果不创建新线程,用户界面将与其方法在同一线程上运行

因此,您的for循环在某些操作之后被触发,线程在结束之前无法执行任何其他操作


解决方案:创建您自己的类,将JLabel或整个表单作为参数传递到构造函数中,实现线程并将其作为新线程运行。

如果您不创建新线程,则用户界面将在与其方法相同的线程上运行

因此,您的for循环在某些操作之后被触发,线程在结束之前无法执行任何其他操作


解决方案:创建您自己的类,将JLabel或整个表单作为参数传递到构造函数中,实现线程化并将其作为新线程运行。

如果您想在Swing中执行类似动画的操作,我建议您查看。它可以帮助您,具体取决于您的一般需要。

如果您想做一些类似Swing中动画的事情,我建议您看看。它可以帮助您,具体取决于您的一般需要。

如果您希望其他精灵与您的精灵同步移动,您可以创建一个
TimerTask
并使用它。然后,您的
TimerTask
将负责移动所有精灵,并重新绘制移动过程中的所有内容,如背景和精灵中的
JPanel

要使代码片段正常工作,您必须在设置位置后添加背景和精灵的重画,但我建议不要使用这种方法,因为它很容易导致代码设计不好,您创建了一个God类来完成所有工作


如果计算需要一点时间,那么
TimerTask方法也应该更精确,因为它试图在两次调用之间拥有相同的时间,如果计算提前或推迟完成,那么使用休眠线程的方法很容易导致不同的延迟。

如果您希望其他精灵与您的精灵同步移动您可以创建
TimerTask
并使用。然后,您的
TimerTask
将负责移动所有精灵,并重新绘制移动过程中的所有内容,如背景和精灵中的
JPanel

要使代码片段正常工作,您必须在设置位置后添加背景和精灵的重画,但我建议不要使用这种方法,因为它很容易导致代码设计不好,您创建了一个God类来完成所有工作


如果计算需要一点时间,则
TimerTask
方法也应该更精确,因为它试图在两次调用之间拥有相同的时间,如果计算提前或推迟完成,则使用休眠线程的方法很容易导致不同的延迟。

我建议您看看如何设置JComponent的动画使用,而不是for循环。您可以找到有关的各种教程。在这里,简单地解释一下,您正在阻塞操作Java图形端的模块。无论何时,只要您想在动画中创建一个恒定、平滑的流,请确保从不阻止EDT

编辑:以下是Swing Timer类用法的演示:

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.Timer;

public class AnimationTrial extends JFrame {

    private final int DELAY = 10;

    private Timer timer;
    private int x, y;
    private JLabel label;

    public static void main(String[] args) {
        EventQueue.invokeLater( new Runnable () {

            @Override
            public void run() {
                new AnimationTrial();
            }

        });
    }

    public AnimationTrial()
    {
        setSize(500, 500);
        x = 50;
        y = 50;

        label = new JLabel("They see me movin' they hatin'!");

        timer = new Timer( DELAY, new ActionListener()
        {

            @Override
            public void actionPerformed(ActionEvent arg0) {

                x++;
                label.setLocation(x, y);    
            }

        });
        timer.start();

        getContentPane().add(label);
        pack();
        setVisible (true);
    }

}

我建议您看看如何使用而不是for循环来设置JComponent的动画。您可以找到有关的各种教程。在这里,简单地解释一下,您正在阻塞操作Java图形端的模块。无论何时,只要您想在动画中创建一个恒定、平滑的流,请确保从不阻止EDT

编辑:以下是Swing Timer类用法的演示:

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.Timer;

public class AnimationTrial extends JFrame {

    private final int DELAY = 10;

    private Timer timer;
    private int x, y;
    private JLabel label;

    public static void main(String[] args) {
        EventQueue.invokeLater( new Runnable () {

            @Override
            public void run() {
                new AnimationTrial();
            }

        });
    }

    public AnimationTrial()
    {
        setSize(500, 500);
        x = 50;
        y = 50;

        label = new JLabel("They see me movin' they hatin'!");

        timer = new Timer( DELAY, new ActionListener()
        {

            @Override
            public void actionPerformed(ActionEvent arg0) {

                x++;
                label.setLocation(x, y);    
            }

        });
        timer.start();

        getContentPane().add(label);
        pack();
        setVisible (true);
    }

}

我在这篇文章中展示的代码,它在我自己的类中,它的名字是Sprite,里面有一个JLabel,这段代码在我创建的一个名为forTest的方法中运行,当我在窗口中按T键时,它就会运行,所以主窗口有一个keylistener,我按T键,就会发生这种情况。我的代码没有经过任何优化,但我只是在为最终实现做一些测试。有什么例子可以说明我该怎么做吗?另外,我不想让用户在for仍在运行时创建新的输入,这就是为什么我没有使用计时器,而是使用for。但显然它适得其反,哈哈。KeyListener不是在不同的线程中(自动)触发的,它只是“侦听”:。是的,你也可以使用定时器。但是,您必须手动关注用户在某些操作过程中可以做什么和不能做什么。@HectorHammett然而,当调用KeyListener时,它将处于相同的位置,负责重新绘制和处理用户输入。如果你让它进入睡眠状态,那么你就冻结了这个应用程序。我必须澄清一点,我说我的类叫sprite,因为它更容易理解,但因为我说西班牙语,它实际上不叫sprite,它叫“Monito”。我告诉你们这些,因为我的类“Monito”已经扩展到了一个名为“Sprite”的类,Monito是用户,而Sprite它将用于所有其他敌人或其他任何东西。雪碧->莫尼托。那么,再一次,你能给我举个例子吗?还是我把一切都复杂化了?哈哈,我在这篇文章中展示的代码在我自己的类中,它的名字是Sprite,里面有一个JLabel,这段代码在我创建的一个名为forTest的方法中运行,当我按T键i