Java, замена бесконечных циклов? - PullRequest
5 голосов
/ 19 января 2010

Я делаю программу, которая показывает рост клеток через массив. Я понял, что когда я нажимаю кнопку запуска, массив обновляется каждые 10 секунд в цикле while (true) {}. Проблема в том, что я хочу иметь возможность остановить цикл нажатием кнопки паузы, но пока он находится в цикле, он не позволит мне использовать какой-либо из элементов управления. Мне нужно что-то, кроме бесконечного цикла в Orer, чтобы обновить кадры.

Я немного новичок, но сейчас я учусь на Java. поэтому я немного понимаю язык.

Ответы [ 8 ]

10 голосов
/ 19 января 2010

Я бы предложил использовать отдельный поток для обработки массива. Убедитесь, что вы используете потокобезопасный объект (проверьте Java Docs) и просто вызовите .start () для вашего объекта потока, когда вы хотите начать. Держите указатель на него, чтобы вы могли приостановить его с помощью setPaused (true)

Как то так ....

class MyArrayUpdater extends Thread {
    private volatile boolean enabled = true;
    private volatile boolean paused = true;

    @Override
    public void run() {
        super.run();
        try {
            while (enabled) {
                if (!paused) {
                    // Do stuff to your array here.....
                }
                Thread.sleep(1);
            }
        } catch (InterruptedException ex) {
            // handle ex
        }
    }

    public void setEnabled(boolean arg) {
        enabled = arg;
    }

    public void setPaused(boolean arg) {
        paused = arg;
    }
}
6 голосов
/ 20 января 2010

Вам нужно использовать Таймер , который изменяет состояние вашего компонента (в данном случае рост сотовой связи), а затем вызвать JComponent.repaint()

Этот таймер может быть отменен , чтобы сделать паузу и затем перезапустить ее, вы просто создаете новый:

Таким образом, вы можете определить следующие два метода:

private Timer timer;
...
public void startPaiting() {
    timer = new Timer();
    timer.schedule( new TimerTask(){
        public void run(){
            changeState();
            repaint();
        }
    },0,  10000 ); // 10 s. 
}

public void pause(){
    timer.cancel();
}

И затем в вашей кнопке «Пауза / Возобновить» вызовите методы «пауза / старт-пейтинг»:

if( e.getActionCommand().equals("Pause")){
    growPanel.pause();
    setText("Resume");
} else {
    growPanel.startPaiting();
    setText("Pause");
}

http://img512.imageshack.us/img512/7119/capturadepantalla201001.png

Вот полный исходный код, чтобы увидеть, как он работает:

import javax.swing.*;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.*;
import java.util.Timer;
import java.util.TimerTask;

public class Grow {

    public static void main( String [] args ) {
        JFrame frame = new JFrame();
        final GrowPanel growPanel = new GrowPanel();
        frame.add( growPanel );
        frame.add( new JPanel(){{
            add( new JButton("Pause"){{
                addActionListener( new ActionListener(){
                    public void actionPerformed( ActionEvent e ){
                        if( e.getActionCommand().equals("Pause")){
                            growPanel.pause();
                            setText("Resume");
                        } else {
                            growPanel.startPaiting();
                            setText("Pause");
                        }
                    }
                });
        }});}}, java.awt.BorderLayout.SOUTH );
        frame.setSize( 400, 300 );
        frame.setVisible( true );
    }
}

class GrowPanel extends JComponent {
    private int x;
    private int y;
    private Timer timer;
    GrowPanel() {
        x = 10;
        y = 10;
        startPaiting();
    }

    public void startPaiting() {
        timer = new Timer();
        timer.schedule( new TimerTask(){
            public void run(){
                changeState();
                repaint();
            }
        },0,  100 ); // or 10000 which is 10 s. 
    }

    public void pause(){
        timer.cancel();
    }

    public void paintComponent( Graphics g ){
        g.fillOval( x, y, 10, 10 );
    }
    private void changeState(){
            x+=10;
            if( x >= 400 ) {
                y+=10;
                x = 0;
            }
            if( y >= 300 ){
                y = 10;
            }
    }

}
2 голосов
/ 19 января 2010

Если эти «кнопки» являются кнопками Swing, то способ сделать это: заставить кнопку «Пуск» создать новый объект javax.swing.Timer, который обновляется каждые 10 секунд.Затем нажмите кнопку «Пауза», чтобы остановить таймер.

1 голос
/ 19 января 2010

Лично я предпочитаю использовать класс Timer , а не Thread или Thread.sleep(). Класс timer обрабатывает как периодический запуск кода, так и его отмену.

Ваш код будет выглядеть так:

TimerTask myTask = new TimerTask() {
  public void run() {
    // here goes my code
  }
};

Timer timer = new Timer();
timer.schedule(myTask, 0 /*starts now*/, 10 * 1000 /* every 10 seconds */);

// whenever you need to cancel it:
timer.cancel();
1 голос
/ 19 января 2010

Вы хотите запустить симуляцию в потоке (ищите Runnable Interface). Затем вы можете передавать сообщения в эту ветку для приостановки, продолжения и остановки.

0 голосов
/ 19 января 2010

Посмотрите на механизмы wait () / notify (). Вкратце, поток может ждать 10 секунд, но все равно получать уведомление о том, что произошло внешнее событие,

0 голосов
/ 19 января 2010

То, что вы ищете, это многопоточность. Возьмите обработку данных и поместите ее во второй поток, запустите ее асинхронно и используйте основной поток для проверки ввода пользователя.

Конечно, это может также повлечь использование семафора для связи между двумя потоками. На каком уровне вы учитесь - вы уже рассмотрели обе эти темы?

0 голосов
/ 19 января 2010

Да. Похоже, вы рисуете в потоке диспетчера событий. События (нажатия кнопок) никогда не могут быть вызваны, потому что вы никогда не возвращали управление с момента последнего вызова ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...