简体   繁体   English

让两个 JFrame 相互通信

[英]Getting two JFrames to communicate with each other

I'm writing a program that measures the cps in the given amount of time.我正在编写一个程序,可以在给定的时间内测量 cps。 I want the program to be split across two windows:我希望程序被分成两个窗口:

  • one, where you can set the time and then start the other window and一个,您可以在其中设置时间,然后启动另一个窗口和
  • one, where a timer with the given amount of time runs and a button to click as often as possible.一个,其中运行具有给定时间量的计时器和尽可能多地单击的按钮。

After the timer expires, I want the result to be displayed in the first window.计时器到期后,我希望结果显示在第一个窗口中。

My problem is that I cannot figure out how to have the second window somehow tell the first window the calculated cps.我的问题是我无法弄清楚如何让第二个窗口以某种方式告诉第一个窗口计算出的 cps。 As a solution, I have thought of coroutines, but I dont know how they work in Java...作为解决方案,我想到了协程,但我不知道它们在Java中是如何工作的......

Thank you in advance for helping me!预先感谢您帮助我!

Sorry for showing you the entire code, but I thought it was necessary to provide the full details to help you help me with this problem.很抱歉向您展示了整个代码,但我认为有必要提供完整的详细信息来帮助您解决这个问题。

My Main class:我的主课:

public class Main {
    public static void main(String[] args){
        CPS test = new CPS();

    }
}

My First class: (The first Window)我的第一堂课:(第一扇窗)

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

public class CPS {
    JFrame frame;
    JSlider timeSlider;
    JLabel stateTimeSlider;
    final int timeMax = 20;
    final int timeMin = 0;
    JButton button;
    Container mainPane;
    JPanel sliderPane;
    int duration;
    MCPS measure;
    JLabel resultText;

    public CPS(){
        frame = new JFrame("CPS");
        stateTimeSlider = new JLabel("Time: 0");
        mainPane = new Container();
        sliderPane = new JPanel();
        duration = 0;
        initSlider();
        initFrame();
        initButton();
        mainPane.setLayout(new FlowLayout());
        sliderPane.setLayout(new BoxLayout(sliderPane, BoxLayout.Y_AXIS));

        init();
    }

    private void initSlider() {
        timeSlider = new JSlider(JSlider.HORIZONTAL, timeMin, timeMax, 0);
        timeSlider.setMajorTickSpacing(10);
        timeSlider.setMinorTickSpacing(5);
        timeSlider.createStandardLabels(1);
        timeSlider.setPaintTicks(true);
        timeSlider.setPaintLabels(false);

        timeSlider.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                duration = timeSlider.getValue();
                stateTimeSlider.setText("Time: " + duration);
                checkDuration(duration);
            }
        });
        sliderPane.add(timeSlider);
    }

    private void checkDuration(int duration){
        if(duration == 0){
            button.setEnabled(false);
        }
        else{
            button.setEnabled(true);
        }
    }

    private void initButton() {
        button = new JButton("Start");
        button.addMouseListener(new MouseListener() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if(duration != 0){
                    measure = new MCPS(duration);
                }

            }
            @Override
            public void mousePressed(MouseEvent e) {}
            @Override
            public void mouseReleased(MouseEvent e) {}
            @Override
            public void mouseEntered(MouseEvent e) {}
            @Override
            public void mouseExited(MouseEvent e) {}
        });
        checkDuration(duration);
    }

    private void initFrame() {
        frame.setResizable(true);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setSize(350, 150);
    }


    public void init() {
        timeSlider.setVisible(true);
        button.setVisible(true);
        stateTimeSlider.setVisible(true);

        sliderPane.add(stateTimeSlider);
        stateTimeSlider.setAlignmentX(JLabel.CENTER_ALIGNMENT);
        sliderPane.add(timeSlider);

        mainPane.add(sliderPane);
        mainPane.add(button);

        frame.add(mainPane);
        frame.setVisible(true);
    }
}

The second class (the second window):第二类(第二个窗口):

import javax.swing.*;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Timer;
import java.util.TimerTask;

public class MCPS {
    JFrame frame;
    JProgressBar timeProgress;
    int stateTimeProgress;
    JButton button;
    Container pane;
    boolean inGame;
    int amountClicked;
    boolean isMeasured;
    int duration;
    java.util.Timer timer;
    int cps;

    public MCPS(int time){
        cps = 0;
        stateTimeProgress = 0;
        duration = time;
        frame = new JFrame("CPS");
        initLogic();
        initFrame();
        initProgressBar(duration);
        initButton();
        pane = new Container();
        pane.setLayout(new FlowLayout());

        init();
    }

    private void initProgressBar(int time) {
        timeProgress = new JProgressBar(0, time);
        timeProgress.setValue(0);

    }


    private void initLogic() {
        inGame = false;
        amountClicked = 0;
        isMeasured = false;
    }

    private void startTimer(int time) {
        timer = new Timer();
        timer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                stateTimeProgress++;
                timeProgress.setValue(stateTimeProgress);
                if(stateTimeProgress == time){
                    timer.cancel();
                    stopGame();
                }
            }
        }, 0, 1000);
    }

    private void stopGame() {
        inGame = false;

        cps = amountClicked / duration;


        frame.dispose();
    }

    private boolean isInGame() {
        return inGame;
    }

    private void initButton() {
        button = new JButton("Start");
        button.addMouseListener(new MouseListener() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if(isInGame()){
                    amountClicked++;
                }
                else{
                    if(isMeasured == false) {
                        button.setText("Click me!");
                        startGame();
                    }
                }
            }
            @Override
            public void mousePressed(MouseEvent e) {}
            @Override
            public void mouseReleased(MouseEvent e) {}
            @Override
            public void mouseEntered(MouseEvent e) {}
            @Override
            public void mouseExited(MouseEvent e) {}
        });
    }

    private void startGame() {
        inGame = true;
        isMeasured = true;
        startTimer(duration);
    }

    private void initFrame() {
        frame.setResizable(true);
        frame.setSize(350, 150);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
    }

    private void init() {
        pane.add(button);
        pane.add(timeProgress);

        frame.add(pane);
        frame.setVisible(true);
    }
}

To return a value from a second frame, use a JDialog rather than a JFrame .要从第二个框架返回值,请使用JDialog而不是JFrame
Note other commented changes in the code:请注意代码中的其他注释更改:

import java.awt.Container;
import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JProgressBar;
import javax.swing.Timer;

public class MCPS {
    JDialog frame;
    JProgressBar timeProgress;
    int stateTimeProgress, amountClicked, duration;
    double cps; //use double to avoid rounding error
    JButton button;
    Container pane;
    boolean inGame, isMeasured;
    Timer timer;
    private static int CYCLE = 1000;

    public MCPS(int time){
        cps = 0;
        stateTimeProgress = 0;
        duration = time;
        frame = new JDialog();
        //make JDialog modal
        frame. setModalityType(JDialog.ModalityType.DOCUMENT_MODAL);
        initLogic();
        initFrame();
        initProgressBar(duration);
        initButton();
        pane = new Container();
        pane.setLayout(new FlowLayout());
        init();
    }

    private void initProgressBar(int time) {
        timeProgress = new JProgressBar(0, time);
        timeProgress.setValue(0);
    }

    private void initLogic() {
        inGame = false;
        amountClicked = 0;
        isMeasured = false;
    }

    private void startTimer(int time) {

        //use swing timer to interact with gui
        timer = new Timer(CYCLE, e->{
               stateTimeProgress++;
               timeProgress.setValue(stateTimeProgress);
               if(stateTimeProgress == time){
                   timer.stop();
                   stopGame();
               }
        });
        timer.setRepeats(true);
        timer.start();
    }

    private void stopGame() {
        inGame = false;
        cps = (double)amountClicked / duration;
        frame.dispose();
    }

    private boolean isInGame() {
        return inGame;
    }

    private void initButton() {
        button = new JButton("Start");
        //use action listener rather than mouse listener on buttons
        button.addActionListener(e->{
              if(isInGame()){
                  amountClicked++;
              }else if(isMeasured == false) {
                      button.setText("Click me!");
                      startGame();
              }
        });
    }

    private void startGame() {
        inGame = true;
        isMeasured = true;
        startTimer(duration);
    }

    private void initFrame() {
        frame.setResizable(true);
        frame.setSize(350, 150);
        frame.setLocationRelativeTo(null);
    }

    private void init() {
        pane.add(button);
        pane.add(timeProgress);
        frame.add(pane);
        frame.setVisible(true);
    }

    double getCps(){
        return cps;
    }
}

To get the value of cps from MCPS modify initButton() to:要从MCPS获取cps的值, initButton()修改为:

  private void initButton() {
        button = new JButton("Start");
        button.addActionListener(e->{
            if(duration != 0){
                MCPS measure = new MCPS(duration);
                System.out.println("CPS is: "+measure.getCps());
             }
        });
        checkDuration(duration);
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM