开始计时器(javax.swing)在按钮点击时而不是自行启动

huangapple go评论99阅读模式
英文:

Start timer (javax.swing) on button-click rather than on its own

问题

  1. import javax.swing.JFrame;
  2. import javax.swing.JLabel;
  3. import javax.swing.JButton;
  4. import java.awt.FlowLayout;
  5. import java.awt.GridBagLayout;
  6. import java.awt.Dimension;
  7. import java.awt.event.ActionListener;
  8. import java.awt.event.ActionEvent;
  9. import javax.swing.Timer;
  10. public class Main extends JFrame implements ActionListener
  11. {
  12. private static final long serialVersionUID = 1L;
  13. public static final int WIDTH = 550;
  14. public static final int HEIGHT = 550;
  15. public static final int WIDTH1 = 450;
  16. public static final int HEIGHT1 = 450;
  17. public static final int WIDTH2 = 125;
  18. public static final int HEIGHT2 = 25;
  19. private JLabel lblValue;
  20. private int clicks = 0;
  21. private int count = 6;
  22. public static void main(String[] args)
  23. {
  24. Main counter1 = new Main( );
  25. counter1.setVisible(true);
  26. Main counter2 = new Main( );
  27. counter2.setVisible(true);
  28. }
  29. public Main( )
  30. {
  31. setTitle("CPS Test");
  32. setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  33. setSize(WIDTH, HEIGHT);
  34. setMaximumSize(new Dimension(WIDTH, HEIGHT));
  35. setMinimumSize(new Dimension(WIDTH, HEIGHT));
  36. setLayout(new FlowLayout( ));
  37. lblValue = new JLabel("0");
  38. add(lblValue);
  39. JButton addButton = new JButton("Please Wait");
  40. addButton.addActionListener(this);
  41. addButton.setSize(new Dimension(WIDTH1, HEIGHT1));
  42. addButton.setPreferredSize(new Dimension(WIDTH1, HEIGHT1));
  43. addButton.setMinimumSize(new Dimension(WIDTH1, HEIGHT1));
  44. addButton.setMaximumSize(new Dimension(WIDTH1, HEIGHT1));
  45. add(addButton);
  46. JButton resetButton = new JButton("Restart");
  47. resetButton.setSize(new Dimension(WIDTH2, HEIGHT2));
  48. resetButton.setPreferredSize(new Dimension(WIDTH2, HEIGHT2));
  49. resetButton.setMinimumSize(new Dimension(WIDTH2, HEIGHT2));
  50. resetButton.setMaximumSize(new Dimension(WIDTH2, HEIGHT2));
  51. JLabel label = new JLabel("Starting Soon");
  52. setLayout(new GridBagLayout());
  53. add(label);
  54. Timer timer = new Timer(1000, new ActionListener() {
  55. public void actionPerformed(ActionEvent e) {
  56. count--;
  57. if (count >= 0) {
  58. label.setText(Integer.toString(count));
  59. }
  60. else {
  61. ((Timer) (e.getSource())).stop();
  62. remove(addButton);
  63. label.setText("");
  64. lblValue.setText("You clicked " + clicks / 5d + " clicks per second.");
  65. add(resetButton);
  66. }
  67. if (count == 5) {
  68. addButton.setText("Click Here");
  69. }
  70. }
  71. });
  72. timer.setInitialDelay(3000);
  73. timer.start();
  74. }
  75. public void actionPerformed(ActionEvent e)
  76. {
  77. String actionCommand = e.getActionCommand( );
  78. if (actionCommand.equals("Click Here"))
  79. {
  80. lblValue.setText(Integer.toString(clicks += 1));
  81. }
  82. }
  83. }
英文:

I have added a button, that is initially "Please Wait" and changes to "Click Here" as the timer starts. I need to make it so that if the button is clicked, whilst the text is "Please Wait", it starts the timer, rather than having the timer start itself after the 3000ms.

