Пятница, 2025-02-07, 23:48:08
Главная Регистрация RSS
Приветствую Вас, Гость
[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
задание 21.10 - таймеры и многопоточность
CHerryДата: Суббота, 2011-10-22, 16:37:34 | Сообщение # 1
Генералиссимус
Группа: Администраторы
Сообщений: 141
Репутация: 3732
Статус: Offline
Реализовать на swing два потока таймеров.

статья про потоки и swing
 
CHerryДата: Суббота, 2011-10-22, 16:37:44 | Сообщение # 2
Генералиссимус
Группа: Администраторы
Сообщений: 141
Репутация: 3732
Статус: Offline
Мой рабочий пример с потоками, но пока в консоли...
кстати в Java 1.5 был добавлен новый пакет java.util.concurrent, который более гибко реализует многопоточность и позволяет реализовать параллельные вычисления.

Создаем наш главный класс Timers откуда и будут стартовать потоки запуска других таймеров
Code
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Timers {
      /**
       * @author Cherry
       * Реализация многопоточности с использованием исполнителей (executors)
       * из библиотеки java.util.concurent
       * этот способ запуска рекомендован для использования начиная с версии Java SE5
       */
      public static void main(String[] args) {
          ExecutorService exec = Executors.newCachedThreadPool();
              System.out.println("создаем первый поток");
              exec.execute(new MyTimer());
                
              System.out.println("создаем второй поток");
              exec.execute(new MyTimer());
                
              System.out.println("создаем третий поток");
              exec.execute(new MyTimer());
      }

}



далее создаем MyTimer класс (в нашем проекте), который будет реализовывать работу наших таймеров, экземпляров класса MyTimer.
Code
// наш класс обязательно должен реализовать интерфейс Runnable
// который включает в себя метод run()

public class MyTimer implements Runnable{
      // счетчик и ключ для определения номера экземпляра класса (потока)
      static int count=1;
      final int id = count++;
        
      MyTimer() {
          System.out.println("номер потока id="+id);
      }
        
      public void run() {
          for (int i=1;i<10;i++){
              System.out.print(" #"+id);
                  try {
                      Thread.sleep(100);
                  } catch (InterruptedException e) {}
          }
      }
}
 
CHerryДата: Воскресенье, 2011-10-23, 00:05:12 | Сообщение # 3
Генералиссимус
Группа: Администраторы
Сообщений: 141
Репутация: 3732
Статус: Offline
А вот в swing ничего не получается. А точнее вроде как поток создается, но вывести не удается.

Code
package ua.at.javac;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.swing.SwingUtilities;

public class TimerJFrame extends javax.swing.JFrame{

     private javax.swing.JButton jButtonStart;
     private static javax.swing.JLabel jLabelTimer1;
     private javax.swing.JLabel jLabelTimer2;
     private static final long serialVersionUID = 1L;

     public javax.swing.JLabel getjLabelTimer1() {
         return jLabelTimer1;
     }

     public void setjLabelTimer1(javax.swing.JLabel jLabelTimer1) {
         this.jLabelTimer1 = jLabelTimer1;
     }

     public TimerJFrame() {
         initComponents();
     }

     private void initComponents() {

         setjLabelTimer1(new javax.swing.JLabel());
         jLabelTimer2 = new javax.swing.JLabel();
         jButtonStart = new javax.swing.JButton();

         setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

         getjLabelTimer1().setText("0");

         jLabelTimer2.setText("10");

         jButtonStart.setText("Start");
         jButtonStart.addActionListener(new java.awt.event.ActionListener() {
             public void actionPerformed(java.awt.event.ActionEvent evt) {

                 try {
                     Thread.sleep(2000);
                     jLabelTimer1.setText(" one");
                     Thread.sleep(2000);
                     jLabelTimer1.setText(" two");

                 } catch (InterruptedException e) {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
                 }

                  
             }
         });

         javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
         getContentPane().setLayout(layout);
         layout.setHorizontalGroup(
             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
             .addGroup(layout.createSequentialGroup()
                 .addGap(60, 60, 60)
                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                     .addComponent(jButtonStart, javax.swing.GroupLayout.PREFERRED_SIZE, 200, javax.swing.GroupLayout.PREFERRED_SIZE)
                     .addGroup(layout.createSequentialGroup()
                         .addComponent(getjLabelTimer1(), javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)
                         .addGap(50, 50, 50)
                         .addComponent(jLabelTimer2, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)))
                 .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
         );
         layout.setVerticalGroup(
             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
             .addGroup(layout.createSequentialGroup()
                 .addContainerGap()
                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                     .addComponent(getjLabelTimer1())
                     .addComponent(jLabelTimer2))
                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                 .addComponent(jButtonStart)
                 .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
         );

         pack();
     }

     public static void main(String args[]) {

         java.awt.EventQueue.invokeLater(new Runnable() {
             public void run() {
                 new TimerJFrame().setVisible(true);
             }
         });
          
          
              
              
              
              
          

     }
      
     public void setjLabelTimer1(String s) {
         this.jLabelTimer1.setText(s);
     }

}
 
MINIshaДата: Воскресенье, 2011-10-23, 18:29:29 | Сообщение # 4
Генерал-майор
Группа: Администраторы
Сообщений: 21
Репутация: 1293
Статус: Offline
Это работает !!!
Code

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

class swingTimer {    
Thread g;
JFrame frame;
public JLabel label;
JPanel panel2;
String ii;
ActionListener list;

public swingTimer() {   //основной класс с формой
frame = new JFrame("Timer");

JPanel panel = new JPanel();
panel.setLayout(new GridLayout(3,2));
JPanel panel1 = new JPanel();
panel2 = new JPanel();
panel.add(panel1);
panel.add(panel2);

JButton button = new JButton("START!");
label = new JLabel();
label.setText("Hello!");
g = new Go();                //т.к. Go() наследник Thread(), то при вызове его метода
//start() создаётся новый поток и используется метод run() в котором я описал что должно  
//передаваться потоку;
list = new ActionListener(){
@SuppressWarnings("deprecation")

public void actionPerformed(ActionEvent ae)
{
try {

if ((g.getState() == Thread.State.TERMINATED)||(g.isAlive())){ //если поток живой
g.interrupt(); //убить поток
g.stop(); //остановить поток
g=new Go();//создать новый поток
}
}
catch (Exception e) {
//    System.out.println(e);
//    e.printStackTrace();
}

g.start(); //стартовать поток

}

};
button.addActionListener(list);

panel1.add(button);
panel2.add(label);

frame.add(panel);
frame.setSize(400, 400);

frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

}

class Go extends Thread {//вложенный класс-наследник Thread
swingTimer st1;

public void run(){

st1 = swingTimer.this; //обращаюсь к данному экземпляру класса
for (int i = 0;i<=5; i++ ){

st1.label.setText(Integer.toString(i));
System.out.println(Integer.toString(i));
try {
Thread.sleep(500);
}
catch (Exception e) {
System.out.println(e);
e.printStackTrace();
}
}
end = true;
}
}
}


Code
public class MainTimer {
public static void main (String[] ar){
new swingTimer(); //тупо создаю экземпляр класса
}
}


Жду ответов!!! biggrin :D biggrin


Почему? ДА ЧЕРЕЗ ПОТОМУ КАК ЧТОЖ!

Сообщение отредактировал MINIsha - Понедельник, 2011-10-24, 09:52:51
 
CHerryДата: Воскресенье, 2011-10-23, 19:15:39 | Сообщение # 5
Генералиссимус
Группа: Администраторы
Сообщений: 141
Репутация: 3732
Статус: Offline
Общие мысли по архитектуре такие:
Должен быть класс Main откуда запускаются :
один поток для swing GUI
второй для таймера, третий для второго таймера и т.д.

Как создать поток, я вижу так:
Code

             ExecutorService exec = Executors.newCachedThreadPool();
             exec.execute(new MyTimer());


Как создать форму тоже понятно.

А вот как передать из класса MyTimer в элемент метку(Label) класса формы непонятно.

На других форумах предлагаю использовать JavaUtils.invoke
и класс SwingWorker
 
CHerryДата: Воскресенье, 2011-10-23, 22:01:10 | Сообщение # 6
Генералиссимус
Группа: Администраторы
Сообщений: 141
Репутация: 3732
Статус: Offline
статья про потоки и swing
 
j_todeskyДата: Воскресенье, 2011-10-23, 23:42:56 | Сообщение # 7
Рядовой
Группа: Проверенные
Сообщений: 18
Репутация: 1
Статус: Offline
я тоже кое что изобразил , проанализировав Мишин текст
Code

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class SwingTimer
{
     JTextField text;
     JFrame frame ;
     JLabel label;
     JLabel label1;
     Thread g;
     final Thread thr1;
     JTabbedPane zakladka;
     JPanel panel;
     Thread back;
     SwingTimer()
     {
frame = new JFrame("Timer");
         panel= new JPanel();
         panel.setLayout(new GridLayout(4,4));
         label= new JLabel("time");
         label1 = new JLabel("backtime");
         JLabel label3 = new JLabel("sec    ");
         JLabel label4 = new JLabel("sec    ");
         thr1 = new Thread();
         JPanel panel1 =new JPanel();
         JPanel panel2= new JPanel();
         JPanel panel3= new JPanel();
         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         g = new Go();
         back = new BackTimer();
       JButton jStartBack = new JButton("STARTBackTIMER!");
   jStartBack.addActionListener(new ActionListener(){
          public void actionPerformed(ActionEvent ae)
       {
                 try {

                     if ((back.getState() == Thread.State.TERMINATED)||(back.isAlive())){
                     back.interrupt();
                     //back.stop();
                     back=new BackTimer();
                     }
                     }
                 catch (Exception e) {
                     }
                 back.start();
       }
   });
       JButton jStart = new JButton("START!");
   jStart.addActionListener(new ActionListener(){
          public void actionPerformed(ActionEvent ae)
       {
                 try {

                     if ((g.getState() == Thread.State.TERMINATED)||(g.isAlive())){
                     g.interrupt();
                     //g.stop();
                     g=new Go();
                     }
                     }
                 catch (Exception e) {
                     }
                 g.start();
       }
   });
       JButton jPause = new JButton("PAUSE!");
         jPause.addActionListener(new ActionListener(){
             public void actionPerformed(ActionEvent ae)
             {
                 g.suspend();

             }
         });
      JButton jStopBackCount = new JButton("StopBackCount");
     jStopBackCount.addActionListener(new ActionListener(){
         public void actionPerformed(ActionEvent ae)
         {
             back.suspend();
         }
     });
panel2.add(label);
         panel2.add(label3) ;
         panel2.add(label1);
         panel2.add(label4) ;
         panel3.add(jStart);
         panel3.add(jStartBack);
         panel1.add(jPause);
         panel1.add(jStopBackCount);
         panel.add(panel3);
         panel.add(panel1);
         panel.add(panel2);
         frame.add(panel);
         frame.setSize(300,300);
         frame.setVisible(true);
         frame.setBackground(Color.red);
     }
     class BackTimer extends  Thread{
         SwingTimer st2;
         public void run (){
             st2= SwingTimer.this;
             for (int i=25;i>0; i--)
             {
                 st2.label1.setText(Integer.toString(i));
                 System.out.println(Integer.toString(i));
                 try{
                     Thread.sleep(1000);
                 }
                 catch(Exception e){}
             }
         }
     }
     class Go extends Thread{
     SwingTimer st1;
     public void run()
     {
         st1 = SwingTimer.this;
         for (int i = 0;; i++ )
             {
                 st1.label.setText(Integer.toString(i));
                 System.out.println(Integer.toString(i));
                 try {
                     Thread.sleep(1000);
                     }
                 catch (Exception e) {
                    // System.out.println(e);
                    // e.printStackTrace();
                     }
             }
     }
}
}
public class Main {
     public static void main(String[] args) {
         new SwingTimer();
     }
}
 
CHerryДата: Понедельник, 2011-10-24, 10:39:59 | Сообщение # 8
Генералиссимус
Группа: Администраторы
Сообщений: 141
Репутация: 3732
Статус: Offline
Кстати методы suspend() помечены как Deprecated.
А чем же их заменить ?
 
MINIshaДата: Понедельник, 2011-10-24, 12:10:53 | Сообщение # 9
Генерал-майор
Группа: Администраторы
Сообщений: 21
Репутация: 1293
Статус: Offline
Quote (CHerry)
Кстати методы suspend() помечены как Deprecated.
А чем же их заменить ?


прочтите это

или

вот это

очень познавательно!

Добавлено (2011-10-24, 12:10:53)
---------------------------------------------

Quote (CHerry)
статья про потоки и swing


Кстати, здесь рассказывается о моей программе:

... где вместо того, чтобы
блокировать поток событий пока не завершится метод wait, создается
анонимный внутренний класс, который расширяет java.lang.Thread,
который будет вызывать для нас метод wait. В этой версии кода, событие
больше не будет ждать завершения метода wait, а просто вернет управление
остальному приложению (передаче собития другим слушателям) после того,
как новый поток инициализировался и запустился. В результате имеем
быструю реакцию на события и не заторможенную работу GUI.


Почему? ДА ЧЕРЕЗ ПОТОМУ КАК ЧТОЖ!

Сообщение отредактировал MINIsha - Понедельник, 2011-10-24, 11:56:42
 
CHerryДата: Понедельник, 2011-10-24, 13:23:17 | Сообщение # 10
Генералиссимус
Группа: Администраторы
Сообщений: 141
Репутация: 3732
Статус: Offline
В этих статьях описана работа устаревшей модели потоков, в коментах пишут что это статья 1996.
я так понял, за эти годы методы приостановления потоков оказались не безопасны и сейчас не используются.
Как же быть?
 
CHerryДата: Воскресенье, 2011-10-30, 18:23:52 | Сообщение # 11
Генералиссимус
Группа: Администраторы
Сообщений: 141
Репутация: 3732
Статус: Offline
Вот я созрел и дописал код используя рекомендации в Java SE5/6
а собственно:
Исполнители ExecutorService вместо Thread
и ожидание TimeUnit вместо Thread.sleep
прорисовку GUI через поток invokeLater

Code
package ua.at.javac;

import java.awt.GridLayout;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import javax.swing.*;
           
public class jFrameGUI extends JFrame {
       /**
        *
        */
       private static final long serialVersionUID = 1L;
       // объявляем переменную JLabel и открытый метод доступа к ней
       private JLabel countLabel;
       public void setCountLabel (String text) throws InterruptedException{
           countLabel.setText(text);
           TimeUnit.SECONDS.sleep(1);
       }
       private JLabel timeLabel;
       // флаги состояния нажатых кнопок
       public boolean pressPause=false;
       public boolean pressStop=false;
       public boolean pressReset=false;

       /**
        * Инициализация графического окна
        *
        */

       public void initGUI() {

           // создаем исполнителя exec для выполнения объекта Runnable
           // используем два потока для таймера и счетчика
           final ExecutorService exec = Executors.newFixedThreadPool(2);

           // создание фрейма
           JFrame frame = new JFrame();
           frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

           // кнопки
           final JButton buttonStop = new JButton("Stop");
           final JButton buttonReset = new JButton("Reset");
           final JButton buttonPause = new JButton("Pause");
           JButton buttonStart = new JButton("Start");
           buttonStop.setEnabled(false);
           buttonReset.setEnabled(false);
           buttonPause.setEnabled(false);

           // слушаем кнопки Start, Stop, Reset, Pause    
           buttonStart.addActionListener(
                   new java.awt.event.ActionListener() {
                       public void actionPerformed(java.awt.event.ActionEvent evt) {
                           exec.execute(new CountDown());
                           buttonStop.setEnabled(true);
                           buttonPause.setEnabled(true);
                           buttonReset.setEnabled(true);
                           pressPause=false;
                           pressStop=false;
                        
                       }
                   }
            );

           buttonStop.addActionListener(
                   new java.awt.event.ActionListener() {
                       public void actionPerformed(java.awt.event.ActionEvent evt) {
                           pressStop=true;
                           buttonStop.setEnabled(false);
                           buttonPause.setEnabled(false);
                           buttonReset.setEnabled(false);
                       }
                   }
            );

           buttonReset.addActionListener(
                   new java.awt.event.ActionListener() {
                       public void actionPerformed(java.awt.event.ActionEvent evt) {
                           pressReset=true;
                           buttonStop.setEnabled(false);
                           buttonPause.setEnabled(false);
                           buttonReset.setEnabled(false);
                       }
                   }
            );

           buttonPause.addActionListener(
                   new java.awt.event.ActionListener() {
                       public void actionPerformed(java.awt.event.ActionEvent evt) {
                           buttonPause.setSelected(true);
                           pressPause=true;
                           buttonPause.setEnabled(false);
                       }
                   }
            );

           // метки
           timeLabel = new JLabel("Timer");
           countLabel = new JLabel("Count");

               // запускаем отсчет времени и вывод в timeLabel в отдельном потоке
               exec.execute(new Runnable(){
                   @Override
                   public void run() {
                       // TODO Auto-generated method stub
                       int i=0;
                       while(true){
                           i++;
                           timeLabel.setText(""+i);
                           try {
                     TimeUnit.SECONDS.sleep(1);
                           } catch (InterruptedException e) {
                     e.printStackTrace();
                           }
                       }
                   }

               });

           // создание табличной панели 2 строки * 3 столбца, отступы 10 * 10
           JPanel panel = new JPanel();
           frame.add(panel);
           panel.setLayout(new GridLayout(2,3,10,10));

           // добавление элементов в табличную панель
           panel.add(timeLabel);
           panel.add(buttonStart);
           panel.add(buttonPause);
           panel.add(countLabel);
           panel.add(buttonStop);
           panel.add(buttonReset);

           // создание формы
           frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
           //frame.setSize(300, 100);
           frame.pack();
           frame.setTitle("Timer");
           frame.setVisible(true);
       }

       public class CountDown implements Runnable {
           @Override
           public void run() {
               // TODO Auto-generated method stub
               int i=0;
               while (pressStop==false){
                   if (pressPause==false){
                       i++;
                       try {
                           setCountLabel(""+i);
                           // устаревшая конструкция Thread.sleep(100)    
                           // заменена на новую TimeUnit.SECONDS.sleep(1)
                           TimeUnit.SECONDS.sleep(1);
                       } catch (InterruptedException e) {
                           e.printStackTrace();
                       }
                   }
                   if (pressReset==true) {
                       pressReset=false;
                       i=0;
                       try {
                           setCountLabel("0");
                       } catch (InterruptedException e) {
                           // TODO Auto-generated catch block
                           e.printStackTrace();
                       }
                   }
               }

           }
       }

       public static void main(String[] args) {

           // Создание потока для инициализации окна
          javax.swing.SwingUtilities.invokeLater(new Runnable() {
             public void run() {
                new jFrameGUI().initGUI();
             }
          });
          //

       }
}
[/code]
 
  • Страница 1 из 1
  • 1
Поиск: