简体   繁体   English

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

[英]Java - Can't access arraylist in another class

I have a runnable class "TemperatureSensor" which is periodically adding a new randomized floating point value to an array list TemperatureList as an object Temperature. 我有一个可运行的类“ TemperatureSensor”,该类定期将新的随机浮点值添加到数组列表TemperatureList作为对象Temperature。 The last added object in the array (index 0) is then sent from RMI client to RMI server - this happens without problems. 然后,将阵列中最后添加的对象(索引0)从RMI客户端发送到RMI服务器-这不会出现问题。

However, when I click a button on GUI to display the size of this object array, I always get a 0. If I print out the size of the array from RMI client class, it shows a correct size. 但是,当我单击GUI上的一个按钮以显示该对象数组的大小时,总是得到0。如果我从RMI客户端类中打印出数组的大小,则显示正确的大小。

My question is, how do I access the same array from multiple classes correctly? 我的问题是,如何正确地从多个类访问同一数组?

Here is the UML: 这是UML:

在此处输入图片说明 TemperatureSensor : 温度传感器

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

Model: 模型:

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

Here is where I launch the GUI: 这是我启动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();                
}
}

Your problem is not about classes. 您的问题与课程无关。

You run two separate applications. 您运行两个单独的应用程序。 One runs your RMIsensorClient and one runs your GUI . 一种运行RMIsensorClient ,另一种运行GUI They know nothing about each other, your RMIsensorClient and your Controller have their own separate instances of ModelManager and you have no code anywhere that would share any data between them. 他们彼此之间一无所知,您的RMIsensorClientController具有他们自己的ModelManager实例,并且您在任何地方都没有可以共享任何数据的代码。

You need to make the data you want to show in your GUI accessible somehow. 您需要以某种方式使要显示在GUI中的数据可访问。

One solution could be to use a network interface for that. 一种解决方案是为此使用网络接口。 Create two different ModelManager s, one that opens and listens to a ServerSocket , and one that uses a Socket in getLatestTemperatureData() to connect to the other one. 创建两个不同的ModelManager ,一个打开并侦听ServerSocket ,另一个在getLatestTemperatureData()中使用Socket连接到另一个。

Use the former in your RMIsensorClient and the latter in your GUI 's Controller . RMIsensorClient使用前者,而在GUIController使用后者。

Research networking in Java. Java研究网络。

This is a very crude solution, but there are plenty of great tutorials for networking and sharing data between multiple Java applications. 这是一个非常粗糙的解决方案,但是有很多很棒的教程可以在多个Java应用程序之间建立网络并共享数据。

You haven't included your TemperatureList implementation, but if as you say it's an ArrayList it's likely you're not properly synchronizing access across threads . 您尚未包括TemperatureList实现,但是如果您说它是ArrayList则可能是您未正确同步跨线程的访问 It's imperative that you properly synchronize cross-thread work otherwise you'll wind up with some sort of undefined behavior, such as changes not propagating or data structures winding up broken. 必须正确同步跨线程工作,否则您将陷入某种未定义的行为,例如未传播的更改或数据结构崩溃。

There are a number of thread-safe collections in java.util.collect.concurrent that you might consider, otherwise you'll need to ensure you use synchronized blocks or methods anywhere you're working with this list. 您可能会考虑在java.util.collect.concurrent中有许多线程安全的集合,否则,您需要确保在使用此列表的任何地方都使用synchronized块或方法。

The most obvious problem that I found(and this might not be all) is that your array list is method specific. 我发现的最明显的问题(可能不是全部)是您的数组列表特定于方法。 it is not static. 它不是静态的。 Meaning that it can only be accessed by the method it originates in. the easiest fix for this is to add a static modifier to your array list when it is created and create it outside of the methods. 意味着只能通过其起源的方法来访问它。最简单的解决方法是在创建数组列表时向其添加静态修饰符,然后在方法之外创建它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM