【问题标题】:JLabel run function form runnable interface is not being called未调用 JLabel 运行函数表单可运行接口
【发布时间】:2022-01-16 11:12:07
【问题描述】:

所以我读到 Runnable 接口中的 run 函数会自动调用,但它对我不起作用(未调用 run)。这是我第一次在 java 中做任何事情,所以我可能做了一些愚蠢的事情。下面的代码应该在屏幕上移动一个矩形。矩形已绘制,但没有移动。

主要:

    public class Label extends JLabel{

    Game game;

    public Label(Game game){
       this.game = game;
    }

    public void paint(Graphics gfx){
        game.render(gfx);
    }
}

框架:

import javax.swing.*;
import java.awt.*;

public class Frame extends JFrame implements Runnable{

    Game game;

    public Frame(Label label, Game game) {
        this.setSize(600, 600);
        this.setTitle("idk");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);
        this.setEnabled(true);
        this.game = game;
        this.setContentPane(label);
    }

    public void run(){
        game.update();
        try {
            Thread.sleep(20);
        }
        catch(InterruptedException ex){}
    }
}

标签:

import javax.swing.*;
import java.awt.*;

public class Label extends JLabel{

    Game game;

    public Label(Game game){
       this.game = game;
    }

    public void paint(Graphics gfx){
        game.render(gfx);
    }
}

游戏:

import java.awt.*;

public class Game {

    float x = 0;
    float y = 0;
    float w = 20;
    float h = 20;

    void render(Graphics gfx){
        gfx.fillRect((int)x, (int)y, (int)w, (int)h);
    }

    void update(){
        x += 0.1f;
        System.out.println(x);
    }
}

【问题讨论】:

  • 可运行的 JLabel 没有任何意义。
  • @Olivier 我更改了代码以使 JFrame 可运行,但结果仍然相同。矩形被绘制但不移动。我更新了问题中的代码
  • "Runnable接口的run函数被自动调用"错了。
  • 请发布minimal reproducible example,包括main 方法。对于 Swing 动画,使用摇摆 Timer
  • 通常,在 Swing 中,当您想要自己进行绘画时,您会编写一个扩展 javax.swing.JPanel 的类并覆盖其 paintComponent 方法。请参阅Performing Custom Painting。如果要添加动画,通常使用 [Swing] 计时器。参考How to Use Swing Timers

标签: java swing jlabel


【解决方案1】:

您需要创建一个 main 方法,在该方法中创建一个新的 Thread 对象,在该 Thread 实例中传递 Runnable 类(即在您的情况下为 Frame),然后是 start @ 987654327@。见下文:

public class Main
{     
    public static void main(String args[])  
    {    
        Game g = new Game();
        Label l = new Label(g);
        Frame f = new Frame(l, g);    
        Thread t1 =new Thread(f);   
        // this will call run() method in Frame class 
        t1.start();    
    }    
} 

编辑:另外,您的 Frame 类应该如下所示。一个线程执行一次它的run方法,然后它被认为是完成的。如果你想循环,你必须自己做(下面使用了while(true),可以更改为一些变量,当你希望程序退出时可以转到false)。最后,一定要在game.update()之后调用repaint()才能使绘制生效。

import javax.swing.*;
import java.awt.*;

public class Frame extends JFrame implements Runnable{

    Game game;
    Label label;
    public Frame(Label label, Game game) {
        this.label = label;
        this.setSize(600, 600);
        this.setTitle("idk");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);
        this.setEnabled(true);
        this.game = game;
        this.setContentPane(label);
    }

    @Override
    public void run(){
        while(true) {
            game.update();
            label.repaint();
            try {
                Thread.sleep(5);
            }
            catch(InterruptedException ex){}
        }
    }
} 

【讨论】:

  • 我认为你不应该在 EDT 上sleeping。您也不应该在不是 EDT 的线程上更新 GUI。参考Concurrency in Swing
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-15
  • 2021-01-21
  • 1970-01-01
  • 2014-07-23
相关资源
最近更新 更多