I also am wondering how I could make the restart button, actually restart the test.

  1. import javax.swing.JFrame;
  2. import javax.swing.JLabel;
  3. import javax.swing.JButton;
  4. import java.awt.FlowLayout;
  5. import java.awt.GridBagLayout;
  6. import java.awt.Dimension;
  7. import java.awt.event.ActionListener;
  8. import java.awt.event.ActionEvent;
  9. import javax.swing.Timer;
  10. public class Main extends JFrame implements ActionListener
  11. {
  12. private static final long serialVersionUID = 1L;
  13. //Width and Height of the JFrame
  14. public static final int WIDTH = 550;
  15. public static final int HEIGHT = 550;
  16. //Width and Height of the Add Button
  17. public static final int WIDTH1 = 450;
  18. public static final int HEIGHT1 = 450;
  19. //Width and Height of Restart Button
  20. public static final int WIDTH2 = 125;
  21. public static final int HEIGHT2 = 25;
  22. //Adding the 3 main components
  23. //This is the label that counts the clicks
  24. private JLabel lblValue;
  25. //This is the integer that counts the clicks
  26. private int clicks = 0;
  27. //This is the timer
  28. private int count = 6;
  29. public static void main(String[] args)
  30. {
  31. // This creates two instances of Main,
  32. // which creates two different windows.
  33. Main counter1 = new Main( );
  34. counter1.setVisible(true);
  35. Main counter2 = new Main( );
  36. counter2.setVisible(true);
  37. }
  38. public Main( )
  39. {
  40. //Title that appears at the top of the page
  41. setTitle("CPS Test");
  42. //Close when the close button is pressed
  43. setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  44. //Setting size of the frame
  45. setSize(WIDTH, HEIGHT);
  46. setMaximumSize(new Dimension(WIDTH, HEIGHT));
  47. setMinimumSize(new Dimension(WIDTH, HEIGHT));
  48. setLayout(new FlowLayout( ));
  49. // This is the label for the amount of clicks
  50. lblValue = new JLabel("0");
  51. //Adding the counter onto the screen
  52. add(lblValue);
  53. //This is the button that adds 1 every time clicked
  54. JButton addButton = new JButton("Please Wait");
  55. addButton.addActionListener(this);
  56. //Setting size for button
  57. addButton.setSize(new Dimension(WIDTH1, HEIGHT1));
  58. addButton.setPreferredSize(new Dimension(WIDTH1, HEIGHT1));
  59. addButton.setMinimumSize(new Dimension(WIDTH1, HEIGHT1));
  60. addButton.setMaximumSize(new Dimension(WIDTH1, HEIGHT1));
  61. //Adding button onto screen
  62. add(addButton);
  63. JButton resetButton = new JButton("Restart");
  64. //Setting size for button
  65. resetButton.setSize(new Dimension(WIDTH2, HEIGHT2));
  66. resetButton.setPreferredSize(new Dimension(WIDTH2, HEIGHT2));
  67. resetButton.setMinimumSize(new Dimension(WIDTH2, HEIGHT2));
  68. resetButton.setMaximumSize(new Dimension(WIDTH2, HEIGHT2));
  69. //Adds the label for the timer. This changes after 1000 milliseconds to 1, and then counts every second
  70. JLabel label = new JLabel("Starting Soon");
  71. setLayout(new GridBagLayout());
  72. //Adding timer onto the screen
  73. add(label);
  74. //Delay in milliseconds between number adding
  75. Timer timer = new Timer(1000, new ActionListener() {
  76. public void actionPerformed(ActionEvent e) {
  77. //Add 1 to count every interval of 1000 milliseconds
  78. count--;
  79. //Timer keeps ticking till this number is achieved
  80. if (count >= 0) {
  81. label.setText(Integer.toString(count));
  82. }
  83. //Will stop timer, remove the click button and will calculate how many clicks you got per second
  84. else {
  85. ((Timer) (e.getSource())).stop();
  86. remove(addButton);
  87. label.setText("");
  88. lblValue.setText("You clicked " + clicks / 5d + " clicks per second.");
  89. add(resetButton);
  90. }
  91. //Will change text from "Please Wait" to "Click Here" after timer delay has finished
  92. if (count == 5) {
  93. addButton.setText("Click Here");
  94. }
  95. }
  96. });
  97. //Timer wont start for 3000 milliseconds
  98. timer.setInitialDelay(3000);
  99. //Start Timer
  100. timer.start();
  101. }
  102. public void actionPerformed(ActionEvent e)
  103. {
  104. String actionCommand = e.getActionCommand( );
  105. //This will only work whilst the text is "Click Here". Wont work for 1000 milliseconds as the text is "Please Wait"
  106. if (actionCommand.equals("Click Here"))
  107. {
  108. //Adds 1 to the click counter ever time it is clicked
  109. lblValue.setText(Integer.toString(clicks += 1));
  110. }
  111. }
  112. }```
  113. </details>
  114. # 答案1
  115. **得分**: 4
  116. 根据[Andrew Thompson][1]的指示,你需要完成四个步骤来解决这个问题。
  117. **1.) 计时器应该是类的全局变量**
  118. 这一步很重要,否则对象无法从我们即将创建的ActionListeners内部访问。
  119. ```java
  120. import javax.swing.Timer;
  121. public class Test {
  122. private Timer timer;
  123. public Test() {
  124. }
  125. }

