JavaFX ListView IndexOutOfBoundsException - PullRequest
0 голосов
/ 14 мая 2018

Я использую JFXListView для получения списка служб с удаленного сервера с использованием rmi. Когда я обновляю JFXListView, я просто вызываю метод getServices, проблема заключается в том, что после активации метода обновления он запускается мгновенно, а не принимает частоту обновления(время между каждым обновлением) от JFXSlider и после нескольких обновлений приложение блокируется, и я получаю

Exception in thread "JavaFX Application Thread" java.lang.IndexOutOfBoundsException: Index: 8, Size: 0
    at java.util.ArrayList.rangeCheck(ArrayList.java:657)
    at java.util.ArrayList.get(ArrayList.java:433)
    at javafxcyberwind.UtilisateurController.getServices(UtilisateurController.java:172)
    at javafxcyberwind.UtilisateurController.lambda$Refresh$14(UtilisateurController.java:420)
    at com.sun.scenario.animation.shared.TimelineClipCore.visitKeyFrame(TimelineClipCore.java:239)
    at com.sun.scenario.animation.shared.TimelineClipCore.playTo(TimelineClipCore.java:180)
    at javafx.animation.Timeline.impl_playTo(Timeline.java:176)
    at javafx.animation.AnimationAccessorImpl.playTo(AnimationAccessorImpl.java:39)
    at com.sun.scenario.animation.shared.InfiniteClipEnvelope.timePulse(InfiniteClipEnvelope.java:110)
    at javafx.animation.Animation.impl_timePulse(Animation.java:1102)
    at javafx.animation.Animation$1.lambda$timePulse$25(Animation.java:186)
    at java.security.AccessController.doPrivileged(Native Method)
    at javafx.animation.Animation$1.timePulse(Animation.java:185)
    at com.sun.scenario.animation.AbstractMasterTimer.timePulseImpl(AbstractMasterTimer.java:344)
    at com.sun.scenario.animation.AbstractMasterTimer$MainLoop.run(AbstractMasterTimer.java:267)
    at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:514)
    at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:498)
    at com.sun.javafx.tk.quantum.QuantumToolkit.pulseFromQueue(QuantumToolkit.java:491)
    at com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$403(QuantumToolkit.java:319)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$147(WinApplication.java:177)
    at java.lang.Thread.run(Thread.java:748)

, я думаю, это связано с тем, что метод getServices сильно заряжен.Как я могу максимально упростить этот метод?

@FXML
private JFXListView li_se;

@FXML
private JFXSlider refresh;    

