Java JApplet repaint()不';行不通

Java JApplet repaint()不';行不通,java,repaint,japplet,Java,Repaint,Japplet,问题: Main.repaint()对我不起作用。repaint()不调用Main中的my paint方法。我尝试在重新绘制之前调用validate,但没有成功。Main在最初或调整大小时绘制得非常完美,但在代码中调用repaint()时,什么都没有发生 以下是到目前为止该程序的外观 因此,我试图用java为游戏创建一个关卡选择屏幕。我的游戏是日本式的。我的结构如下: public Main getInstance() { return instance; } 我的主要类,它扩展了JA

问题: Main.repaint()对我不起作用。repaint()不调用Main中的my paint方法。我尝试在重新绘制之前调用validate,但没有成功。Main在最初或调整大小时绘制得非常完美,但在代码中调用repaint()时,什么都没有发生

以下是到目前为止该程序的外观

因此,我试图用java为游戏创建一个关卡选择屏幕。我的游戏是日本式的。我的结构如下:

public Main getInstance() {
    return instance;
}
  • 我的主要类,它扩展了JApplet并包含 水平筛类

    LevelScreen有一个由Main调用的绘制方法

  • 我尽量避免使用Swing,因为布局经理在设计上给了我麻烦。所以我试着做一个更简单更适合我需要的结构

    Main.java中的paint()

    public class Main extends JApplet {
    
        public static final int WIDTH = 700, HEIGHT = 500;
        private static Main instance;
    
        private LevelScreen levelScreen = new LevelScreen();
        private View view = View.LEVELSCREEN;
    
        public static Main getInstance() {
            if (instance == null)
                instance = new Main();
            return instance;
        }
    
        @Override
        public void init() {
            setSize(WIDTH, HEIGHT);
            addMouseMotionListener(new MouseAdapter() {
                @Override
                public void mouseMoved(MouseEvent e) {
                    Point p = e.getPoint();
                    if (view == View.LEVELSCREEN) {
                        levelScreen.mouseMoved(p);
                    }
                }
            });
        }
    
        @Override
        public void paint(Graphics g) {
            Graphics2D g2 = (Graphics2D) g;
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);
    
            if (view == View.LEVELSCREEN) 
                levelScreen.paint(g2);
        }
    
        public enum View {
            GAME, LEVELSCREEN;
        }
    }
    
    在我的按钮代码中,我尝试重新绘制Main,因为我想在鼠标离开按钮时制作淡出动画。我的问题是我不能用repaint()调用main中的绘画(图形g)

    这里我调用repaint():


    这是实现单例设计模式的方式的问题。您这样做的方式不适用于小程序,小程序的实例是由小程序容器为您创建的。您可以通过如下更改
    getInstance
    来修复它:

    public Main getInstance() {
        return instance;
    }
    
    并将此行添加到
    init
    方法:

    instance = this;
    

    顺便说一句,您不应该覆盖Swing组件中的
    paint
    ,而JApplet就是这样的组件。您应该替代
    paintComponent
    ,并调用
    super.paintComponent(g)
    作为第一行。这应该可以解决问题

    Main.getInstance().repaint();  //this doesnt work!!
    
    我并不惊讶。创建
    JApplet
    实例的不是您,而是浏览器

    当你叫这个

    public static Main getInstance() {
        if (instance == null)
            instance = new Main();
        return instance;
    }
    
    实际上,您正在创建小程序的第二个实例,而不是屏幕上的实例,因此,当您调用
    repaint
    时,Swing会说,“没有意义,您甚至无法显示”,并且什么也不做

    如果没有更多的代码上下文,您甚至可能不需要
    getInstance
    ,而是使用
    Main引用当前实例

    <>你也应该考虑看一下。

    JAppelt
    这样的顶级容器不是双缓冲的,这需要更多的工作来直接绘制。相反,将应用程序移动到类似于
    JPanel
    的基础上,并替代它的
    paintComponent
    方法


    绘画也是一个复杂的、多层次的方案。您必须调用
    super.paintXxx
    ,以保留绘制链并防止任何可能的问题。

    我之所以使用JApplet而不是JFrame,是因为我希望我的游戏在某个时候在浏览器中运行。编译器说Main.this在作用域中不可访问。我发现了一个临时的肮脏解决方案,它只是让主重绘()在特定的时间间隔完美地工作!我误解了JApplet是如何由浏览器而不是程序创建的。