2016-02-04 3 views
0

Как использовать WindowBuilder в eclipse для печати чисел из цикла for в текстовое поле, я сделал цикл for для запуска счетчика при нажатии кнопки start (до 60). Я просто задаюсь вопросом, как бы вы его отображали в другом текстовом поле, когда я нажимаю кнопку «Пуск». Если это объяснение было не столь ясным, другими словами, я делаю секундомер, и когда вы нажимаете кнопку запуска, он печатает до 60 в консоли eclipse. Я хочу, чтобы эти числа отображались в поле JText в окне, когда я нажимаю кнопку «Пуск». Любая помощь приветствуется :)Печать чисел с использованием Jframe/текстовых полей

здесь страница кода, я надеюсь, что вы, ребята (или девушки) может помочь мне :) (это то, что я пытался сделать.

package com.racecar484.user; 

import java.awt.EventQueue; 

import javax.swing.JFrame; 
import javax.swing.JTextField; 
import javax.swing.JButton; 
import java.awt.event.ActionListener; 
import java.awt.event.ActionEvent; 
import javax.swing.SwingConstants; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.awt.Color; 
import javax.swing.JLabel; 
import javax.swing.JTable; 

public class StopWatch extends ForLoopTesting { 

    private JFrame frmStopWatchPro; 
    private JTextField txtClickMeTo; 
    private JButton Terminate; 

    /** 
    * Launch the application. 
    */ 
    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       try { 
        StopWatch window = new StopWatch(); 
        window.frmStopWatchPro.setVisible(true); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 

    /** 
    * Create the application. 
    */ 
    public StopWatch() { 
     initialize(); 
    } 

    /** 
    * Initialize the contents of the frame. 
    * @param i 
    */ 



    private void initialize(String i) { 
     frmStopWatchPro = new JFrame(); 
     frmStopWatchPro.getContentPane().setBackground(new Color(255, 127, 80)); 
     frmStopWatchPro.setTitle("Stop Watch Pro"); 
     frmStopWatchPro.setBounds(100, 100, 450, 300); 
     frmStopWatchPro.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frmStopWatchPro.getContentPane().setLayout(null); 

     txtClickMeTo = new JTextField(); 
     for(int i1 = 0; i1 < 60; i1++){ 
      try { 
       Thread.sleep(1000); 
      } catch (InterruptedException e1) { 
       // TODO Auto-generated catch block 
       e1.printStackTrace(); 
      } 
     } 

     txtClickMeTo.setText(i); 
     txtClickMeTo.addMouseListener(new MouseAdapter() { 
      @Override 
      public void mouseClicked(MouseEvent arg0) { 

      System.out.println("Oh my god this worked!"); 

      } 
     }); 
     txtClickMeTo.setEditable(false); 
     txtClickMeTo.setBounds(19, 24, 300, 58); 
     frmStopWatchPro.getContentPane().add(txtClickMeTo); 
     txtClickMeTo.setColumns(10); 

     JButton btnNewButton = new JButton("Start"); 
     btnNewButton.addMouseListener(new MouseAdapter() { 
      @Override 
      public void mouseClicked(MouseEvent e) { 
       System.out.println("Stop-Watch activated."); 
       for(int i = 0; i < 60; i++){ 
        System.out.println(i); 
        try { 
         Thread.sleep(1000); 
        } catch (InterruptedException e1) { 
         // TODO Auto-generated catch block 
         e1.printStackTrace(); 
        } 
       } 
      } 
     }); 
     btnNewButton.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent arg0) { 
      } 
     }); 
     btnNewButton.setBounds(53, 121, 108, 40); 
     frmStopWatchPro.getContentPane().add(btnNewButton); 

     JButton btnStop = new JButton("Stop"); 
     btnStop.addMouseListener(new MouseAdapter() { 
      @Override 
      public void mouseClicked(MouseEvent e) { 
      String Meow = "hey"; 
       System.out.println("Stop-Watch stopped."); 
      } 
     }); 
     btnStop.setBounds(211, 121, 108, 40); 
     frmStopWatchPro.getContentPane().add(btnStop); 

     Terminate = new JButton("Terminate"); 
     Terminate.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent arg0) { 

      frmStopWatchPro.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       System.out.println("Closing Application."); 
      System.exit(0); 
      } 
     }); 
     Terminate.setBounds(329, 0, 105, 261); 
     frmStopWatchPro.getContentPane().add(Terminate); 

     JLabel lblonlyOneThat = new JLabel("(Only one that actually works without console ->)"); 
     lblonlyOneThat.setBounds(53, 211, 266, 39); 
     frmStopWatchPro.getContentPane().add(lblonlyOneThat); 

     JLabel lblStopWatchPro = new JLabel("Stop Watch Pro V.1- made by Andrew Lopez "); 
     lblStopWatchPro.setBounds(53, 187, 257, 29); 
     frmStopWatchPro.getContentPane().add(lblStopWatchPro); 
    } 
} 

ответ

1

Ваше понимание По моему мнению, структура Java swing несколько ограничена. У вас есть две основные проблемы: одна из них вы уже описали в своем вопросе, а другая - то, что вы не знаете, как сделать таймер.

В настоящий момент вы являетесь используя Thread.sleep(1000) в виде «ожидания» в течение 1 секунды. Но вы положили его в метод initialize. Почему вы хотите подождать 60 секунд, когда w indow инициализирует? Для меня это не имеет смысла.

Я вижу, что у вас есть еще один Thread.sleep(1000) в прослушивателе кликов для кнопки запуска. Это имеет смысл, но вы не установили текст txtClickMeTo.

Это должно быть так:

for(int i = 0; i < 60; i++){ 
    System.out.println(i); 
    try { 
     Thread.sleep(1000); 
     txtClickMeTo.setText(Integer.toString(i)); 
    } catch (InterruptedException e1) { 
     // TODO Auto-generated catch block 
     e1.printStackTrace(); 
    } 
} 

Кроме того, необходимо отметить txtClickMeTo в final, если вы сделаете это.

final JTextField txtClickMeTo = new JTextField(); 

Таким образом, кнопка запуска будет работать отлично.

Но как насчет кнопки остановки? почему он не работает, когда я запускаю таймер?

Причина: Thread.sleep вызывает блокирует. Метод блокирует поток от продолжения, поэтому пользовательские взаимодействия могут реагировать только после 60 секунд.

В результате Thread.sleep не рекомендуется применять для качания. Вместо этого вы используете javax.swing.Timer. Это очень удобно. Он предоставляет множество удобных способов для использования вашей кнопки остановки.

Вот документация для этого: https://docs.oracle.com/javase/7/docs/api/javax/swing/Timer.html

А вот учебник для этого: https://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html

EDIT:

Я покажу вам код для использования таймера качели для удовлетворения требование.

Сначала вам нужно создать (конечно!)

Timer t = new Timer(1000, new ActionListener() { 
    public void actionPerformed(ActionEvent e) { 
     // blah blah blah 
    } 
}); 

В этом коде 1000 означает, что таймер будет срабатывать каждые 1000 миллисекунд или 1 секунду.И вторым параметром является действие, которое необходимо выполнить при запуске таймера, в этом случае вы должны установить текст txtClickMeTo на некоторое число.

Конечно, вам нужно следить за то, что число должно быть, поэтому сделать переменную для хранения, что:

int secondsElapsed = 0; 

И вы в основном только установить текст JTextField в secondsElasped и увеличить его.

1

Swing - однопоточный, что означает, что если вы делаете что-либо, что блокирует Thread Dispatching Thread, например, запускает цикл, используя Thread.sleep или какой-либо другой длительный процесс, пользовательский интерфейс не будет обновляться (и никаких новых событий не будет обработанный).

свинг тоже не поточно, это означает, что вы никогда не должны обновить пользовательский интерфейс с любого другого потока, чем EDT

Start, взглянув на Concurrency in Swing для получения более подробной информации.

Вопрос в том, как вы можете это исправить? Вы можете использовать Thread и SwingUtilities.invokeLater, но это довольно грязно. Вы можете использовать SwingWorker, но это очень тяжело. Лучшим решением было бы использовать Swing Timer, который вызывает зарегистрированный обратный вызов (ActionListener) через регулярные промежутки времени из EDT, что позволяет безопасно обновлять пользовательский интерфейс изнутри.

Для получения более подробной информации смотрите How to use Swing Timers.

И для примера ...

import java.awt.EventQueue; 
import java.awt.GridBagConstraints; 
import java.awt.GridBagLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JTextField; 
import javax.swing.Timer; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class StopWatch { 

    public static void main(String[] args) { 
     new StopWatch(); 
    } 

    public StopWatch() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
        ex.printStackTrace(); 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     private JTextField field; 
     private Timer timer; 
     private int counter; 

     public TestPane() { 
      setLayout(new GridBagLayout()); 
      GridBagConstraints gbc = new GridBagConstraints(); 
      gbc.gridwidth = GridBagConstraints.REMAINDER; 
      field = new JTextField(4); 
      add(field, gbc); 

      JButton btn = new JButton("Start"); 
      btn.addActionListener(new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        if (timer.isRunning()) { 
         timer.stop(); 
         btn.setText("Start"); 
        } else { 
         counter = 0; 
         timer.start(); 
         field.setText(Integer.toString(counter)); 
         btn.setText("Stop"); 
        } 
       } 
      }); 
      add(btn, gbc); 

      timer = new Timer(1000, new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        counter++; 
        if (counter >= 60) { 
         timer.stop(); 
         btn.setText("Start"); 
        } 
        field.setText(Integer.toString(counter)); 
       } 
      }); 

     } 

    } 

} 

Cavet: Это простой пример. Свинг Timer гарантирует, что он назовет ActionListener ПОСЛЕ заданной задержки, что делает его несколько неточным (в миллисекундах). Более «соответствующее» решение было бы использовать сравнение между временем Timer был начат и временем ActionListener был уведомлен

Вы также можете захотеть взглянуть на How to Use Buttons, Check Boxes, and Radio Buttons и How to Write an Action Listeners для более подходящего механизма для работы с кнопками

Смежные вопросы