2.) 在构造函数中创建计时器元素

在构造函数中,我们将初始化计时器,但是重要的是 - 我们暂时不会启动它。

  1. import java.awt.event.ActionEvent;
  2. import java.awt.event.ActionListener;
  3. import javax.swing.Timer;
  4. public class Test {
  5. private Timer timer;
  6. private int count = 0;
  7. public Test() {
  8. ActionListener taskPerformer = new ActionListener() {
  9. public void actionPerformed(ActionEvent evt) {
  10. //计时器应该做什么?
  11. count++;
  12. System.out.println(count);
  13. }
  14. };
  15. timer = new Timer(1000, taskPerformer);
  16. }
  17. }

3.) 在开始按钮的ActionListener中启动计时器

在这一步中,我们通过按下按钮来启动计时器的功能。为此,我们使用了一个ActionListener和计时器的start()方法。

  1. import java.awt.event.ActionEvent;
  2. import java.awt.event.ActionListener;
  3. import javax.swing.JButton;
  4. import javax.swing.Timer;
  5. public class Test {
  6. private Timer timer;
  7. private int count = 0;
  8. public Test() {
  9. ActionListener taskPerformer = new ActionListener() {
  10. public void actionPerformed(ActionEvent evt) {
  11. //计时器应该做什么?
  12. count++;
  13. System.out.println(count);
  14. }
  15. };
  16. timer = new Timer(1000, taskPerformer);
  17. JButton start = new JButton("开始");
  18. //在这里添加功能
  19. start.addActionListener(new ActionListener() {
  20. @Override
  21. public void actionPerformed(ActionEvent arg0) {
  22. if(!timer.isRunning()) {
  23. System.out.println("计时器已启动!");
  24. timer.start();
  25. }
  26. }
  27. });
  28. }
  29. }

4.) 在停止按钮的ActionListener中停止计时器

这基本上是相反的过程。我们将创建另一个按钮,以添加停止计时器功能。为此,我们再次使用ActionListener和计时器的stop()方法。

  1. import java.awt.event.ActionEvent;
  2. import java.awt.event.ActionListener;
  3. import javax.swing.JButton;
  4. import javax.swing.Timer;
  5. public class Test {
  6. private Timer timer;
  7. private int count = 0;
  8. public Test() {
  9. ActionListener taskPerformer = new ActionListener() {
  10. public void actionPerformed(ActionEvent evt) {
  11. //计时器应该做什么?
  12. count++;
  13. System.out.println(count);
  14. }
  15. };
  16. timer = new Timer(1000, taskPerformer);
  17. JButton start = new JButton("开始");
  18. start.addActionListener(new ActionListener() {
  19. @Override
  20. public void actionPerformed(ActionEvent arg0) {
  21. if(!timer.isRunning()) {
  22. System.out.println("计时器已启动!");
  23. timer.start();
  24. }
  25. }
  26. });
  27. //在这里添加功能
  28. JButton stop = new JButton("停止");
  29. stop.addActionListener(new ActionListener() {
  30. @Override
  31. public void actionPerformed(ActionEvent arg0) {
  32. if(timer.isRunning()) {
  33. count = 0;
  34. System.out.println("计时器已停止!");
  35. timer.stop();
  36. }
  37. }
  38. });
  39. }
  40. }

