Listview不能正确显示实时的可观察列表更改

时间:2019-04-21 22:41:44

标签: java listview javafx observable observablecollection

我的应用程序的一部分存在某些问题,该部分无法按我的要求正确运行,我有一个Java fx listview,就像一个日志,我正在尝试用它创建一个简单的日志。看一下代码,

我试图添加一个任务,该任务每秒钟使用“ writeLog”功能写入日志,并且可以正常工作(列表视图使用新字符串正确刷新)。第二个代码是相同的,但是没有Task,它不能像我想要的那样工作,在这种情况下,writeLog将被其他类调用。 从其他类调用writeLog(“ any string ..”)时,Observable列表将正确更改,文件(log)也将更改,但是listview不想显示添加到日志中的新String。

public class ControllerServer implements Initializable {

    @FXML
    public ListView myListView;

    private ObservableList<String> logList = FXCollections.observableArrayList();

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        try {
            fillLogList();
            MyTask task = new MyTask();
            Timer timer = new Timer(true);
            timer.scheduleAtFixedRate(task,4000,4000);
        } catch (IOException e) {
            e.printStackTrace();
        }

        if (logList!= null) {
            for (int i = 0; i < logList.size(); i++) {
                System.out.println(logList.get(i));
            }
         logList.addListener((javafx.beans.Observable observable)->{
             System.out.println("changed list");
         });
        }
        myListView.setItems(logList);
    }
    //METHODS
    public void fillLogList() throws IOException {
        BufferedReader reader = new BufferedReader(new FileReader("samplefile1.txt"));
        String line;
        while((line = reader.readLine())!=null) {
            logList.add(line);
        }
    }
    public void writeLog(String log) throws IOException {
        BufferedWriter writer = new BufferedWriter(new FileWriter("samplefile1.txt", true));
        writer.write(log);
        if(logList!=null){
            logList.add(log);
            System.out.println("i'm writing this log inside the file, log say : " + log);
        }else
        writer.newLine();
        writer.close();
    }

    class MyTask extends TimerTask {
        @Override
        public void run(){
            try {
                writeLog("Hello, i'm working inside this task, why?");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
public class ControllerServer implements Initializable {

    @FXML
    public ListView myListView;

    private ObservableList<String> logList = FXCollections.observableArrayList();

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        try {
            fillLogList();
        } catch (IOException e) {
            e.printStackTrace();
        }

        if (logList!= null) {
            for (int i = 0; i < logList.size(); i++) {
                System.out.println(logList.get(i));
            }
         logList.addListener((javafx.beans.Observable observable)->{
             System.out.println("changed list");
         });
        }
        myListView.setItems(logList);
    }
    //METHODS
    public void fillLogList() throws IOException {
        BufferedReader reader = new BufferedReader(new FileReader("samplefile1.txt"));
        String line;
        while((line = reader.readLine())!=null) {
            logList.add(line);
        }
    }
    public void writeLog(String log) throws IOException {
        BufferedWriter writer = new BufferedWriter(new FileWriter("samplefile1.txt", true));
        writer.write(log);
        if(logList!=null){
            logList.add(log);
            System.out.println("i'm writing this log inside the file, log say : " + log);
        }else
        writer.newLine();
        writer.close();
    }

}
public class Server extends Application {
    private static ServerLog serverLog = new ServerLog();
    private static ControllerServer  controllerServer = new ControllerServer();


    public static void main(String[] args) throws IOException {
        Runnable r = () -> {
            new File("users").mkdir();
            try {
                ServerSocket socket = new ServerSocket(8189);

                while(true) {
                    Socket s = socket.accept();
                    ServiceHandler client = new  ServiceHandler(s);
                }

            }catch(IOException e){e.printStackTrace();}
        };
        new Thread(r).start();
        controllerServer.writeLog("server starting..");
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("View/server.fxml"));
        primaryStage.setScene(new Scene(root, 800, 600));
        primaryStage.setTitle("Server Log");
        primaryStage.show();
    }

}

package server;

import server.Controller.ControllerServer;
import server.Model.*;

import java.io.*;
import java.net.Socket;

import static common.ServiceID.*;
import static common.ServiceID.FAILURE_RESPONSE;

public class ServiceHandler extends Thread{

    private static Object lock = new Object();
    private static ServerLog serverLog = new ServerLog();
    private static ControllerServer controllerServer = new ControllerServer();
    private Socket s;

    public ServiceHandler(Socket s){
        this.s = s;

        this.start();
    }

    public void run()
    {
        try
        {
            controllerServer.writeLog("client address "+s.getInetAddress());
            InputStream inputStream = s.getInputStream();
            int servId = inputStream.read();
            OutputStream outputStream = s.getOutputStream();
            Thread t;
            switch(servId) {
                case WRITE_EMAIL:
                    controllerServer.writeLog("Writing Email, id : " + WRITE_EMAIL);
                    outputStream.write(SUCCESS_RESPONSE);
                    t = new Thread(new EmailReceiver(s,lock, servId));
                    t.start();
                    break;

                case READ_ALL_EMAILS:
                    controllerServer.writeLog("Loading users list, id : " + READ_ALL_EMAILS);
                    outputStream.write(SUCCESS_RESPONSE);
                    t = new Thread(new EmailReader(s));
                    t.start();
                    break;

                case USER_LIST:
                    controllerServer.writeLog("Caricamento lista utenti, id : " + USER_LIST);
                    outputStream.write(SUCCESS_RESPONSE);
                    t = new Thread(new UserGetter(s));
                    t.start();
                    break;

                case LOGIN:
                    controllerServer.writeLog("Login, id " + LOGIN);
                    outputStream.write(SUCCESS_RESPONSE);
                    t = new Thread(new UserLogin(s));
                    t.start();
                    break;

                case DELETE_EMAIL:
                    controllerServer.writeLog("delete email, id " + DELETE_EMAIL);
                    outputStream.write(SUCCESS_RESPONSE);
                    t = new Thread(new EmailDelete(s));
                    t.start();
                    break;
                default:
                    controllerServer.writeLog("Error");
                    outputStream.write(FAILURE_RESPONSE);
                    break;

            }


        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }

}

1 个答案:

答案 0 :(得分:1)

问题在于您正在其他班级创建一个新的ControllerServer

从这些类中调用controllerServer.writeLog()时,实际上是在写与绑定到List上的ListView完全不同的ControllerServer


相反,您应该只有一个ServiceHandler并将对它的引用传递给需要它的任何其他类。

例如,您可以像这样更新public class ServiceHandler extends Thread { private static Object lock = new Object(); private static ServerLog serverLog = new ServerLog(); private Socket s; private ControllerServer controllerServer; // Do NOT instantiate it here! // Pass your single ControllerServer to the constructor public ServiceHandler (Socket socket, ControllerServer controllerServer) { this.s = socket; this.controllerServer = controllerServer; this.start(); } } 类:

controllerServer.writeLog()

现在,以后再调用ControllerServer时,将在正确的import pandas as pd import numpy as np from sklearn.pipeline import Pipeline from sklearn.base import BaseEstimator, TransformerMixin class Impute(BaseEstimator, TransformerMixin): def __init__(self, columns=None, value='mean'): """ columns: A list of columns to apply the imputation to. value: - "mean": Fills in missing values with mean of training data - number: Fills in values with that number - dictionary: Fills in values where dictionary keys are column names """ self.columns = columns self.value = value def fit(self, X, y=None): if self.columns is None: self.columns = X.columns if isinstance(self.value, str): if self.value == "mean": self.value = X[self.columns].mean() elif self.value == 'median': self.value = X[self.columns].median() return self def transform(self, X): X[self.columns] = X[self.columns].fillna(self.value) return X class Log(BaseEstimator, TransformerMixin): def __init__(self, columns=None, offset_value=0): """ offset_value: a value to specify to handle invalid outputs such as log(0) or log(negative values) """ self.columns = columns self.offset_value = offset_value def fit(self, X, y=None): return self def transform(self, X): X_new = X.copy() X_new[self.columns] = np.log(X_new[self.columns] + self.offset_value) return X_new ########################### temp = pd.DataFrame([[590,3,None, "2018-01-01"],[0,2,3, "2018-01-01"], [590,2,4, "2019-01-01"], [None ,None,4, "2018-01-01"], [850 ,None,4, "2018-01-01"]], columns=["credit_score", "n_cats", "premium", "fix_date"]) print(temp) impute = Impute(columns=["credit_score", "n_cats", "premium"], value="mean") impute.fit(temp) temp = impute.transform(temp) log = Log(columns=["credit_score", "n_cats", "premium"], offset_value=1) log.fit(temp) temp = log.transform(temp) temp ########################### temp = pd.DataFrame([[590,3,None, "2018-01-01"],[0,2,3, "2018-01-01"], [590,2,4, "2019-01-01"], [None ,None,4, "2018-01-01"], [850 ,None,4, "2018-01-01"]], columns=["credit_score", "n_cats", "premium", "fix_date"]) print(temp) impute = Impute(columns=["credit_score", "n_cats", "premium"], value="mean") log = Log(columns=["credit_score", "n_cats", "premium"], offset_value=1) steps = [("impute", impute), ("log", log) ] pipe = Pipeline(steps) pipe.fit(temp) pipe.transform(temp) temp 实例上进行。