Java 如何使框架在窗户关闭前一直重新喷漆?

Java 如何使框架在窗户关闭前一直重新喷漆?,java,swing,Java,Swing,我目前正在制作一个立方体(使用point2d和line2d绘制形状)在一个框架周围移动,类似于pong或窗口屏幕保护程序气泡。我可以将立方体打印到框架上,但我不知道如何在第一次打印后使其移动。我想用一个计时器动作监听器使球四处移动 观众 import javax.swing.JFrame; public class CubeBounceViewer { public static void main(String[] agrs) { JFrame frame = new

我目前正在制作一个立方体(使用point2d和line2d绘制形状)在一个框架周围移动,类似于pong或窗口屏幕保护程序气泡。我可以将立方体打印到框架上,但我不知道如何在第一次打印后使其移动。我想用一个计时器动作监听器使球四处移动

观众

import javax.swing.JFrame;
public class CubeBounceViewer {

    public static void main(String[] agrs) {
        JFrame frame = new JFrame();

        frame.setTitle("Cube Bounce");
        frame.setSize(1280,720);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);

        CubeBounceComponent component = new CubeBounceComponent();
        frame.add(component);
    }
}
组成部分

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JComponent;
import javax.swing.Timer;

public class CubeBounceComponent extends JComponent{

    public void paintComponent(Graphics g) {

        Graphics2D g2 = (Graphics2D) g;

        //Creates a object list with size equal to value of instance
        Cube cube = new Cube();

        class TimerListener implements ActionListener {
            public void actionPerformed(ActionEvent event) {
                cube.move();
            }
        }

        ActionListener listener = new TimerListener();

        final int DELAY = 100;
        Timer t = new Timer(DELAY, listener);
        t.start();

        cube.draw(g2);
        cube.move();
        if (cube.getX()>=1265 || cube.getX()<=15 && cube.getY()<=15 || cube.getY()>=705) {
            cube.changeDirection(-1, -1);
        } else if(cube.getX()>=1265 || cube.getX()<=15) {
            cube.changeDirection(-1, 1);
        } if (cube.getY()<=15 || cube.getY()>=705) {
            cube.changeDirection(1,-1);
        }

    }
}

非常感谢您的帮助!谢谢。

这是一次冒险,但您是否尝试过将代码放入:

While (true) {}

这是一个黑暗中的镜头,但您是否尝试将代码放入:

While (true) {}

首先使多维数据集成为类的成员,而不是局部变量。其次,从绘制组件中删除所有移动逻辑。第三,在更新立方体位置后请求重新绘制

Cube cube = new Cube();

public void updatePosition(){


    cube.move();
    if (cube.getX()>=1265 || cube.getX()<=15 && cube.getY()<=15 || cube.getY()>=705) {
        cube.changeDirection(-1, -1);
    } else if(cube.getX()>=1265 || cube.getX()<=15) {
        cube.changeDirection(-1, 1);
    } if (cube.getY()<=15 || cube.getY()>=705) {
        cube.changeDirection(1,-1);
    }
    repaint();
}

public void paintComponent(Graphics g) {
    Graphics2D g2 = (Graphics2D) g;
    cube.draw(g2);
}
注意,您可以使用lambdas使其更加简洁,而不需要命名类
TimerListener

Timer t = new Timer(DELAY, evt->component.updatePosition() )

首先使多维数据集成为类的成员,而不是局部变量。其次,从绘制组件中删除所有移动逻辑。第三,在更新立方体位置后请求重新绘制

Cube cube = new Cube();

public void updatePosition(){


    cube.move();
    if (cube.getX()>=1265 || cube.getX()<=15 && cube.getY()<=15 || cube.getY()>=705) {
        cube.changeDirection(-1, -1);
    } else if(cube.getX()>=1265 || cube.getX()<=15) {
        cube.changeDirection(-1, 1);
    } if (cube.getY()<=15 || cube.getY()>=705) {
        cube.changeDirection(1,-1);
    }
    repaint();
}

public void paintComponent(Graphics g) {
    Graphics2D g2 = (Graphics2D) g;
    cube.draw(g2);
}
注意,您可以使用lambdas使其更加简洁,而不需要命名类
TimerListener

Timer t = new Timer(DELAY, evt->component.updatePosition() )

当我在cube.draw(g2)之前实现它并编译它时,多维数据集不会显示,除非我停止控制台或其他操作,否则我将无法关闭窗口。我正在使用EclipseIDE编程。当我在cube.draw(g2)之前实现它并编译它时,多维数据集不会显示,除非我停止控制台或其他操作,否则我将无法关闭窗口。我正在使用EclipseIDE来编程,你在画图组件中做了很多你不应该做的事情。这只会重新绘制组件。整个cube.move和边界检查应该用一种完全不同的方法来完成。我对如何使边界检查成为一种不同的方法有了一些想法。我不明白如何使整个立方体分开移动。计算机将如何自动重新绘制自身?重新绘制经常发生,您可以请求重新绘制,或者如果场景中发生变化,可以调用paintComponent。现在,您总是在绘制组件中创建新的立方体。你从不绘制更新后的立方体。你在绘制组件中做了很多你不应该做的事情。这只会重新绘制组件。整个cube.move和边界检查应该用一种完全不同的方法来完成。我对如何使边界检查成为一种不同的方法有了一些想法。我不明白如何使整个立方体分开移动。计算机将如何自动重新绘制自身?重新绘制经常发生,您可以请求重新绘制,或者如果场景中发生变化,可以调用paintComponent。现在,您总是在绘制组件中创建新的立方体。你从来没有画过更新过的立方体。谢谢你的帮助。我让它工作了。现在我唯一的问题是,随着时间的推移,调用cube.move()的次数似乎越来越快。你知道是什么原因吗?@NonSopbrain可能是因为你创造了越来越多的计时器。只需启动一个调用更新位置的计时器。我将更新答案以反映这一点。非常感谢您的帮助。看到你如何解释我的问题,看到这些步骤,让我更容易理解为什么事情会这样发展。再次感谢你的帮助。谢谢你的帮助。我让它工作了。现在我唯一的问题是,随着时间的推移,调用cube.move()的次数似乎越来越快。你知道是什么原因吗?@NonSopbrain可能是因为你创造了越来越多的计时器。只需启动一个调用更新位置的计时器。我将更新答案以反映这一点。非常感谢您的帮助。看到你如何解释我的问题,看到这些步骤,让我更容易理解为什么事情会这样发展。再次感谢你的帮助。