最后一步:创建其余的GUI

这对于回答你的问题不再必要,但我想提供一个最小的工作示例。为此,我使用了SwingUtilities.invokeLater()。关于这是在做什么以及为什么应该使用它的更多信息,请参阅这个问题

  1. import java.awt.FlowLayout;
  2. import java.awt.event.ActionEvent;
  3. import java.awt.event.ActionListener;
  4. import javax.swing.JButton;
  5. import javax.swing.JFrame;
  6. import javax.swing.JPanel;
  7. import javax.swing.SwingUtilities;
  8. import javax.swing.Timer;
  9. public class Test {
  10. private Timer timer;
  11. private int count = 0;
  12. public Test() {
  13. ActionListener taskPerformer = new ActionListener() {
  14. public void actionPerformed(ActionEvent evt) {
  15. //计时器应该做什么?
  16. count++;
  17. System.out.println(count);
  18. }
  19. };
  20. timer = new Timer(1000, taskPerformer);
  21. JButton start = new JButton("开始");
  22. start.addActionListener(new ActionListener() {
  23. @Override
  24. public void actionPerformed(ActionEvent arg0) {
  25. if(!timer.isRunning()) {
  26. System.out.println("计时器已启动!");
  27. timer.start();
  28. }
  29. }
  30. });
  31. JButton stop = new JButton("停止");
  32. stop.addActionListener(new ActionListener() {
  33. @Override
  34. public void actionPerformed(ActionEvent arg0) {
  35. if(timer.isRunning()) {
  36. count = 0;
  37. System.out.println("计时器已停止!");
  38. timer.stop();
  39. }
  40. }
  41. });
  42. //最小工作示例
  43. JFrame frame = new JFrame("计时器");
  44. JPanel panel = new JPanel();
  45. panel.setLayout(new FlowLayout());
  46. panel.add(start);
  47. panel.add(stop);
  48. frame.add(panel);
  49. frame.setSize(300,300);
  50. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  51. frame.setVisible(true);
  52. }
  53. public static void main(String[] args) {
  54. SwingUtilities.invokeLater(Test::new);
  55. }
  56. }
英文:

As Andrew Thompson pointed out, you will have to go through four steps to solve this problem.

1.) The Timer should be a global variable of the class

This step is important because otherwise the object wouldn't be accessible from inside the ActionListeners we are going to create.

  1. import javax.swing.Timer;
  2. public class Test {
  3. private Timer timer;
  4. public Test() {
  5. }
  6. }

2.) Create the timer-element in the constructor

In the constructor, we are now going to initialize the timer, but - and this is important - we are not going to to start it yet.

  1. import java.awt.event.ActionEvent;
  2. import java.awt.event.ActionListener;
  3. import javax.swing.Timer;
  4. public class Test {
  5. private Timer timer;
  6. private int count = 0;
  7. public Test() {
  8. ActionListener taskPerformer = new ActionListener() {
  9. public void actionPerformed(ActionEvent evt) {
  10. //What should the timer do?
  11. count++;
  12. System.out.println(count);
  13. }
  14. };
  15. timer = new Timer(1000, taskPerformer);
  16. }
  17. }

3.) Start the timer in the ActionListener of the start-button

In this step we are adding the functionality to start the timer by pressing a button. For this purpose we are using an ActionListener and the start()-method of the timer.

  1. import java.awt.event.ActionEvent;
  2. import java.awt.event.ActionListener;
  3. import javax.swing.JButton;
  4. import javax.swing.Timer;
  5. public class Test {
  6. private Timer timer;
  7. private int count = 0;
  8. public Test() {
  9. ActionListener taskPerformer = new ActionListener() {
  10. public void actionPerformed(ActionEvent evt) {
  11. //What should the timer do?
  12. count++;
  13. System.out.println(count);
  14. }
  15. };
  16. timer = new Timer(1000, taskPerformer);
  17. JButton start = new JButton(&quot;Start&quot;);
  18. //Here the functionality is added
  19. start.addActionListener(new ActionListener() {
  20. @Override
  21. public void actionPerformed(ActionEvent arg0) {
  22. if(!timer.isRunning()) {
  23. System.out.println(&quot;Timer started!&quot;);
  24. timer.start();
  25. }
  26. }
  27. });
  28. }
  29. }

4.) Stop the timer in the ActionListener of the stop-button

This is basically the other way around. We are going to create another button to add the the functionality to stop the timer. For this purpose we are going to use an ActionListener again and the stop()-method of the timer.

  1. import java.awt.event.ActionEvent;
  2. import java.awt.event.ActionListener;
  3. import javax.swing.JButton;
  4. import javax.swing.Timer;
  5. public class Test {
  6. private Timer timer;
  7. private int count = 0;
  8. public Test() {
  9. ActionListener taskPerformer = new ActionListener() {
  10. public void actionPerformed(ActionEvent evt) {
  11. //What should the timer do?
  12. count++;
  13. System.out.println(count);
  14. }
  15. };
  16. timer = new Timer(1000, taskPerformer);
  17. JButton start = new JButton(&quot;Start&quot;);
  18. start.addActionListener(new ActionListener() {
  19. @Override
  20. public void actionPerformed(ActionEvent arg0) {
  21. if(!timer.isRunning()) {
  22. System.out.println(&quot;Timer started!&quot;);
  23. timer.start();
  24. }
  25. }
  26. });
  27. //Functionality is added here
  28. JButton stop = new JButton(&quot;stop&quot;);
  29. stop.addActionListener(new ActionListener() {
  30. @Override
  31. public void actionPerformed(ActionEvent arg0) {
  32. if(timer.isRunning()) {
  33. count = 0;
  34. System.out.println(&quot;Timer stopped!&quot;);
  35. timer.stop();
  36. }
  37. }
  38. });
  39. }
  40. }

Final step: Create the rest of the GUI

This isn't necessary for answering your question anymore, but I wanted to provide a minimal working example. For this, I am using SwingUtilities.invokeLater(). For more information on what this is doing and why you should use it, please see this question.

  1. import java.awt.FlowLayout;
  2. import java.awt.event.ActionEvent;
  3. import java.awt.event.ActionListener;
  4. import javax.swing.JButton;
  5. import javax.swing.JFrame;
  6. import javax.swing.JPanel;
  7. import javax.swing.SwingUtilities;
  8. import javax.swing.Timer;
  9. public class Test {
  10. private Timer timer;
  11. private int count = 0;
  12. public Test() {
  13. ActionListener taskPerformer = new ActionListener() {
  14. public void actionPerformed(ActionEvent evt) {
  15. //What should the timer do?
  16. count++;
  17. System.out.println(count);
  18. }
  19. };
  20. timer = new Timer(1000, taskPerformer);
  21. JButton start = new JButton(&quot;Start&quot;);
  22. start.addActionListener(new ActionListener() {
  23. @Override
  24. public void actionPerformed(ActionEvent arg0) {
  25. if(!timer.isRunning()) {
  26. System.out.println(&quot;Timer started!&quot;);
  27. timer.start();
  28. }
  29. }
  30. });
  31. JButton stop = new JButton(&quot;stop&quot;);
  32. stop.addActionListener(new ActionListener() {
  33. @Override
  34. public void actionPerformed(ActionEvent arg0) {
  35. if(timer.isRunning()) {
  36. count = 0;
  37. System.out.println(&quot;Timer stopped!&quot;);
  38. timer.stop();
  39. }
  40. }
  41. });
  42. //Minimal working example
  43. JFrame frame = new JFrame(&quot;Timer&quot;);
  44. JPanel panel = new JPanel();
  45. panel.setLayout(new FlowLayout());
  46. panel.add(start);
  47. panel.add(stop);
  48. frame.add(panel);
  49. frame.setSize(300,300);
  50. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  51. frame.setVisible(true);
  52. }
  53. public static void main(String[] args) {
  54. SwingUtilities.invokeLater(Test::new);
  55. }
  56. }

huangapple
  • 本文由 发表于 2020年9月22日 11:38:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/64002760.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定