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

Java中不创建对象如何从另一个类获取变量(Risk游戏场景)

解决Java Risk游戏中玩家数量传递的问题

嘿,这个问题我之前做Java GUI项目的时候也碰到过!核心问题其实是你在NomJoueurs里新建的NombreJoueurs对象,和用户实际操作选择玩家数量的那个实例不是同一个——就像你拿了个新的空表单,当然看不到之前填的数字啦。下面给你几个靠谱的解决办法,按推荐程度排序:

1. 直接通过构造函数传递玩家数量(最推荐)

这是最简单直接的方式,当用户在NombreJoueurs里选好玩家数量后,创建NomJoueurs窗口的时候把这个值直接传进去,完全绕开对象实例依赖的问题。

首先修改NomJoueurs的构造函数,让它接收玩家数量参数:

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

public class NomJoueurs extends JFrame {
    private int nbJoueurs;

    // 构造函数接收玩家数量
    public NomJoueurs(int nbJoueurs) {
        this.nbJoueurs = nbJoueurs;
        initUI();
    }

    private void initUI() {
        setTitle("输入玩家名称");
        setLayout(new GridLayout(nbJoueurs, 2)); // 根据数量设置布局

        // 循环创建对应数量的TextField
        for (int i = 0; i < nbJoueurs; i++) {
            add(new JLabel("玩家" + (i + 1) + "名称:"));
            add(new JTextField(20));
        }

        pack();
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
    }
}

然后在NombreJoueurs的按钮点击事件里,获取到选择的数量后,直接传递给NomJoueurs:

// 假设这是NombreJoueurs里的按钮点击事件处理方法
private void onConfirmButtonClicked() {
    // 这里替换成你获取用户选择数量的逻辑,比如从下拉框或按钮组获取
    int selectedNb = 3; // 示例值
    // 创建NomJoueurs并传递数量
    new NomJoueurs(selectedNb).setVisible(true);
    // 关闭当前窗口
    this.dispose();
}

2. 使用回调接口解耦窗口(适合复杂流程)

如果你的界面跳转逻辑更复杂(比如NombreJoueurs不需要直接创建NomJoueurs,而是由Main类统一管理),可以用回调接口来传递数据,这样两个窗口类之间不会直接依赖。

首先定义一个回调接口:

public interface PlayerCountCallback {
    void onPlayerCountSelected(int count);
}

然后修改NombreJoueurs的构造函数,让它接收这个回调接口:

public class NombreJoueurs extends JFrame {
    private PlayerCountCallback callback;

    public NombreJoueurs(PlayerCountCallback callback) {
        this.callback = callback;
        initUI();
    }

    private void initUI() {
        // 初始化你的按钮、选择组件等
        JButton confirmBtn = new JButton("确认");
        confirmBtn.addActionListener(e -> {
            int selectedNb = 4; // 替换成实际获取的数量
            callback.onPlayerCountSelected(selectedNb);
            dispose();
        });
        add(confirmBtn);
        // 其他UI初始化逻辑
    }
}

最后在Main类里实现这个回调,创建NomJoueurs:

public class Main {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            // 启动选择玩家数量的窗口,并传入回调
            new NombreJoueurs(count -> {
                // 当用户选择好数量后,创建输入名称的窗口
                new NomJoueurs(count).setVisible(true);
            }).setVisible(true);
        });
    }
}

3. 单例模式(不推荐,除非必要)

如果你非要用getter方法获取值,可以把NombreJoueurs做成单例,确保你在NomJoueurs里拿到的是用户操作的同一个实例。但这种方式会增加类之间的耦合,而且如果窗口生命周期处理不好容易出问题,所以谨慎使用。

修改NombreJoueurs为单例:

public class NombreJoueurs extends JFrame {
    private static NombreJoueurs instance;
    private int nb_joueurs;

    // 私有构造函数,禁止外部新建
    private NombreJoueurs() {
        initUI();
    }

    // 获取单例实例
    public static NombreJoueurs getInstance() {
        if (instance == null) {
            instance = new NombreJoueurs();
        }
        return instance;
    }

    // getter方法
    public int getNb_joueurs() {
        return nb_joueurs;
    }

    private void initUI() {
        // 按钮点击时设置nb_joueurs
        JButton confirmBtn = new JButton("确认");
        confirmBtn.addActionListener(e -> {
            nb_joueurs = 5; // 替换成实际获取的数量
            dispose();
        });
        add(confirmBtn);
    }
}

然后在NomJoueurs里获取值:

public class NomJoueurs extends JFrame {
    public NomJoueurs() {
        // 确保用户已经选择过数量后再调用
        int nbJoueurs = NombreJoueurs.getInstance().getNb_joueurs();
        // 后续创建TextField的逻辑
    }
}

最后提醒你

一定要确保在调用getter或者创建NomJoueurs之前,用户已经完成了玩家数量的选择操作——如果NomJoueurs窗口在用户点击确认按钮之前就被创建了,那拿到的肯定是nb_joueurs的初始值(比如0)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:10:31