Определение области видимости Java с помощью ActionListeners

#java #swing #timer

#java #swing #таймер

Вопрос:

У меня есть приложение, которому необходимо сканировать устройства Bluetooth каждые 10 минут в течение продолжительности, установленной пользователем.

У меня есть два javax.swing.Таймер (не java.util.Таймер) — один управляет вызовом метода сканирования каждые 10 минут, другой останавливает первый таймер (следовательно, останавливает сканирование) после достижения предела продолжительности.

durationTimer создается и запускается в ActionListener.

Моя проблема в том, что, поскольку durationTimer создается в ActionListener, я не могу остановить таймер из другого ActionListener, поскольку программа не может «видеть» имя переменной «durationTimer».

Сокращенный код показан ниже….

 public class mainGui extends JFrame

{



public mainGui()

  {

    final ActionListener timerActionEvent = new ActionListener(){

        public void actionPerformed(ActionEvent evt){

            //start a task here

            Timer myTimer2 = (Timer) evt.getSource();

            //Invoke BluetoothScan method

            BluetoothScan(myTimer2);

        }

    };







    final Timer timerDuration;

    final Timer myTimer = new Timer(5000, timerActionEvent); 



    final ActionListener timerDurationActionEvent = new ActionListener(){

        public void actionPerformed(ActionEvent evt){

            //Stops myTimer, so that Bluetooth Stops scanning every 10mins. 

            myTimer.stop();

        }

    };






    ActionListener btnScanAction = new ActionListener(){

    //Action listener for reading data from db

    public void actionPerformed(ActionEvent e){

        int roomID = 0;

        int lecturer = 0;

        int unit;

        int roomIDIndex;

        int lectIDIndex;

        int yearIDIndex;

        int unitIDIndex;

        String[] roomArray;

        String[] lecturerArray;

        String[] unitArray = null;

        int durationIndex;

        String DURATION;

        int durationInt;





        //System.out.println(unitArray.length);

        durationIndex = durCB.getSelectedIndex();

        DURATION = itemDuration[durationIndex];

        durationInt = Integer.parseInt(DURATION);



        //User Selected Duration converted to Milliseconds

        int durationMilliSec = (int)(durationInt*60000);



        ArrayList<String[]> unitYear = null;



        //Store the index ID of the JComboBox Selections

        roomIDIndex = roomCB.getSelectedIndex();

        lectIDIndex = lectCB.getSelectedIndex();

        unitIDIndex = unitCB.getSelectedIndex();

        yearIDIndex = yearCB.getSelectedIndex();



        switch(yearIDIndex)

        {

        case 1: unitYear = Units1; break;

        case 2: unitYear = Units2; break;

        case 3: unitYear = Units3; break;

        case 4: unitYear = UnitsMasters; break;

        }



        //Get the Array contents at index location

        roomArray = rooms.get(roomIDIndex);

        lecturerArray = Lecturers.get(lectIDIndex);

        unitArray = unitYear.get(unitIDIndex);





        if(unitArray==null){

            System.out.println("Please select a unit");

            System.exit(0);

        }



        roomID = Integer.parseInt(roomArray[0]);

        lecturer = Integer.parseInt(lecturerArray[0]);

        unit = Integer.parseInt(unitArray[0]);



        populateComboBoxes pcb = new populateComboBoxes();

        pcb.LabSessionInfo(roomID, lecturer, unit);



        myTimer.start();

        Timer timerDuration = new Timer(durationMilliSec, timerDurationActionEvent);

        timerDuration.start();





        }

    };



public void BluetoothScan(Timer myTimer) {

BluetoothDeviceDiscovery scan = new BluetoothDeviceDiscovery();

try {

    myTimer.stop();

    scan.main();

} catch (IOException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

} catch (InterruptedException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

}

myTimer.start();



};



  }
  

Заранее благодарю вас за любую помощь

Комментарии:

1. Возможно ли урезать код, который вы нам предоставляете? Сложно проанализировать все это и найти соответствующие биты.

2. Кроме того, форматирование кода является своего рода сбоем. Если вы можете потратить время на то, чтобы красиво отформатировать код в своих вопросах, это всегда очень ценится.

3. ах, извините, я сильно урезал это, поскольку думал, что все это необходимо, но, полагаю, я мог бы сократить это немного больше. Спасибо за отзыв

Ответ №1:

Вы можете объявить durationTimer на уровне класса и по-прежнему создавать его в ActionListener. Таким образом, это должно быть видно во всем классе. Просто убедитесь, что оно не равно null, прежде чем пытаться вызвать stop() для него.

Другой вариант — заставить его остановить себя:

 final ActionListener timerDurationActionEvent = new ActionListener(){
    public void actionPerformed(ActionEvent evt){
        //Stops myTimer, so that Bluetooth Stops scanning every 10mins. 
        myTimer.stop();
        ((Timer)evt.getSource()).stop();
    }
};
  

И другой (и, возможно, лучший) вариант — просто сделать его неповторяющимся:

     Timer timerDuration = new Timer(durationMilliSec, timerDurationActionEvent);
    timerDuration.setRepeats(false);
    timerDuration.start();
  

Этот последний вариант — правильный.

Ответ №2:

Поскольку вы запускаете сканирование синего зуба в потоке отправки событий, ваш второй таймер не сработает до завершения сканирования синего зуба.

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

Я предлагаю вам использовать SwingWorker.

Ответ №3:

Я не знаю, когда btnScanAction запускается (вероятно, часто, поскольку это ActionListener ), но при каждом вызове создается новый timerDuration . Вероятно, в итоге у вас будет несколько таймеров продолжительности, что (я думаю …) не то, что вы хотите.