Я использую 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;
}