You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Main类引用传递给JFrame类?双向方法调用问题

解决Main与MyJFrame双向方法调用的构造器错误问题

问题描述

需要实现Main类和MyJFrame类的双向方法调用:

  • 在MyJFrame类中调用Main类的addOne()方法
  • 在Main类中调用MyJFrame类的getNumber()方法

但现有代码出现两个问题:

  1. 在SwingUtilities.invokeLater的匿名Runnable内部执行this.myJFrame = new MyJFrame(this);时,报错:The constructor MyJFrame(new Runnable(){}) is undefined
  2. 直接在类成员位置执行public MyJFrame frame = new MyJFrame(this);创建实例也无法成功

错误原因

  • 匿名内部类的this指向错误:Runnable匿名内部类中的this指代的是Runnable实例,而非Main类的实例,传递给MyJFrame构造器的参数类型不匹配,导致构造器找不到。
  • 类初始化阶段的实例不完整:在类成员位置直接用this初始化MyJFrame时,Main类的实例还未完全初始化完成,此时使用this会引发异常。

修正后的代码

Main类代码

package main;

import javax.swing.SwingUtilities;

public class Main {
    
    public MyJFrame myJFrame;
    
    public static void main(String[] args) 
    {
        // 先创建完整的Main实例
        Main mainInstance = new Main();
        
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run()
            {
                // 用已创建的Main实例初始化MyJFrame,确保参数类型正确
                mainInstance.myJFrame = new MyJFrame(mainInstance);
            }
        });
        
        // 示例:调用MyJFrame的getNumber方法(等待窗口初始化完成)
        try {
            Thread.sleep(100); // 简单延迟确保Swing线程完成窗口初始化
            int number = mainInstance.myJFrame.getNumber();
            int result = mainInstance.addOne(number);
            System.out.println("调用getNumber得到:" + number + ",执行addOne后结果:" + result);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public int addOne(int amount)
    {
        return amount + 1;
    }
    
}

MyJFrame类代码

package main;

import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

import javax.swing.JFrame;

public class MyJFrame extends JFrame implements WindowListener {

    private static final long serialVersionUID = -2422522191234311369L;
    
    Main main;
    
    public MyJFrame(Main main)
    {
        super("MyJFrame");
        this.main = main;
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(400, 400);
        setVisible(true);
        setResizable(false);
        addWindowListener(this);
        
        // 示例:调用Main类的addOne方法
        int addResult = main.addOne(5);
        System.out.println("调用addOne(5)得到结果:" + addResult);
    }

    @Override
    public void windowActivated(WindowEvent e) {
        System.out.println("窗口已激活");
    }

    @Override
    public void windowClosed(WindowEvent e) {
        System.out.println("窗口已关闭");
    }

    @Override
    public void windowClosing(WindowEvent e) {
        System.out.println("即将关闭窗口");
    }

    @Override
    public void windowDeactivated(WindowEvent e) {
        System.out.println("窗口已失去焦点");
    }

    @Override
    public void windowDeiconified(WindowEvent e) {
        System.out.println("窗口已恢复"); 
    }

    @Override
    public void windowIconified(WindowEvent e) {
        System.out.println("窗口已最小化");
    }
    
    @Override
    public void windowOpened(WindowEvent e) {
        System.out.println("窗口已打开");
    }
    
    public int getNumber() 
    {
        return 10;
    }
}

关键修改说明

  1. 正确传递Main实例:在main方法中先创建完整的Main实例,再将该实例传入MyJFrame的构造器,避免了匿名内部类中this指向错误的问题。
  2. 延后窗口初始化时机:不在类成员位置直接初始化窗口,而是在Main实例创建完成后,通过Swing线程初始化MyJFrame,确保实例状态完整。
  3. 实现双向调用:在MyJFrame构造器中调用Main的addOne()方法,在Main的main方法中调用MyJFrame的getNumber()方法,完成双向方法调用的需求。

内容的提问来源于stack exchange,提问作者pumpkinpie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 14:25:24