Java - 无法访问另一个类中的arraylist

时间:2018-03-27 21:32:28

标签: java arrays model-view-controller

我有一个可运行的类“TemperatureSensor”,它定期将新的随机浮点值添加到数组列表TemperatureList作为对象温度。然后,数组中最后添加的对象(索引0)从RMI客户端发送到RMI服务器 - 这没有问题。

然而,当我单击GUI上的一个按钮来显示此对象数组的大小时,我总是得到0.如果我从RMI客户端类打印出数组的大小,它会显示正确的大小。

我的问题是,如何正确地从多个类访问相同的数组?

以下是UML:

enter image description here温度传感器节温

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

的ModelManager:

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

的Controler:

public class Controller
{
    private static Model model;

    public Controller ()
    {   
        this.model = new ModelManager();
    }

    public int getNumberOfListElements()
    {
        return model.getTempListSize();
    }
}

GUI:

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

TemperatureList:

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

3 个答案:

答案 0 :(得分:1)

您的问题与课程无关。

您运行两个单独的应用程序。一个运行RMIsensorClient,一个运行GUI。他们对彼此一无所知,您的RMIsensorClientController拥有自己独立的ModelManager个实例,并且您无法在任何地方共享任何数据。

您需要以某种方式使您想要在GUI中显示的数据可用。

一种解决方案可能是使用网络接口。创建两个不同的ModelManager,一个打开并收听ServerSocket,另一个使用getLatestTemperatureData()中的Socket连接到另一个。{/ p>

在您的RMIsensorClient中使用前者,在GUI Controller中使用后者。

用Java研究网络。

这是一个非常粗略的解决方案,但是有很多很棒的教程可以在多个Java应用程序之间进行网络连接和共享数据。

答案 1 :(得分:0)

您尚未加入TemperatureList实施,但如果您说它是ArrayList,那么您可能不是properly synchronizing access across threads。您必须正确地同步跨线程工作,否则您将遇到某种未定义的行为,例如更改未传播或数据结构崩溃。

您可能会考虑java.util.collect.concurrent中有许多线程安全的集合,否则您需要确保在使用此列表的任何位置使用synchronized块或方法。< / p>

答案 2 :(得分:-1)

我发现的最明显的问题(可能不是全部)是您的数组列表是特定于方法的。它不是静止的。这意味着它只能通过它所源自的方法来访问。最简单的解决方法是在创建数组列表时为其添加静态修饰符,并在方法之外创建它。