javaarraylistwebviewjavafx-webenginejfxpanel

Maintaining sequence in pushing and printing values of two arraylists


I'm trying to build a web browser and I'm using WebView for getting web pages. I need to fetch both the URL and the title name for storing history.

So i tried in this way:

 private void currentScene() {
    Platform.runLater(new Runnable() {
        @Override
        public void run() {

            WebView view = new WebView();
            engine = view.getEngine();

            engine.createPopupHandlerProperty();
            engine.titleProperty().addListener(new ChangeListener<String>() {
                @Override
                public void changed(ObservableValue<? extends String> observable, String oldValue, final String newValue) {
                    SwingUtilities.invokeLater(new Runnable() {
                        @Override
                        public void run() {
                            if (newValue != null) {
                                //stores the title name in an arraylist
                                title.add(newValue);
                            }
                        }

                    });
                }
            });

            engine.locationProperty().addListener(new ChangeListener<String>() {
                @Override
                public void changed(ObservableValue<? extends String> ov, String oldValue, final String newValue) {
                    SwingUtilities.invokeLater(new Runnable() {
                        @Override
                        public void run() {
                            //stores the URL in another arraylist
                            titleUrl.add(newValue);
                            //sets the text of the location text field
                            locationTextField.setText(newValue);
                        }
                    });
                }
            });

            jfxPanel.setScene(new Scene(view));
        }
    });
 }

I printed out the values:

 for (int i = 0; i < title.size(); i++) {
           System.Out.Println(title.get(i)+" : "+titleUrl.get(i));        
        }

But my output is like

Google : http://www.yahoo.com
Yahoo : http://www.google.com

Can anyone please tell me where did i go wrong? Thanks in advance.


Solution

  • if you know the order of when of the 2 listeners is called (for example titleProperty listener is always called first) then you can check on the second listener the length of first list and only add stuff to it if the list of the first listener is bigger by 1 element from the list of second listener

    here is the important part of the solution

      if (title.size() == titleUrl.size() + 1) {
          titleUrl.add(newValue);
      }
    

    So this solution will work if 2 conditions are met

    1) always both events are fired (there is no case that one event only will be triggered)

    2) always both event fire in same order titleProperty listener then locationProperty listener

    here is the full code

       private void currentScene() {
            Platform.runLater(new Runnable() {
                @Override
                public void run() {
    
                    WebView view = new WebView();
                    engine = view.getEngine();
    
                    engine.createPopupHandlerProperty();
                    engine.titleProperty().addListener(new ChangeListener<String>() {
                        @Override
                        public void changed(ObservableValue<? extends String> observable, String oldValue, final String newValue) {
                            SwingUtilities.invokeLater(new Runnable() {
                                @Override
                                public void run() {
                                    if (newValue != null) {
                                        //stores the title name in an arraylist
                                        title.add(newValue);
                                    }
                                }
    
                            });
                        }
                    });
    
                    engine.locationProperty().addListener(new ChangeListener<String>() {
                        @Override
                        public void changed(ObservableValue<? extends String> ov, String oldValue, final String newValue) {
                            SwingUtilities.invokeLater(new Runnable() {
                                @Override
                                public void run() {
                                    //stores the URL in another arraylist
                                    if (title.size() == titleUrl.size() + 1) {
                                        titleUrl.add(newValue);
                                    }
                                    //sets the text of the location text field
                                    locationTextField.setText(newValue);
                                }
                            });
                        }
                    });
    
                    jfxPanel.setScene(new Scene(view));
                }
            });
        }