[英]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:
我希望程序被分成两个窗口:
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.