使用ActionListeners的Java作用域

使用ActionListeners的Java作用域,java,swing,timer,Java,Swing,Timer,我有一个应用程序,需要在用户设置的持续时间内每隔10分钟扫描一次蓝牙设备 我有两个javax.swing.Timer(不是java.util.Timer)——一个控制每10分钟调用一次扫描方法,另一个控制在达到持续时间限制后停止第一个计时器(在停止扫描之前) durationTimer是在actionListener中创建和启动的 我的问题是,因为durationTimer是在ActionListener中创建的,所以我无法从另一个ActionListener停止计时器,因为程序无法“看到”变量

我有一个应用程序,需要在用户设置的持续时间内每隔10分钟扫描一次蓝牙设备

我有两个javax.swing.Timer(不是java.util.Timer)——一个控制每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();



};



  }
public类mainGui扩展JFrame
{
公共mainGui()
{
final ActionListener timerActionEvent=新ActionListener(){
已执行的公共无效操作(操作事件evt){
//在这里开始一项任务
计时器myTimer2=(计时器)evt.getSource();
//调用BluetoothScan方法
蓝牙扫描(myTimer2);
}
};
最终计时器计时;
最终计时器myTimer=新计时器(5000,timerActionEvent);
final ActionListener timerDurationActionEvent=新建ActionListener(){
已执行的公共无效操作(操作事件evt){
//停止myTimer,以便蓝牙每10分钟停止扫描一次。
myTimer.stop();
}
};
ActionListener btnScanAction=新建ActionListener(){
//用于从数据库读取数据的操作侦听器
已执行的公共无效操作(操作事件e){
int roomID=0;
int=0;
整数单位;
introomidex;
int-lectindex;
国际年指数;
国际统一指数;
字符串数组;
字符串数组;
字符串[]unitArray=null;
国际持续指数;
字符串持续时间;
持续时间;
//System.out.println(单位数组长度);
durationIndex=durCB.getSelectedIndex();
持续时间=项目持续时间[durationIndex];
durationInt=Integer.parseInt(持续时间);
//用户选择的持续时间转换为毫秒
持续时间毫秒=(持续时间*60000);
ArrayList unitYear=null;
//存储JComboBox选择的索引ID
roomIDIndex=roomCB.getSelectedIndex();
lectIDIndex=lectCB.getSelectedIndex();
UNITINDEX=unitCB.getSelectedIndex();
yearIDIndex=yearCB.getSelectedIndex();
开关(年号索引)
{
案例1:单位年=单位1;中断;
案例2:单位年=单位2;中断;
案例3:单位年=单位3;中断;
案例4:unitYear=UnitsMasters;中断;
}
//在索引位置获取数组内容
roomArray=rooms.get(roomIDIndex);
讲师阵列=讲师.get(lectIDIndex);
unitArray=unitYear.get(unitIDIndex);
if(unitArray==null){
System.out.println(“请选择一个单位”);
系统出口(0);
}
roomID=Integer.parseInt(roomArray[0]);
讲师=整数.parseInt(讲师数组[0]);
unit=Integer.parseInt(unitArray[0]);
PopulateComboBox pcb=新的PopulateComboBox();
pcb.LabSessionInfo(室友、讲师、单元);
myTimer.start();
Timer timerDuration=新计时器(持续毫秒,timerDurationActionEvent);
timerDuration.start();
}
};
公共无效蓝牙扫描(计时器myTimer){
BluetoothDeviceDiscovery扫描=新建BluetoothDeviceDiscovery();
试一试{
myTimer.stop();
scan.main();
}捕获(IOE异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}捕捉(中断异常e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
myTimer.start();
};
}

提前感谢您提供的任何帮助

您可以在类级别声明durationTimer,并且仍然在ActionListener中构造它。这样,它应该在整个类中都可见。在尝试调用stop()之前,请确保它不为null

另一种选择是让它自行停止:

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();

最后一种方法就是这样。

您可以在类级别声明durationTimer,并且仍然在ActionListener中构造它。这样,它应该在整个类中都可见。在尝试调用stop()之前,请确保它不为null

另一种选择是让它自行停止:

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();

这是最后一个方法。

因为您在事件调度线程上启动了蓝牙扫描,所以在蓝牙扫描完成之前,您的第二个计时器不会启动

您需要为蓝牙扫描启动一个新线程


我建议您使用SwingWorker。

因为您在事件调度线程上启动了蓝牙扫描,所以在蓝牙扫描完成之前,您的第二个计时器不会启动

您需要为蓝牙扫描启动一个新线程


我建议您使用SwingWorker。

我不知道何时触发
btnScanAction
(可能经常是因为它是
ActionListener
),但它会创建一个新的
timerDuration
每次调用时。您可能会得到多个持续时间计时器,这(我想…)不是您想要的。

我不知道何时触发
btnScanAction
(可能经常是因为它是
ActionListener
),但它会创建一个新的持续时间
timerDuration
在每次通话中。您可能会得到多个持续时间计时器,这(我猜…)不是您想要的。

您是否可以精简您提供给我们的代码?很难解析所有代码并找到相关的位。而且,代码格式有点混乱。如果您能花时间在您的qu中很好地格式化代码