我从无人机那里得到电池值。我能够在JLabel上显示新的电池值。但是,当我试图将这些电池值存储到int数组中时,它只是存储数组上的第一个电池值。随后的数组值将只填充第一个电池值。
我展示了一个输出,这样您就可以了解正在发生的事情了。第一个值来自无人驾驶飞机,而第二个值表示数组索引。输出清楚地显示,由于未知的原因,数组不能接受新的数据。
P/S:我不知道什么是最好的数组大小,因为我每秒钟都会从无人机那里得到值。所以我已经声明了一个大小为9999999的int数组。我怎样才能设置一个阵列的最大大小,以满足从无人机获得连续电池值的需要?这些值稍后将用于绘制图形。
我的代码:
public class arDroneFrame extends javax.swing.JFrame implements Runnable, DroneStatusChangeListener, NavDataListener {
private String text; // string for speech
private static final long CONNECT_TIMEOUT = 10000;
public ARDrone drone;
public NavData data;
public Timer timer = new Timer();
public int batteryGraphic=0;
public int [] arrayBatt = new int[9999999];
public arDroneFrame(String text) {
this.text=text;
}
public arDroneFrame() {
initComponents();
initDrone();
}
private void initDrone() {
try {
drone = new ARDrone();
data = new NavData();
} catch (UnknownHostException ex) {
return;
}
videoDrone.setDrone(drone);
drone.addNavDataListener(this);
}
public void navDataReceived(NavData nd) {
getNavData(nd);
int battery = nd.getBattery();
cmdListOK.jlblBatteryLevelValue.setText(battery + " %");
//JLabel can get updated & always display new battery values
}
public void getNavData(NavData nd){
for(int i=0;i<arrayBatt.length;i++){
batteryGraphic= nd.getBattery();
arrayBatt[i] = batteryGraphic;
System.err.println("This is stored battery values : " + arrayBatt[i] + " " + i + "\n");
}
}
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
String text = "Welcome!";
arDroneFrame freeTTS = new arDroneFrame(text);
freeTTS.speak();
new arDroneFrame().setVisible(true);
}
});
}结果:
This is stored battery values : 39 0
This is stored battery values : 39 1
This is stored battery values : 39 2
This is stored battery values : 39 3
This is stored battery values : 39 4
This is stored battery values : 39 5发布于 2015-07-09 17:35:53
问题在于这个方法:
public void getNavData(NavData nd){
for (int batteryValue : arrayBatt){
arrayBatt[i] = nd.getBattery();
System.err.println("This is stored battery values : " + arrayBatt[i] + " " + i + "\n");
}
}通过传递一个NavData实例来调用该方法。这意味着,无论nd为nd.getBattery()包含什么值,都将分配给数组中的每个索引,因为循环在电池数组上进行交互。
您应该做的是将循环移到getNavData(NavData nd)方法之外,并为每个调用传递一个新的NavData实例。当您将其与下面的ArrayList建议相结合时,您应该有一个不同电池值的动态数组。
边解
声明这个数组的方式是,非常可怕的。你应该只使用你需要的空间,而不是更多。我知道你不知道实际需要多大的尺寸,但不要太过分。
你应该用更小的东西初始化你的数组;
public int [] arrayBatt = new int[10000];附带说明:通常不建议将您的班级成员作为公共成员。您应该使它们成为私有的,并分别创建getter/setter方法来检索和修改数据。
然后,有一个检查数组是否已满的方法。如果数组已满,则通过n/2增加数组大小,其中n是数组的初始大小。
这种方法的缺点是,随着数组变得更大,您将花费大量时间将旧数组复制到新数组,这是非常不可取的。
一个更好的解决方案
就是使用内置的ArrayList库,然后将项添加到列表中,让Java来做繁重的工作。
ArrayList<Integer> batteryArray = new ArrayList <Integer>();只需调用以下命令即可将项添加到列表中:
batteryArray.add(item);这一解决办法的好处是:
在您的循环打印电池值,您可以使它更干净,通过实现一个for-每个循环。
System.err打印电池的对话框?这不是System.err应该用于的,也不是违反最小惊讶原则的
getNavData(NavData nd){ for (int batteryValue : arrayBatt){ arrayBatti = nd.getBattery();System.err.println(“这是存储的电池值:”+ arrayBatti +“+i+”);}
}发布于 2015-07-09 18:20:58
我认为无人机的硬件引发了某种事件。您的循环运行太快,可能是每秒数千次,因此没有时间进行任何电池的更改,并且nd.getBattery()返回相同的值。
似乎这就是为什么这些值被重复的原因。
另一方面,我怀疑只有当硬件检测到更改时才调用navDataReceived,这就是它显示新值的原因。当调用getNavData时,您将运行一个紧循环,该循环锁定执行并阻止应用程序在执行循环时接收此事件。
只有在收到有关更改的通知时,才应存储值。
我认为getNavData的实现是根本错误的。
在这种情况下,您的1000万int数组是无用的。
我不知道您的应用程序如何与无人机的硬件交互,但是接口名称DroneStatusChangeListener和NavDataListener建议您在发生更改时收到一些通知。
https://stackoverflow.com/questions/31324063
复制相似问题