Ignore:
Timestamp:
01/24/14 11:32:31 (10 years ago)
Author:
ngw8
Message:

Changed JFX files to no longer use reflection (as some new features were impossible via reflection) and just import javafx instead. This will probably cause Eclipse to complain if you're using a Java version <= 7, but building/running Expeditee will still work (using Eclipse or Ant).
Have also added an Ant target that builds without ant JFX stuff. See the comments near the top of JfxBrowser.java or WebParser.java for details

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/expeditee/io/WebParser.java

    r734 r748  
    1313import java.util.Arrays;
    1414
     15/*
     16 * JavaFX is not on the default java classpath until Java 8 (but is still included with Java 7), so your IDE will probably complain that the imports below can't be resolved.
     17 * In Eclipse hitting'Proceed' when told 'Errors exist in project' should allow you to run Expeditee without any issues (although the JFX Browser widget will not display),
     18 * or you can just exclude JfxBrowser, WebParser and JfxbrowserActions from the build path.
     19 *
     20 * If you are using Ant to build/run, 'ant build' will try to build with JavaFX jar added to the classpath.
     21 * If this fails, 'ant build-nojfx' will build with the JfxBrowser, WebParser and JfxbrowserActions excluded from the build path.
     22 */
     23
     24import javafx.animation.AnimationTimer;
     25import javafx.application.Platform;
     26import javafx.beans.value.ChangeListener;
     27import javafx.beans.value.ObservableValue;
     28import javafx.concurrent.Worker.State;
     29import javafx.scene.web.WebEngine;
     30
    1531import javax.imageio.ImageIO;
    1632import javax.swing.JComponent;
     33
     34import netscape.javascript.JSObject;
    1735
    1836import org.expeditee.gui.Frame;
     
    2644import org.expeditee.items.Picture;
    2745import org.expeditee.items.Text;
    28 import org.expeditee.reflection.JavaFX;
    2946import org.w3c.dom.Node;
    3047import org.w3c.dom.html.HTMLBodyElement;
     
    4966        public static void parseURL(final String URL, final Frame frame) {
    5067                try {
    51                         JavaFX.PlatformRunLater.invoke(null, new Runnable() {
     68                        Platform.runLater(new Runnable() {
    5269                                @Override
    5370                public void run() {
    5471                    try {
    55                         Object webEngine = JavaFX.WebEngineConstructor.newInstance(URL);
     72                                                WebEngine webEngine = new WebEngine(URL);
    5673                            loadPage(webEngine, frame);
    5774                    } catch (Exception e) {
     
    6582        }
    6683       
    67         protected static void loadPage(final Object webEngine, final Frame frame) throws Exception {
    68                 JavaFX.ReadOnlyObjectPropertyAddListener.invoke(JavaFX.WorkerStateProperty.invoke(JavaFX.WebEngineGetLoadWorker
    69                         .invoke(webEngine)), java.lang.reflect.Proxy.newProxyInstance(
    70                                         JavaFX.ChangeListener.getClassLoader(), new java.lang.Class[] { JavaFX.ChangeListener },
    71                         new java.lang.reflect.InvocationHandler() {
    72                         @Override
    73                         public Object invoke(Object proxy, java.lang.reflect.Method method, Object[] args)
    74                                 throws java.lang.Throwable {
    75                                 String method_name = method.getName();
    76                                 // Class<?>[] classes = method.getParameterTypes();
    77                                 // public void changed(ObservableValue ov, State oldState, State newState)
    78                                 if (method_name.equals("changed")) {
    79                                         // changed takes 3 args
    80                                         if (args == null || args.length != 3) {
    81                                                 return null;
    82                                         }
    83                                         // args[0] is the ObservableValue
    84                                         // args[2] is the new State
    85                                         if (args[2].getClass() == JavaFX.State) {
    86                                                 int id = JavaFX.StateConstants.indexOf(args[2]);
    87                                                 switch (id) {
    88                                                         case 0: // READY
    89                                                                 // MessageBay.displayMessage("WebEngine ready");
    90                                                                 break;
    91                                                         case 1: // SCHEDULED
    92                                                                 // MessageBay.displayMessage("Scheduled page load");
    93                                                                 break;
    94                                                         case 2: // RUNNING
    95                                                                 System.out.println("Loading page!");
    96                                                                 // MessageBay.displayMessage("WebEngine running");
    97                                                                 break;
    98                                                         case 3: // SUCCEEDED
    99                                                                 // MessageBay.displayMessage("Finished loading page");
    100                                                                 System.out.println("Parsing page!");
    101                                                                 JavaFX.WebEngineExecuteScript.invoke(webEngine, "window.resizeTo(800, 800);"
    102                                                                                 + "document.body.style.width = '1000px'");
    103                                                                 parsePage(webEngine, frame);
    104                                                                 System.out.println("Parsed page!");
    105                                                                 break;
    106                                                         case 4: // CANCELLED
    107                                                                 MessageBay.displayMessage("Cancelled loading page");
    108                                                                 break;
    109                                                         case 5: // FAILED
    110                                                                 MessageBay.displayMessage("Failed to load page");
    111                                                                 break;
    112                                                         }
    113                                                 }
    114                                                 System.out.println("\n");
    115                                         }
    116                                         return null;
    117                                 }
    118                 }));
     84        protected static void loadPage(final WebEngine webEngine, final Frame frame) throws Exception {
     85                webEngine.getLoadWorker().stateProperty().addListener(new ChangeListener<State>() {
     86
     87                        @Override
     88                        public void changed(ObservableValue<? extends State> ov, State oldState, State newState) {
     89
     90                        switch (newState) {
     91                                case READY: // READY
     92                                        // MessageBay.displayMessage("WebEngine ready");
     93                                        break;
     94                                case SCHEDULED: // SCHEDULED
     95                                        // MessageBay.displayMessage("Scheduled page load");
     96                                        break;
     97                                case RUNNING: // RUNNING
     98                                        System.out.println("Loading page!");
     99                                        // MessageBay.displayMessage("WebEngine running");
     100                                        break;
     101                                case SUCCEEDED: // SUCCEEDED
     102                                        // MessageBay.displayMessage("Finished loading page");
     103                                        System.out.println("Parsing page!");
     104                                        webEngine.executeScript("window.resizeTo(800, 800);"
     105                                                        + "document.body.style.width = '1000px'");
     106                                        parsePage(webEngine, frame);
     107                                        System.out.println("Parsed page!");
     108                                        break;
     109                                case CANCELLED: // CANCELLED
     110                                        MessageBay.displayMessage("Cancelled loading page");
     111                                        break;
     112                                case FAILED: // FAILED
     113                                        MessageBay.displayMessage("Failed to load page");
     114                                        break;
     115                        }       
     116                        }
     117                });
    119118        }
    120119       
     
    127126         *            The Expeditee frame to output the converted page to
    128127         */
    129         public static void parsePage(final Object webEngine, final Frame frame) {
     128        public static void parsePage(final WebEngine webEngine, final Frame frame) {
    130129                try {
    131                         JavaFX.PlatformRunLater.invoke(null, new Runnable() {
     130                        Platform.runLater(new Runnable() {
    132131                                @Override
    133132                                public void run() {
     
    135134                                                Progress progressBar = MessageBay.displayProgress("Converting web page");
    136135
    137                                                 HTMLBodyElement doc = (HTMLBodyElement) JavaFX.WebEngineExecuteScript.invoke(webEngine, "document.body");
    138 
    139                                                 Object window = JavaFX.WebEngineExecuteScript.invoke(webEngine, "window");
    140 
    141                                                 frame.setBackgroundColor(rgbStringToColor((String) JavaFX.JSObjectCall.invoke(JavaFX.JSObjectCall.invoke(window, "getComputedStyle", new Object[] { doc }), "getPropertyValue",
     136                                                Node doc = (Node) webEngine.executeScript("document.body");
     137
     138                                                JSObject window = (JSObject) webEngine.executeScript("window");
     139
     140                                                frame.setBackgroundColor(rgbStringToColor((String) ((JSObject) (window.call("getComputedStyle", new Object[] { doc }))).call("getPropertyValue",
    142141                                                                new Object[] { "background-color" })));
    143142                                               
    144143                                                // Functions to be used later in JavaScript
    145                                                 JavaFX.WebEngineExecuteScript.invoke(webEngine, ""
     144                                                webEngine.executeScript(""
     145                                                                                + "function addToSpan(text) {"
     146                                                                                + "             span = document.createElement('wordSpan');"
     147                                                                                + "             span.textContent = text;"
     148                                                                                + "             par.insertBefore(span, refNode);"
     149                                                                                                // Checking if the current word is on a new line (i.e. lower than the previous word)
     150                                                                                + "             if (prevSpan !== null && span.getBoundingClientRect().top > prevSpan.getBoundingClientRect().top) {"
     151                                                                                                        // If it is, prepend a new line character to it. The new line characters doesn't affect the rendered HTML
     152                                                                                + "                     span.textContent = '\\n' + span.textContent;"
     153
     154                                                                                                        // Checking if the previous word is horizontally aligned with the one before it.
     155                                                                                                        // If it is, merge the text of the two spans
     156                                                                                + "                     if ( prevPrevSpan !== null && prevPrevSpan.getBoundingClientRect().left == prevSpan.getBoundingClientRect().left) {"
     157                                                                                + "                             prevPrevSpan.textContent = prevPrevSpan.textContent + prevSpan.textContent;"
     158                                                                                + "                             par.removeChild(prevSpan);"
     159                                                                                + "                     } else {"
     160                                                                                + "                             prevPrevSpan = prevSpan;"
     161                                                                                + "                     }"
     162                                                                                + "                     prevSpan = span;"
     163                                                                                + "             } else if ( prevSpan !== null) {"
     164                                                                                                        // Word is on the same line as the previous one, so merge the second into the span of the first
     165                                                                                + "                     prevSpan.textContent = prevSpan.textContent + span.textContent;"
     166                                                                                + "                     par.removeChild(span);"
     167                                                                                + "             } else {"
     168                                                                                + "                     prevSpan = span;"
     169                                                                                + "             }"
     170                                                                                + "}"
     171
     172                                                                                + "function splitIntoWords(toSplit) {"
     173                                                                                + "             var words = [];"
     174                                                                                + "             var pattern = /\\s+/g;"
     175                                                                                + "             var words = toSplit.split(pattern);"
     176                                                                                + ""
     177                                                                                + "             for (var i = 0; i < words.length - 1; i++) {"
     178                                                                                + "                     words[i] = words[i] + ' ';"
     179                                                                                + "             }"
     180                                                                                + "             return words;"
     181                                                                                + "}"
     182                                                );
     183                                       
     184                                                // Using Javascript to get an array of all the text nodes in the document so they can be wrapped in spans. Have to
     185                                                // loop through twice (once to build the array and once actually going through the array, otherwise when the
     186                                                // textnode is removed from the document items end up being skipped)
     187                                                JSObject textNodes = (JSObject) webEngine.executeScript(""
     188                                                        + "function getTextNodes(rootNode){"
     189                                                                + "var node;"
     190                                                                + "var textNodes=[];"
     191                                                                + "var walk = document.createTreeWalker(rootNode, NodeFilter.SHOW_TEXT);"
     192                                                                + "while(node=walk.nextNode()) {"
     193                                                                        + "if((node.textContent.trim().length > 0)) { "
     194                                                                                + "textNodes.push(node);"
     195                                                                        + "}"
     196                                                                + "}"
     197                                                                + "return textNodes;"
     198                                                        + "}; "
     199                                                        + "getTextNodes(document.body)"
     200                                                        );
     201                                               
     202                                                int nodesLength = (Integer) textNodes.getMember("length");
     203
     204                                                // Looping through all the text nodes in the document
     205                                                for (int j = 0; j < nodesLength; j++) {
     206                                                        Node currentNode = (Node) textNodes.getSlot(j);
     207
     208                                                        // Making the current node accessible in JavaScript
     209                                                        window.setMember("currentNode", currentNode);
     210                                               
     211                                                        webEngine.executeScript(""
     212                                                                        + "var span = null, prevSpan = null, prevPrevSpan = null;"
     213                                                                       
     214                                                                        // Removing repeated whitespace from the text node's content then splitting it into individual words
     215                                                                        + "var textContent  = currentNode.textContent.replace(/\\n|\\r/g, '').replace(/\\s+/g, ' ');"
     216                                                                        + "var words = splitIntoWords(textContent);"
     217                                                                       
     218                                                                        + "var refNode = currentNode.nextSibling;"
     219                                                                        + "var par = currentNode.parentElement;"
     220                                                                        + "currentNode.parentElement.removeChild(currentNode);"
     221                                                                       
     222                                                                        + "for (var i = 0; i < words.length; i++) {"
     223                                                                        + "             addToSpan(words[i]);"
     224                                                                        + "}"
     225                                                                       
     226                                                                        + "if (prevPrevSpan !== null && prevPrevSpan.getBoundingClientRect().left == prevSpan.getBoundingClientRect().left) {"
     227                                                                        + "             prevPrevSpan.textContent = prevPrevSpan.textContent + prevSpan.textContent;"
     228                                                                        + "             par.removeChild(prevSpan);"
     229                                                                        + "}"
     230                                                                        );
     231
     232                                                        // Will never reach 100% here, as the processing is not quite finished - progress is set to 100% at the end of
     233                                                        // the addPageToFrame loop below
     234                                                        progressBar.set((100 * (j)) / nodesLength);
     235                                                }
     236
     237                                                // Finding all links within the page, then setting the href attribute of all their descendants to be the same
     238                                                // link/URL.
     239                                                // This is needed because there is no apparent and efficient way to check if an element is a child of a link when
     240                                                // running through the document when added each element to Expeditee
     241                                                webEngine.executeScript(""
     242                                                                + "var anchors = document.getElementsByTagName('a');"
     243                                                                + ""
     244                                                                + "for (var i = 0; i < anchors.length; i++) {"
     245                                                                        + "var currentAnchor = anchors.item(i);"
     246                                                                        + "var anchorDescendants = currentAnchor.querySelectorAll('*');"
     247                                                                        + "for (var j = 0; j < anchorDescendants.length; j++) {"
     248                                                                                + "anchorDescendants.item(j).href = currentAnchor.href;"
     249                                                                        + "}"
     250                                                                + "}"
     251                                                                );
     252
     253                                                WebParser.addPageToFrame(doc, window, webEngine, frame);
     254
     255                                                progressBar.set(100);
     256
     257                                        } catch (Exception e) {
     258                                                e.printStackTrace();
     259                                        }
     260                                        System.out.println("Parsed frame");
     261                                        FrameUtils.Parse(frame);
     262                                        frame.setChanged(true);
     263                                        FrameIO.SaveFrame(frame);
     264                                }
     265                        });
     266                } catch (Exception e) {
     267                        e.printStackTrace();
     268                }
     269    }
     270
     271        /**
     272         * Converts a loaded page to Expeditee frame(s)
     273         *
     274         * @param webEngine
     275         *            The JavaFX WebEngine in which the page to be converted is loaded
     276         * @param frame
     277         *            The Expeditee frame to output the converted page to
     278         */
     279        public static void parsePageSimple(final WebEngine webEngine, final Object webView, final JComponent jfxPanel, final Frame frame) {
     280                try {
     281                        final Object notifier = new Object();
     282                        final MutableBool bottomReached = new MutableBool(false);
     283
     284                        final Progress progressBar = MessageBay.displayProgress("Converting web page");
     285
     286                        AnimationTimer timer = new AnimationTimer() {
     287
     288                                int frameCount = 0;
     289                                Frame frameToAddTo = frame;
     290
     291                                @Override
     292                                public void handle(long arg0) {
     293                                        // Must wait 2 frames before taking a snapshot of the webview, otherwise JavaFX won't have redrawn
     294                                        if (frameCount++ > 1) {
     295                                                frameCount = 0;
     296                                                this.stop();
     297
     298                                                BufferedImage image = new BufferedImage(jfxPanel.getWidth(), jfxPanel.getHeight(), BufferedImage.TYPE_INT_ARGB);
     299
     300                                                Graphics graphics = image.createGraphics();
     301
     302                                                // Drawing the JfxPanel (containing the webview) to the image
     303                                                jfxPanel.paint(graphics);
     304
     305                                                try {
     306                                                        int hashcode = Arrays.hashCode(image.getData().getPixels(0, 0, image.getWidth(), image.getHeight(), (int[]) null));
     307
     308                                                        File out = new File(FrameIO.IMAGES_PATH + "webpage-" + Integer.toHexString(hashcode) + ".png");
     309                                                        out.mkdirs();
     310                                                        ImageIO.write(image, "png", out);
     311
     312                                                        Text link = new Text("Next");
     313                                                        link.setPosition(500, 20);
     314                                                        frameToAddTo.addItem(link);
     315
     316                                                        FrameIO.SaveFrame(frameToAddTo);
     317
     318                                                        frameToAddTo = FrameIO.CreateFrame(frame.getFramesetName(), Integer.toHexString(hashcode), null);
     319
     320                                                        link.setLink(frameToAddTo.getName());
     321
     322                                                        // Adding the image
     323                                                        frameToAddTo.addText(0, 0, "@i: " + out.getName(), null);
     324
     325                                                        // Button to go to the next page
     326                                                        Text nextButton = (Text) FrameCreator.createButton("Next", null, null, 10F, 10F);
     327                                                        nextButton.setID(frameToAddTo.getNextItemID());
     328                                                        nextButton.addAction("next");
     329                                                        frameToAddTo.addItem(nextButton);
     330
     331                                                        FrameIO.SaveFrame(frameToAddTo);
     332                                                        System.out.println("C");
     333
     334                                                } catch (IOException e) {
     335                                                        e.printStackTrace();
     336                                                }
     337
     338
     339                                                graphics.dispose();
     340                                                image.flush();
     341
     342                                                synchronized (notifier) {
     343                                                        notifier.notify();
     344                                                }
     345
     346                                                try {
     347                                                        Platform.runLater(new Runnable() {
     348                                                                @Override
     349                                                                public void run() {
     350                                                                        try {
     351                                                                                HTMLBodyElement doc = (HTMLBodyElement) webEngine.executeScript("document.body");
     352
     353                                                                                JSObject window = (JSObject) webEngine.executeScript("window");
     354
     355                                                                                System.out.println("adding");
     356                                                                                WebParser.addPageToFrame(doc, window, webEngine, frameToAddTo);
     357                                                                        } catch (Exception ex) {
     358                                                                                ex.printStackTrace();
     359                                                                        }
     360                                                                }
     361                                                        });
     362                                                } catch (Exception ex) {
     363                                                        ex.printStackTrace();
     364                                                }
     365                                        }
     366                                }
     367                        };
     368
     369                        Platform.runLater(new Runnable() {
     370                                @Override
     371                                public void run() {
     372                                        try {
     373                                               
     374                                                webEngine.executeScript(""
     375                                                                // Initializing the counter used when scrolling the page
     376                                                                + "var scrollCounter = 0;"
     377                                                               
     378                                                                // Setting all text to be hidden
     379                                                                + "var css = document.createElement('style');"
     380                                                                + "css.type = 'text/css';"
     381                                                                + "var style = 'WordSpan { visibility: hidden }';"
     382                                                                + "css.appendChild(document.createTextNode(style));"
     383                                                                + "document.getElementsByTagName('head')[0].appendChild(css);");
     384
     385                                                HTMLBodyElement doc = (HTMLBodyElement) webEngine.executeScript("document.body");
     386
     387                                                JSObject window = (JSObject) webEngine.executeScript("window");
     388
     389                                                frame.setBackgroundColor(rgbStringToColor((String) ((JSObject) (window.call("getComputedStyle", new Object[] { doc }))).call("getPropertyValue",
     390                                                                new Object[] { "background-color" })));
     391                                               
     392                                                // Functions to be used later in JavaScript
     393                                                webEngine.executeScript(""
    146394                                                                                + "function addToSpan(text) {"
    147395                                                                                + "             span = document.createElement('wordSpan');"
     
    180428                                                // loop through twice (once to build the array and once actually going through the array, otherwise when the
    181429                                                // textnode is removed from the document items end up being skipped)
    182                                                 Object textNodes = JavaFX.WebEngineExecuteScript.invoke(webEngine, ""
     430                                                JSObject textNodes = (JSObject) webEngine.executeScript(""
    183431                                                        + "function getTextNodes(rootNode){"
    184432                                                                + "var node;"
     
    195443                                                        );
    196444                                               
    197                                                 int nodesLength = (Integer) JavaFX.JSObjectGetMember.invoke(textNodes, "length");
     445                                                int nodesLength = (Integer) textNodes.getMember("length");
    198446
    199447                                                // Looping through all the text nodes in the document
    200448                                                for (int j = 0; j < nodesLength; j++) {
    201                                                         Node currentNode = (Node) JavaFX.JSObjectGetSlot.invoke(textNodes, j);
     449                                                        Node currentNode = (Node) textNodes.getSlot(j);
    202450
    203451                                                        // Making the current node accessible in JavaScript
    204                                                         JavaFX.JSObjectSetMember.invoke(window, "currentNode", currentNode);
     452                                                        window.setMember("currentNode", currentNode);
    205453                                               
    206                                                         JavaFX.WebEngineExecuteScript.invoke(webEngine, ""
     454                                                        webEngine.executeScript(""
    207455                                                                        + "var span = null, prevSpan = null, prevPrevSpan = null;"
    208456                                                                       
     
    234482                                                // This is needed because there is no apparent and efficient way to check if an element is a child of a link when
    235483                                                // running through the document when added each element to Expeditee
    236                                                 JavaFX.WebEngineExecuteScript.invoke(webEngine, ""
     484                                                webEngine.executeScript(""
    237485                                                                + "var anchors = document.getElementsByTagName('a');"
    238486                                                                + ""
     
    246494                                                                );
    247495
    248                                                 WebParser.addPageToFrame(doc, window, webEngine, frame);
    249 
    250                                                 progressBar.set(100);
    251 
    252                                         } catch (Exception e) {
    253                                                 e.printStackTrace();
    254                                         }
    255                                         System.out.println("Parsed frame");
    256                                         FrameUtils.Parse(frame);
    257                                         frame.setChanged(true);
    258                                         FrameIO.SaveFrame(frame);
    259                                 }
    260                         });
    261                 } catch (Exception e) {
    262                         e.printStackTrace();
    263                 }
    264     }
    265 
    266         /**
    267          * Converts a loaded page to Expeditee frame(s)
    268          *
    269          * @param webEngine
    270          *            The JavaFX WebEngine in which the page to be converted is loaded
    271          * @param frame
    272          *            The Expeditee frame to output the converted page to
    273          */
    274         public static void parsePageSimple(final Object webEngine, final Object webView, final JComponent jfxPanel, final Frame frame) {
    275                 try {
    276                         final Object notifier = new Object();
    277                         final MutableBool notAtBottom = new MutableBool(true);
    278 
    279                         JavaFX.PlatformRunLater.invoke(null, new Runnable() {
    280                                 @Override
    281                                 public void run() {
    282                                         try {
    283                                                 // Initializing the counter used when scrolling the page
    284                                                 JavaFX.WebEngineExecuteScript.invoke(webEngine, "var scrollCounter = 0");
    285496                                        } catch (Exception ex) {
    286497                                                ex.printStackTrace();
     
    303514                        }
    304515
    305                                 int tick = 0;
    306                                 Frame frameToAddTo = frame;
    307 
    308                         while (notAtBottom.getValue()) {
    309                                 JavaFX.PlatformRunLater.invoke(null, new Runnable() {
     516                        while (!bottomReached.getValue()) {
     517                                Platform.runLater(new Runnable() {
    310518                                        @Override
    311519                                        public void run() {
    312520                                                try {
    313521                                                        // Scrolling down the page
    314                                                         JavaFX.WebEngineExecuteScript.invoke(webEngine, ""
     522                                                        webEngine.executeScript(""
    315523                                                                        + "window.scrollTo(0, scrollCounter * window.innerHeight);"
    316524                                                                        + "scrollCounter = scrollCounter+1;");
    317                        
    318                                                         notAtBottom.setValue((Boolean) JavaFX.WebEngineExecuteScript.invoke(webEngine, "(window.pageYOffset + window.innerHeight < document.documentElement.scrollHeight)"));
     525
     526                                                        System.out.println('B');
     527
     528                                                        bottomReached.setValue((boolean) webEngine.executeScript("(window.pageYOffset + window.innerHeight >= document.documentElement.scrollHeight)"));
    319529
    320530                                                        synchronized (notifier) {
     
    338548                                }
    339549
    340                                 BufferedImage image = new BufferedImage(jfxPanel.getWidth(), jfxPanel.getHeight(), BufferedImage.TYPE_INT_ARGB);
    341 
    342                                 Graphics graphics = image.createGraphics();
    343 
    344                                 // Drawing the JfxPanel (containing the webview) to the image
    345                                 jfxPanel.paint(graphics);
    346 
    347                                 try {
    348                                         int hashcode = Arrays.hashCode(image.getData().getPixels(0, 0, image.getWidth(), image.getHeight(), (int[]) null));
    349 
    350                                         File out = new File(FrameIO.IMAGES_PATH + "webpage-" + Integer.toHexString(hashcode) + ".png");
    351                                         out.mkdirs();
    352                                         ImageIO.write(image, "png", out);
    353 
    354                                         Text link = new Text("Next");
    355                                         link.setPosition(500, 20);
    356                                         frameToAddTo.addItem(link);
    357 
    358                                         frameToAddTo = FrameIO.CreateFrame(frame.getFramesetName(), Integer.toHexString(hashcode), null);
    359 
    360                                         link.setLink(frameToAddTo.getName());
    361 
    362                                         // Adding the image
    363                                         frameToAddTo.addText(0, 0, "@i: " + out.getName(), null);
    364 
    365                                         // Button to go to the next page
    366                                         Text nextButton = (Text) FrameCreator.createButton("Next", null, null, 10F, 10F);
    367                                         nextButton.setID(frameToAddTo.getNextItemID());
    368                                         nextButton.addAction("next");
    369                                         frameToAddTo.addItem(nextButton);
    370 
    371                                         FrameIO.SaveFrame(frameToAddTo);
    372 
    373                                 } catch (IOException e) {
    374                                         e.printStackTrace();
     550                                timer.start();
     551
     552                                synchronized (notifier) {
     553                                        try {
     554                                                // Waiting for the timer thread to finish before looping again
     555                                                notifier.wait();
     556                                        } catch (InterruptedException e) {
     557                                                // TODO Auto-generated catch block
     558                                                e.printStackTrace();
     559                                        }
    375560                                }
    376                                 graphics.dispose();
    377                                 image.flush();
    378 
    379                                 System.out.println("C");
    380 
    381                                 synchronized (notifier) {
    382                                         notifier.notify();
    383                                 }
    384 
    385                                 tick = 0;
    386561
    387562                        }
     
    442617         * @throws IllegalAccessException
    443618         */
    444         private static void addPageToFrame(Node rootElement, Object window, Object webEngine, Frame frame) throws InvocationTargetException, IllegalAccessException,
     619        private static void addPageToFrame(Node rootElement, JSObject window, WebEngine webEngine, Frame frame) throws InvocationTargetException, IllegalAccessException,
    445620                        IllegalArgumentException {
    446621               
     
    449624                if (currentNode.getNodeType() == Node.TEXT_NODE || currentNode.getNodeType() == Node.ELEMENT_NODE) {
    450625                       
    451                         Object style;
    452                         Object bounds;
     626                        JSObject style;
     627                        JSObject bounds;
    453628
    454629                        if (currentNode.getNodeType() == Node.TEXT_NODE) {
    455630                                // CSS style for the element
    456                                 style = JavaFX.JSObjectCall.invoke(window, "getComputedStyle", new Object[] { currentNode.getParentNode() });
     631                                style = (JSObject) window.call("getComputedStyle", new Object[] { currentNode.getParentNode() });
    457632
    458633                                // Getting a rectangle that represents the area and position of the element
    459                                 bounds = JavaFX.JSObjectCall.invoke(currentNode.getParentNode(), "getBoundingClientRect", new Object[] {});
     634                                bounds = (JSObject) ((JSObject) currentNode.getParentNode()).call("getBoundingClientRect", new Object[] {});
    460635                        } else {
    461                                 style = JavaFX.JSObjectCall.invoke(window, "getComputedStyle", new Object[] { currentNode });
    462 
    463                                 bounds = JavaFX.JSObjectCall.invoke(currentNode, "getBoundingClientRect", new Object[] {});
     636                                style = (JSObject) window.call("getComputedStyle", new Object[] { currentNode });
     637
     638                                bounds = (JSObject) ((JSObject) currentNode).call("getBoundingClientRect", new Object[] {});
    464639                        }
    465640                       
     
    467642                        // TODO: This doesn't check if an element or any of its parent elements have position:fixed set - the only
    468643                        // way to check seems to be to walking through the element's parents until the document root is reached
    469                         float x = Float.valueOf(JavaFX.JSObjectGetMember.invoke(bounds, "left").toString())
    470                                         + Float.valueOf(JavaFX.WebEngineExecuteScript.invoke(webEngine, "window.pageXOffset").toString());
    471                         float y = Float.valueOf(JavaFX.JSObjectGetMember.invoke(bounds, "top").toString())
    472                                         + Float.valueOf(JavaFX.WebEngineExecuteScript.invoke(webEngine, "window.pageYOffset").toString());
    473 
    474                         float width = Float.valueOf(JavaFX.JSObjectGetMember.invoke(bounds, "width").toString());
    475                         float height = Float.valueOf(JavaFX.JSObjectGetMember.invoke(bounds, "height").toString());
     644                        float x = Float.valueOf(bounds.getMember("left").toString()) + Float.valueOf(webEngine.executeScript("window.pageXOffset").toString());
     645                        float y = Float.valueOf(bounds.getMember("top").toString()) + Float.valueOf(webEngine.executeScript("window.pageYOffset").toString());
     646
     647                        float width = Float.valueOf(bounds.getMember("width").toString());
     648                        float height = Float.valueOf(bounds.getMember("height").toString());
    476649
    477650                        // Checking if the element is actually visible on the page
     
    480653                                // Filtering the node type, starting with text nodes
    481654                                if (currentNode.getNodeType() == Node.TEXT_NODE) {
    482                                         String fontSize = ((String) JavaFX.JSObjectCall.invoke(style, "getPropertyValue", new Object[] { "font-size" }));
     655                                       
     656                                        String fontSize = ((String) style.call("getPropertyValue", new Object[] { "font-size" }));
    483657
    484658                                        // Trimming off the units (always px) from the font size
     
    486660                                       
    487661                                        // Always returns in format "rgb(x,x,x)" or "rgba(x,x,x,x)"
    488                                         String color = (String) JavaFX.JSObjectCall.invoke(style, "getPropertyValue", new Object[] { "color" });
     662                                        String color = (String) style.call("getPropertyValue", new Object[] { "color" });
    489663                                       
    490664                                        // Always returns in format "rgb(x,x,x)" or "rgba(x,x,x,x)"
    491                                         String bgColorString = (String) JavaFX.JSObjectCall.invoke(style, "getPropertyValue", new Object[] { "background-color" });
    492 
    493                                         String align = (String) JavaFX.JSObjectCall.invoke(style, "getPropertyValue", new Object[] { "text-align" });
     665                                        String bgColorString = (String) style.call("getPropertyValue", new Object[] { "background-color" });
     666
     667                                        String align = (String) style.call("getPropertyValue", new Object[] { "text-align" });
    494668                                       
    495669                                        // Returns comma-separated list of typefaces
    496                                         String typeface = (String) JavaFX.JSObjectCall.invoke(style, "getPropertyValue", new Object[] { "font-family" });
     670                                        String typeface = (String) style.call("getPropertyValue", new Object[] { "font-family" });
    497671
    498672                                        String[] typefaces = typeface.split(", |,");
    499673                                       
    500                                         String weight = (String) JavaFX.JSObjectCall.invoke(style, "getPropertyValue", new Object[] { "font-weight" });
     674                                        String weight = (String) style.call("getPropertyValue", new Object[] { "font-weight" });
    501675                                       
    502                                         String fontStyle = (String) JavaFX.JSObjectCall.invoke(style, "getPropertyValue", new Object[] { "font-style" });
     676                                        String fontStyle = (String) style.call("getPropertyValue", new Object[] { "font-style" });
    503677
    504678                                        // Returns "normal" or a value in pixels (e.g. "10px")
    505                                         String letterSpacing = (String) JavaFX.JSObjectCall.invoke(style, "getPropertyValue", new Object[] { "letter-spacing" });
     679                                        String letterSpacing = (String) style.call("getPropertyValue", new Object[] { "letter-spacing" });
    506680
    507681                                        // Returns a value in pixels (e.g. "10px")
    508                                         String lineHeight = (String) JavaFX.JSObjectCall.invoke(style, "getPropertyValue", new Object[] { "line-height" });
    509 
    510                                         String textTransform = (String) JavaFX.JSObjectCall.invoke(style, "getPropertyValue", new Object[] { "text-transform" });
    511 
    512                                         String linkUrl = (String) JavaFX.JSObjectGetMember.invoke(currentNode.getParentNode(), "href");
     682                                        String lineHeight = (String) style.call("getPropertyValue", new Object[] { "line-height" });
     683
     684                                        String textTransform = (String) style.call("getPropertyValue", new Object[] { "text-transform" });
     685
     686                                        String linkUrl = (String) ((JSObject) currentNode.getParentNode()).getMember("href");
    513687
    514688                                        Boolean fontFound = false;
     
    632806
    633807                                        // Always returns in format "rgb(x,x,x)" or "rgba(x,x,x,x)"
    634                                         String bgColorString = (String) JavaFX.JSObjectCall.invoke(style, "getPropertyValue", new Object[] { "background-color" });
     808                                        String bgColorString = (String) style.call("getPropertyValue", new Object[] { "background-color" });
    635809
    636810                                        Color bgColor = rgbStringToColor(bgColorString);
     
    645819                                        // may also return gradients, data, etc. (not handled yet). Only need to add bg image on
    646820                                        // 'ELEMENT_NODE' (and not 'TEXT_NODE' otherwise there would be double-ups
    647                                         String bgImage = (String) JavaFX.JSObjectCall.invoke(style, "getPropertyValue", new Object[] { "background-image" });
     821                                        String bgImage = (String) style.call("getPropertyValue", new Object[] { "background-image" });
    648822                                       
    649                                         String linkUrl = (String) JavaFX.JSObjectGetMember.invoke(currentNode, "href");
     823                                        String linkUrl = (String) ((JSObject) currentNode).getMember("href");
    650824
    651825                                        if (bgImage.startsWith("url(")) {
    652826                                                bgImage = bgImage.substring(4, bgImage.length() - 1);
    653827
    654                                                 String bgSize = ((String) JavaFX.JSObjectCall.invoke(style, "getPropertyValue", new Object[] { "background-size" })).toLowerCase();
    655                                                 String bgRepeat = ((String) JavaFX.JSObjectCall.invoke(style, "getPropertyValue", new Object[] { "background-repeat" })).toLowerCase();
     828                                                String bgSize = ((String) style.call("getPropertyValue", new Object[] { "background-size" })).toLowerCase();
     829                                                String bgRepeat = ((String) style.call("getPropertyValue", new Object[] { "background-repeat" })).toLowerCase();
    656830
    657831                                                // Returns "[x]px [y]px", "[x]% [y]%", "[x]px [y]%" or "[x]% [y]px"
    658                                                 String bgPosition = ((String) JavaFX.JSObjectCall.invoke(style, "getPropertyValue", new Object[] { "background-position" })).toLowerCase();
     832                                                String bgPosition = ((String) style.call("getPropertyValue", new Object[] { "background-position" })).toLowerCase();
    659833
    660834                                                String[] bgOffsetCoords = bgPosition.split(" ");
     
    720894                                        String imgSrc;
    721895
    722                                         if (currentNode.getNodeName().toLowerCase().equals("img") && (imgSrc = JavaFX.JSObjectGetMember.invoke(currentNode, "src").toString()) != null) {
     896                                        if (currentNode.getNodeName().toLowerCase().equals("img") && (imgSrc = ((JSObject) currentNode).getMember("src").toString()) != null) {
    723897                                                try {
    724898                                                        WebParser.addImageFromUrl(imgSrc, linkUrl, frame, x, y, (int) width, null, null, null, null, null, 0, 0);
     
    743917        }
    744918
    745         private static boolean elementVisible(float x, float y, float width, float height, Object style) {
     919        private static boolean elementVisible(float x, float y, float width, float height, JSObject style) {
    746920                try {
    747                         if (width <= 0 || height <= 0 || x + width <= 0 || y + height <= 0 || ((String) JavaFX.JSObjectCall.invoke(style, "getPropertyValue", new Object[] { "visibility" })).equals("hidden")
    748                                         || ((String) JavaFX.JSObjectCall.invoke(style, "getPropertyValue", new Object[] { "display" })).equals("none")) {
     921                        if (width <= 0 || height <= 0 || x + width <= 0 || y + height <= 0 || ((String) style.call("getPropertyValue", new Object[] { "visibility" })).equals("hidden")
     922                                        || ((String) style.call("getPropertyValue", new Object[] { "display" })).equals("none")) {
    749923                                return false;
    750924                        } else {
Note: See TracChangeset for help on using the changeset viewer.