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

如何在Java中启动一次程序打开两个独立运行且共享代码的Frame?

没问题,这个需求完全可以实现!核心思路是创建两个独立的JFrame实例,每个实例绑定专属的游戏逻辑(确保彼此操作互不干扰),同时用一个包装类来共享整数——因为Java基本类型是值传递,用对象包装才能让两个窗口共享同一个数值引用。下面是具体实现方案:

实现步骤与代码示例

1. 定义共享数据类

首先创建一个用来封装共享整数的类,同时加上同步方法保证多线程下的安全(毕竟两个窗口的操作可能并发执行):

class SharedData {
    private int sharedInt;

    // 初始化共享数值
    public SharedData(int initialValue) {
        this.sharedInt = initialValue;
    }

    // 获取共享数值(同步保证线程安全)
    public synchronized int getSharedInt() {
        return sharedInt;
    }

    // 设置共享数值
    public synchronized void setSharedInt(int sharedInt) {
        this.sharedInt = sharedInt;
    }

    // 示例:增加共享数值的方法
    public synchronized void increment() {
        sharedInt++;
    }
}

2. 创建独立的游戏窗口类

这个类是每个玩家的窗口模板,接收共享数据对象,每个实例拥有独立的UI和游戏逻辑:

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

class GameFrame extends JFrame {
    private final SharedData sharedData;
    private final String playerId;

    public GameFrame(SharedData sharedData, String playerId) {
        this.sharedData = sharedData;
        this.playerId = playerId;

        // 窗口基础配置
        setTitle("玩家" + playerId);
        setSize(400, 600);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new BorderLayout());

        // 显示共享数值的标签
        JLabel sharedValueLabel = new JLabel("共享数值: " + sharedData.getSharedInt());
        sharedValueLabel.setFont(new Font("Arial", Font.PLAIN, 20));
        sharedValueLabel.setHorizontalAlignment(SwingConstants.CENTER);
        add(sharedValueLabel, BorderLayout.NORTH);

        // 示例操作按钮:修改共享数值
        JButton incrementBtn = new JButton("增加共享数值");
        incrementBtn.addActionListener(e -> {
            sharedData.increment();
            // 只更新当前窗口的标签,不影响另一个窗口
            sharedValueLabel.setText("共享数值: " + sharedData.getSharedInt());
        });
        add(incrementBtn, BorderLayout.SOUTH);

        // 游戏主面板(每个窗口独立)
        JPanel gamePanel = new JPanel();
        // 用不同背景色区分两个窗口,直观体现独立性
        gamePanel.setBackground(playerId.equals("1") ? Color.LIGHT_GRAY : Color.WHITE);
        add(gamePanel, BorderLayout.CENTER);

        // 这里可以添加你的游戏核心组件,比如画布、角色控件等
        // 所有组件都是当前窗口独有的,操作一个不会影响另一个
    }
}

3. 主程序启动两个窗口

在主类中初始化共享数据,创建两个窗口实例,并设置它们的位置实现并排显示:

public class TwoPlayerGame {
    public static void main(String[] args) {
        // 初始化共享数值,这里设为0
        SharedData sharedData = new SharedData(0);

        // 创建两个玩家窗口,传入同一个共享数据对象
        GameFrame player1Frame = new GameFrame(sharedData, "1");
        GameFrame player2Frame = new GameFrame(sharedData, "2");

        // 计算窗口位置,让它们在屏幕中间并排
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        int frameWidth = player1Frame.getWidth();
        int startX = (screenSize.width - 2 * frameWidth) / 2;
        player1Frame.setLocation(startX, 100);
        player2Frame.setLocation(startX + frameWidth, 100);

        // 显示两个窗口
        player1Frame.setVisible(true);
        player2Frame.setVisible(true);
    }
}
关键要点说明
  • 独立运行:每个GameFrame都是独立的实例,它们的UI组件、事件监听逻辑完全分离。比如玩家1点击按钮,只会更新自己窗口的标签,不会干扰玩家2的窗口状态。
  • 共享整数:通过SharedData类包装整数,两个窗口持有同一个对象的引用,因此修改共享数值时会实时同步。同步方法避免了多线程并发修改可能导致的数值错误。
  • 并排显示:通过setLocation计算窗口的起始坐标,让两个窗口在屏幕中间横向排列,你可以根据需求调整坐标或窗口大小。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:29:18