@FXML
public void getServices(ActionEvent e) {
    try {
        li_se.getItems().clear();
        for (int i = 0; i < R.ListeService().size(); i++) {
            JFXButton b = new JFXButton("" + R.ListeService().get(i));//line that is pointed by the IndexOutOfBoundsException
            b.setStyle("-fx-rippler-fill:black;-fx-text-fill:black;-fx-font-size:16px;-fx-background-color:orange;-fx-background-radius:5px;");
            b.setOnAction((ActionEvent event) -> {
                try {
                    VBox vBox = new VBox(10);
                    JFXListView li_par = new JFXListView();
                    JFXTextField[] fields = new JFXTextField[22];
                    TextFieldEntier[] fEntiers = new TextFieldEntier[22];
                    TextFieldReel[] fRéels = new TextFieldReel[22];
                    ChoiceBox<String> choiceBox = new ChoiceBox<>();
                    choiceBox.getStylesheets().add(getClass().getResource("/choise-box.css").toExternalForm());
                    choiceBox.getItems().addAll("true", "false");
                    ArrayList<Object> tab = new ArrayList<>();
                    JFXButton folder = new JFXButton("Ouvrir le répertoire");
                    folder.setDisable(true);
                    ObservableList<String> ListParam = FXCollections.observableArrayList(R.paramService(b.getText()));
                    JFXDialogLayout content = new JFXDialogLayout();
                    content.setHeading(new Text(b.getText()));
                    content.setBody(vBox);
                    JFXDialog dialog = new JFXDialog(st_dl, content, JFXDialog.DialogTransition.CENTER);
                    k = 0;
                    ListParam.stream().map((st) -> {
                        if (st.equals("double")) {
                            fRéels[k] = new TextFieldReel();
                            fRéels[k].setPadding(new Insets(11));
                            Label lb = new Label("Argument ( Réel ) : ");
                            lb.setPadding(new Insets(7));
                            lb.setStyle("-fx-min-Width:178;-fx-text-fill:white;-fx-background-color:orange;-fx-background-radius:5px;");
                            HBox hb = new HBox(10);
                            hb.getChildren().add(lb);
                            hb.getChildren().add(fRéels[k]);
                            li_par.getItems().add(hb);
                        }
                        return st;
                    }).map((st) -> {
                        if (st.equals("java.lang.String")) {
                            fields[k] = new JFXTextField();
                            fields[k].setMinHeight(35);
                            fields[k].setMinWidth(157);
                            Label lb = new Label("Argument ( Texte ) : ");
                            lb.setMinWidth(178);
                            lb.setPadding(new Insets(7));
                            lb.setStyle("-fx-text-fill:white;-fx-background-color:orange;-fx-background-radius:5px;");
                            HBox hb = new HBox(10);
                            hb.getChildren().add(lb);
                            hb.getChildren().add(fRéels[k]);
                            li_par.getItems().add(hb);
                        }
                        return st;
                    }).map((st) -> {
                        if (st.equals("int")) {
                            fEntiers[k] = new TextFieldEntier();
                            fEntiers[k].setPadding(new Insets(11));
                            Label lb = new Label("Argument ( Entier ) : ");
                            lb.setPadding(new Insets(7));
                            lb.setStyle("-fx-min-Width:178;-fx-text-fill:white;-fx-background-color:orange;-fx-background-radius:5px;");
                            HBox hb = new HBox(10);
                            hb.getChildren().add(lb);
                            hb.getChildren().add(fEntiers[k]);
                            li_par.getItems().add(hb);
                        }
                        return st;
                    }).map((st) -> {
                        if (st.equals("boolean")) {
                            Label lb = new Label("Argument ( " + st + " ) : ");
                            lb.setMinWidth(178);
                            lb.setPadding(new Insets(7));
                            lb.setStyle("-fx-text-fill:white;-fx-background-color:orange;-fx-background-radius:5px;");
                            HBox hb = new HBox(10);
                            hb.getChildren().add(lb);
                            hb.getChildren().add(choiceBox);
                            li_par.getItems().add(hb);
                        }
                        return st;
                    }).map((st) -> {
                        if (st.equals("java.io.File")) {
                            fields[k] = new JFXTextField();
                            fields[k].setMinHeight(35);
                            fields[k].setMinWidth(157);
                            Label lb = new Label("Argument ( Fichier ) : ");
                            lb.setMinWidth(178);
                            lb.setPadding(new Insets(7));
                            lb.setStyle("-fx-text-fill:white;-fx-background-color:orange;-fx-background-radius:5px;");
                            HBox hb = new HBox(10);
                            hb.getChildren().add(lb);
                            hb.getChildren().add(fields[k]);
                            li_par.getItems().add(hb);
                            int x = k;
                            fields[k].addEventHandler(MouseEvent.MOUSE_CLICKED, (javafx.scene.input.MouseEvent e1) -> {
                                FileChooser fc = new FileChooser();
                                selectedFile = fc.showOpenDialog(null);
                                if (selectedFile != null) {
                                    fields[x].setText(selectedFile.getAbsolutePath());
                                }
                            });
                        }
                        return st;
                    }).forEachOrdered((_item) -> {
                        k++;
                    });
                    JFXButton exe = new JFXButton("Exécuter");
                    WeatherIconView weatherIcon = new WeatherIconView(WeatherIcon.CLOUD);
                    weatherIcon.setSize("30");
                    weatherIcon.setFill(Color.DODGERBLUE);
                    exe.setGraphic(weatherIcon);
                    exe.setStyle("-fx-text-fill:DODGERBLUE;-fx-background-color:white;-fx-background-radius:5px;");
                    exe.setPadding(new Insets(10));
                    JFXTextField res = new JFXTextField();
                    res.setMinWidth(150);
                    Label re = new Label("Résultat");
                    HBox hb = new HBox(10);
                    hb.getChildren().add(re);
                    hb.getChildren().add(res);
                    hb.setAlignment(Pos.CENTER_RIGHT);
                    hb.getChildren().add(folder);
                    li_par.setMaxHeight(180);
                    li_par.setMinWidth(384);
                    vBox.getChildren().add(li_par);
                    vBox.setAlignment(Pos.CENTER_RIGHT);
                    vBox.getChildren().add(exe);
                    vBox.getChildren().add(hb);
                    exe.setOnAction((ActionEvent e2) -> {
                        tab.clear();
                        try {
                            int k1 = 0;
                            for (String st : ListParam) {
                                if (st.equals("int")) {
                                    tab.add(Integer.valueOf(fEntiers[k1].getText()));
                                }
                                if (st.equals("double")) {
                                    tab.add(Double.valueOf(fRéels[k1].getText()));
                                }
                                if (st.equals("boolean")) {
                                    tab.add(Boolean.valueOf(choiceBox.getValue()));
                                }
                                if (st.equals("java.lang.String")) {
                                    tab.add(fields[k1].getText());
                                }
                                if (st.equals("java.io.File")) {
                                    Fichier f = new Fichier(selectedFile.getName());
                                    tab.add(f);
                                    p1 = (int) ((Math.random() * (9000 - 5000)) + 5000);
                                    R.uploadToCloud(p1, selectedFile.getName());
                                    Socket s = new Socket(ip.IPserveur(), p1);
                                    ObjectOutputStream out;
                                    FileInputStream inf = new FileInputStream(new File(selectedFile.getAbsolutePath()));
                                    out = new ObjectOutputStream(s.getOutputStream());
                                    byte buf[] = new byte[1024];
                                    int n;
                                    while ((n = inf.read(buf)) != -1) {
                                        out.write(buf, 0, n);
                                    }
                                    out.close();
                                }
                                k1++;
                            }
                            if (R.retourService(b.getText()).equals("int") || R.retourService(b.getText()).equals("double") || R.retourService(b.getText()).equals("boolean") || R.retourService(b.getText()).equals("class java.lang.String")) {
                                R.envoieDemande(b.getText(), "", 0, tab.toArray());
                                res.setText("" + R.getResult());
                            }
                            if (R.retourService(b.getText()).equals("class java.io.File")) {
                                p1 = (int) ((Math.random() * (9000 - 5000)) + 5000);
                                LocateRegistry.createRegistry(p1);
                                Utilisateur_MethodsPAIRIMPL U = new Utilisateur_MethodsPAIRIMPL();
                                Naming.bind("rmi://" + InetAddress.getLocalHost().getHostAddress() + ":" + p1 + "/" + R.getEmail(), U);
                                R.envoieDemande(b.getText(), InetAddress.getLocalHost().getHostAddress(), p1, tab.toArray());
                                res.setText("C:/Utilisateur/" + R.getResfile());
                                folder.setDisable(false);
                            }
                        } catch (RemoteException | InvocationTargetException ex) {
                            Alert alert = new Alert(Alert.AlertType.ERROR);
                            alert.setTitle("Erreur");
                            alert.setHeaderText("Erreur");
                            alert.setContentText("Veuillez choisir une option");
                            ButtonType btn_annuler = new ButtonType("Annuler");
                            ButtonType btn_réessayer = new ButtonType("Réessayer");
                            alert.setGraphic(new ImageView("icon/erreur.png"));
                            alert.getButtonTypes().setAll(btn_réessayer, btn_annuler);
                            StringWriter sw = new StringWriter();
                            PrintWriter pw = new PrintWriter(sw);
                            ex.printStackTrace(pw);
                            TextArea area = new TextArea(sw.toString());
                            alert.getDialogPane().setExpandableContent(area);
                            Stage stage = (Stage) alert.getDialogPane().getScene().getWindow();
                            stage.getIcons().add(new Image("icon/erreur.png"));
                            Optional<ButtonType> res1 = alert.showAndWait();
                            if (res1.get() == btn_réessayer) {
                                alert.close();
                            }
                            if (res1.get() == btn_annuler) {
                                dialog.close();
                                alert.close();
                            }
                            //Logger.getLogger(UtilisateurController.class.getName()).log(Level.SEVERE, null, ex);
                        } catch (IOException | AlreadyBoundException ex) {
                            Logger.getLogger(UtilisateurController.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    });
                    JFXButton button = new JFXButton("Terminer " + b.getText());
                    button.setOnAction((ActionEvent evt) -> {
                        dialog.close();
                    });
                    content.setActions(button);
                    dialog.setOverlayClose(false);
                    dialog.show();
                    dialog.setOnDialogOpened((evt) -> {
                        t = true;
                        property.set(1);
                        bp.set(true);
                        pn_li.setDisable(true);
                        pn_us.setDisable(true);
                    });
                    dialog.setOnDialogClosed((evt) -> {
                        pn_li.setDisable(false);
                        pn_us.setDisable(false);
                        bp.set(false);
                        property.set(0);
                    });
                    folder.setOnAction((ActionEvent evt) -> {
                        try {
                            Desktop.getDesktop().open(new File(urep));
                        } catch (IOException ex) {
                            Logger.getLogger(UtilisateurController.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    });
                } catch (RemoteException ex) {
                    Logger.getLogger(UtilisateurController.class.getName()).log(Level.SEVERE, null, ex);
                }
            });
            li_se.getItems().add(b);
        }
        if (!li_se.isExpanded()) {
            li_se.setExpanded(true);
            li_se.depthProperty().set(1);
        } else {
            /*li_se.setExpanded(false);
            li_se.depthProperty().set(0);*/
        }
        lb_re.setDisable(false);
        refresh.setDisable(false);
        //bp.bind(property.isEqualTo(1));
    } catch (RemoteException ex) {
        Logger.getLogger(UtilisateurController.class.getName()).log(Level.SEVERE, null, ex);
    }
}

Остальной код:

package javafxcyberwind;

import com.jfoenix.controls.JFXListView;
import com.jfoenix.controls.JFXSlider;
import java.io.File;
import java.net.ServerSocket;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.beans.binding.Bindings;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableNumberValue;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.effect.BoxBlur;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.paint.CycleMethod;
import javafx.scene.paint.LinearGradient;
import javafx.scene.paint.Stop;
import javafx.scene.shape.Rectangle;
import javafx.util.Duration;

/**
 * FXML Controller class
 *
 * @author Sami
 */
public class UtilisateurController implements Initializable, ControlledScreen, ChangeListener {

    ScreensController myController;

    @FXML
    private JFXListView li_se;

    @FXML
    private StackPane st_dl, glass;

    @FXML
    private AnchorPane pn_us, pn_li;

    @FXML
    private Rectangle rec;

    @FXML
    private JFXSlider refresh;

    @FXML
    private Label lb_re;

    ServerSocket sv;
    private int p1, k;
    IP ip = new IP();
    File selectedFile;
    boolean t = false;
    private final String urep = "c:/Utilisateur/";
    private BooleanProperty bp = new SimpleBooleanProperty(false);

    /**
     * Initializes the controller class.
     *
     * @param url
     * @param rb
     */
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        File p = new File(urep);
        p.mkdir();
        String[] entries = p.list();
        for (String s : entries) {
            File currentFile = new File(p.getPath(), s);
            currentFile.delete();
        }
        li_se.getItems().clear();
        glass.setStyle("-fx-background-color: rgba(255, 255, 255, 0.5);");
        BoxBlur blur = new BoxBlur(10, 10, 3);
        glass.setEffect(blur);
        refresh.valueProperty().addListener(this);
        Timeline timeline;
        double widthOfOneGradientCycle = 40.0;
        double gradientSlopeDegree = 45.0;
        double xStartStatic = 100.0;
        double yStartStatic = 100.0;
        double xEndStatic = xStartStatic + (widthOfOneGradientCycle * Math.cos(Math.toRadians(gradientSlopeDegree)));
        double yEndStatic = yStartStatic + (widthOfOneGradientCycle * Math.sin(Math.toRadians(gradientSlopeDegree)));
        timeline = new Timeline();
        for (int i = 0; i < 10; i++) {
            int innerIterator = i;
            KeyFrame kf = new KeyFrame(Duration.millis(40 * innerIterator), (ActionEvent ae) -> {
                double runningRadius = innerIterator * (widthOfOneGradientCycle / 10);
                double xStartDynamic = xStartStatic + (runningRadius * Math.cos(Math.toRadians(gradientSlopeDegree)));
                double yStartDynamic = yStartStatic + (runningRadius * Math.sin(Math.toRadians(gradientSlopeDegree)));
                double xEndDynamic = xEndStatic + (runningRadius * Math.cos(Math.toRadians(gradientSlopeDegree)));
                double yEnddynamic = yEndStatic + (runningRadius * Math.sin(Math.toRadians(gradientSlopeDegree)));

                LinearGradient gradient = new LinearGradient(xStartDynamic, yStartDynamic, xEndDynamic, yEnddynamic,
                        false, CycleMethod.REPEAT, new Stop[]{
                            new Stop(0.0, Color.TRANSPARENT),
                            new Stop(0.5, Color.TRANSPARENT),
                            new Stop(1.0, Color.BLACK)
                        });
                rec.setStroke(gradient);
            });
            timeline.getKeyFrames().add(kf);
        }
        timeline.setCycleCount(Timeline.INDEFINITE);
        timeline.play();
    }

    private void Refresh(ObservableNumberValue refreshRateProperty) {
        Timeline refreshWonder = new Timeline(new KeyFrame(Duration.seconds(1), (ActionEvent event) -> {
            //getServices(event);
        }));
        refreshWonder.rateProperty().bind(Bindings.divide(1d, refreshRateProperty));
        refreshWonder.setCycleCount(Animation.INDEFINITE);

        bp.addListener((o, oldValue, newValue) -> {
            if (newValue) {
                refreshWonder.pause();
            } else {
                refreshWonder.play();
            }
        });

        refreshWonder.play();
    }

    @Override
    public void changed(ObservableValue observable, Object oldValue, Object newValue) {
        int r = ((int) refresh.getValue());
        ObservableNumberValue obsInt = new SimpleIntegerProperty(r);
        Refresh(obsInt);
    }

    @Override
    public void setScreenParent(ScreensController screenParent) {
        myController = screenParent;
    }

    @FXML
    private void Back(ActionEvent e) {
        myController.setScreen(ScreensFramework.screen2ID);
        li_se.getItems().clear();
    }

    @FXML
    private void Fermer(ActionEvent e) {
        System.exit(0);
    }
}

Это метод ListeService ():

@Override
public ArrayList ListeService() throws RemoteException {
    ArrayList<String> se = new ArrayList<>();
    se.clear();
    try {
        Connection c = DriverManager.getConnection("jdbc:mysql://192.168.1.2:3306/Cyberwind", "cloud", "");
        Statement sta = c.createStatement();
        ResultSet res = sta.executeQuery("SELECT `service` FROM `connexion`");
        ArrayList<String> uniques = new ArrayList<>();
        while (res.next() && !res.getString("service").equals("null")) {
            uniques.add(res.getString("service"));
        }
        uniques.stream().filter((re) -> (!se.contains(re))).forEachOrdered((re) -> {
            se.add(re);
        });
    } catch (SQLException ex) {
        Logger.getLogger(Cloud_ServeurIMPL.class.getName()).log(Level.SEVERE, null, ex);
    }
    return se;
}
...