簡體   English   中英

Java-無法訪問另一個類中的arraylist

[英]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 他們彼此之間一無所知,您的RMIsensorClientController具有他們自己的ModelManager實例,並且您在任何地方都沒有可以共享任何數據的代碼。

您需要以某種方式使要顯示在GUI中的數據可訪問。

一種解決方案是為此使用網絡接口。 創建兩個不同的ModelManager ,一個打開並偵聽ServerSocket ,另一個在getLatestTemperatureData()中使用Socket連接到另一個。

RMIsensorClient使用前者,而在GUIController使用后者。

Java研究網絡。

這是一個非常粗糙的解決方案,但是有很多很棒的教程可以在多個Java應用程序之間建立網絡並共享數據。

您尚未包括TemperatureList實現,但是如果您說它是ArrayList則可能是您未正確同步跨線程的訪問 必須正確同步跨線程工作,否則您將陷入某種未定義的行為,例如未傳播的更改或數據結構崩潰。

您可能會考慮在java.util.collect.concurrent中有許多線程安全的集合,否則,您需要確保在使用此列表的任何地方都使用synchronized塊或方法。

我發現的最明顯的問題(可能不是全部)是您的數組列表特定於方法。 它不是靜態的。 意味着只能通過其起源的方法來訪問它。最簡單的解決方法是在創建數組列表時向其添加靜態修飾符,然后在方法之外創建它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM