我有一个应用程序,需要在用户设置的持续时间内每10分钟扫描一次蓝牙设备。
我有两个javax.swing.Timer(不是java.util.Timer) - 一个控制每10分钟调用一次扫描方法,另一个是在持续时间限制被命中后停止第一个计时器(停止扫描) 。
在actionListener中创建并启动durationTimer。
我的问题是因为在ActionListener中创建了durationTimer,我无法从另一个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();
};
}
提前感谢您的任何帮助
答案 0 :(得分:2)
您可以在类级别声明durationTimer,并仍然在ActionListener中构造它。这种方式应该在整个班级都可见。在尝试调用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();
最后一个是要走的路。
答案 1 :(得分:2)
由于你在Event Dispatch线程上开始蓝牙扫描,你的第二个定时器在蓝牙扫描完成之前不会开启。
您需要为蓝牙扫描启动一个新线程。
我建议您使用SwingWorker。
答案 2 :(得分:1)
我不知道何时触发btnScanAction
(可能经常是因为它是ActionListener
),但它会创建一个新的
每次通话timerDuration
。你最终可能会有多个持续时间计时器,我想这不是你想要的。