Получение двух JFrames для общения друг с другом - PullRequest
0 голосов
/ 12 февраля 2020

Я пишу программу, которая измеряет cps за заданный промежуток времени. Я хочу, чтобы программа была разделена на две windows:

  • одна, где вы можете установить время, а затем запустить другое окно и
  • одна, где таймер с заданный промежуток времени и кнопка, которую нужно нажимать как можно чаще.

После истечения таймера я хочу, чтобы результат отображался в первом окне.

Моя проблема что я не могу понять, как заставить второе окно каким-то образом сообщать первому окну рассчитанный cps. В качестве решения я подумал о сопрограммах, но я не знаю, как они работают в Java ...

Заранее спасибо за помощь!

Извините, что показал вам всю код, но я подумал, что необходимо предоставить полную информацию, чтобы помочь вам решить эту проблему.

Мой основной класс:

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

    }
}

Мой первый класс: (Первое окно)

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);
    }
}

Второй класс (второе окно):

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);
    }
}

1 Ответ

0 голосов
/ 13 февраля 2020

Чтобы вернуть значение из второго кадра, используйте JDialog вместо JFrame. Обратите внимание на другие прокомментированные изменения в коде:

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;
    }
}

Чтобы получить значение cps из MCPS, измените 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);
    }
...