[英]Java - Can't access arraylist in another class
我有一個可運行的類“ TemperatureSensor”,該類定期將新的隨機浮點值添加到數組列表TemperatureList作為對象Temperature。 然后,將陣列中最后添加的對象(索引0)從RMI客戶端發送到RMI服務器-這不會出現問題。
但是,當我單擊GUI上的一個按鈕以顯示該對象數組的大小時,總是得到0。如果我從RMI客戶端類中打印出數組的大小,則顯示正確的大小。
我的問題是,如何正確地從多個類訪問同一數組?
這是UML:
import java.text.DecimalFormat;
import java.util.Random;
public class TemperatureSensor implements Runnable
{
private int waitingTime;
private Model model;
public TemperatureSensor(Model model, int waitingTime)
{
this.model = model;
this.waitingTime = waitingTime;
}
@Override
public void run()
{
float temperature = 25.0f;
while(true)
{
temperature = measureTemperature(temperature);
model.addTemperatureData(temperature);
System.out.println("Sending: " + temperature);
waiting();
}
}
private float measureTemperature(float temperature)
{
Random rand = new Random();
float minTempFloat = 0.1f;
float maxTempFloat = 0.2f;
int incrementSwitch = rand.nextInt(3-0) + 0;
if (incrementSwitch == 0)
{
temperature += minTempFloat + rand.nextFloat() * (maxTempFloat - minTempFloat);
}
else if(incrementSwitch == 1)
{
//Do nothing
}
else if (incrementSwitch == 2)
{
temperature -= minTempFloat + rand.nextFloat() * (maxTempFloat -
minTempFloat);
}
return temperature;
}
private void waiting()
{
try
{
Thread.sleep(waitingTime);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
模型:
public interface Model
{
public void addTemperatureData(float value);
public Temperature getLatestTemperatureData();
public int getTempListSize();
}
模型管理器:
public class ModelManager implements Model
{
private TemperatureList temperatureList;
public ModelManager()
{
temperatureList = new TemperatureList();
}
@Override
public void addTemperatureData(float value)
{
Temperature temperature = new Temperature(value);
//this.temperatureList.clearTemperatureDataList();
this.temperatureList.addTemperatureDataToList(temperature);
}
@Override
public Temperature getLatestTemperatureData()
{
return temperatureList.getLatestTemperatureDataFromList();
}
@Override
public int getTempListSize()
{
return temperatureList.size();
}
}
RMIsensorClient:
import java.rmi.Naming;
import java.rmi.RemoteException;
public class RMIsensorClient
{
private RMIserverInterface serverInterface;
private static Model model = new ModelManager();
public static void main(String[] args) throws RemoteException, InterruptedException
{
TemperatureSensor tempSensor = new TemperatureSensor(model, 5000);
Thread tempThread = new Thread(tempSensor, "TempSensor");
tempThread.start();
RMIsensorClient sensorClient = new RMIsensorClient();
}
public RMIsensorClient() throws RemoteException
{
super();
try
{
serverInterface = (RMIserverInterface) Naming.lookup("rmi://localhost:1099/rmiServer");
while(true)
{
serverInterface.getTemperature(model.getLatestTemperatureData());
System.out.println(model.getTempListSize());
Thread.sleep(5000);
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
控制器:
public class Controller
{
private static Model model;
public Controller ()
{
this.model = new ModelManager();
}
public int getNumberOfListElements()
{
return model.getTempListSize();
}
}
界面:
public class GUItemperatureController implements Initializable
{
private Controller controller = new Controller();
@FXML
private Label tlTemperature;
@FXML
private Pane mainPane;
@FXML
private TextField tfTemperature;
@FXML
private Button btnUpdate;
@Override
public void initialize(URL arg0, ResourceBundle arg1)
{
tfTemperature.setEditable(false);
}
@FXML
void showArraySize(ActionEvent event)
{
tfTemperature.setText(Integer.toString(controller.getNumberOfListElements()));
}
}
溫度列表:
import java.io.Serializable;
import java.util.ArrayList;
public class TemperatureList implements Serializable
{
private ArrayList<Temperature> temperatureList;
public TemperatureList()
{
this.temperatureList = new ArrayList<>();
}
public void addTemperatureDataToList(Temperature temperature)
{
temperatureList.add(0,temperature);
}
public Temperature getLatestTemperatureDataFromList()
{
return this.temperatureList.get(0);
}
public void clearTemperatureDataList()
{
temperatureList.clear();
}
public int size()
{
return temperatureList.size();
}
}
這是我啟動GUI的位置:
import java.rmi.RemoteException;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class userMain extends Application
{
public FXMLLoader loader;
public static void main(String[] args)
{
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception
{
loader = new FXMLLoader();
loader.setLocation(getClass().getResource("FXML/FXMLtemperature.fxml"));
loader.setController(new GUItemperatureController());
Parent root = loader.load();
Scene scene = new Scene(root);
primaryStage.setTitle("GEMS - Test");
primaryStage.setScene(scene);
primaryStage.show();
}
}
您的問題與課程無關。
您運行兩個單獨的應用程序。 一種運行RMIsensorClient
,另一種運行GUI
。 他們彼此之間一無所知,您的RMIsensorClient
和Controller
具有他們自己的ModelManager
實例,並且您在任何地方都沒有可以共享任何數據的代碼。
您需要以某種方式使要顯示在GUI中的數據可訪問。
一種解決方案是為此使用網絡接口。 創建兩個不同的ModelManager
,一個打開並偵聽ServerSocket ,另一個在getLatestTemperatureData()
中使用Socket連接到另一個。
在RMIsensorClient
使用前者,而在GUI
的Controller
使用后者。
Java研究網絡。
這是一個非常粗糙的解決方案,但是有很多很棒的教程可以在多個Java應用程序之間建立網絡並共享數據。
您尚未包括TemperatureList
實現,但是如果您說它是ArrayList
則可能是您未正確同步跨線程的訪問 。 必須正確同步跨線程工作,否則您將陷入某種未定義的行為,例如未傳播的更改或數據結構崩潰。
您可能會考慮在java.util.collect.concurrent
中有許多線程安全的集合,否則,您需要確保在使用此列表的任何地方都使用synchronized
塊或方法。
我發現的最明顯的問題(可能不是全部)是您的數組列表特定於方法。 它不是靜態的。 意味着只能通過其起源的方法來訪問它。最簡單的解決方法是在創建數組列表時向其添加靜態修飾符,然后在方法之外創建它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.