How to run Processing+Twitter4j sketch in broswer

2019-03-02 09:08发布

问题:

I'm a newbie programmer practicing Processing and I recently developed a sketch that uses Twitter4j. When I run the sketch in Java mode from the Processing Development Environment it works perfectly. Also, when I export the sketch from Java mode the resulting application runs perfectly. However, when I switch to JavaScript mode and try to run the sketch the browser preview does not display anything.

I believe the problem is related to Twitter4j because when I remove the Twitter4j-related code from the sketch and run it (in JavaScript mode) the browser preview then displays the Processing visuals.

I've been searching for a solution to this now for several hours spanning several days but I cannot find an adequate answer. I've come across posts addressing related issues but the answers have only involved terms like "signing the JAR file" (related, I think, only to Java mode) or have only shed light on problems running Processing sketches in JavaScript mode on the browser -- excluding sketches that involve the use of Twitter4j.

I've included a copy of my entire code below and would really appreciate a step-by-step answer, catering to a newbie. I'm searching for an explanation of what it takes, if possible, to get my JavaScript-mode-exported Processing + Twitter4j sketch running in HTML/my website.

Thanks for your time and your skills. I've included some notes on the code at the end of this post.

import twitter4j.conf.*;
import twitter4j.*;
import twitter4j.auth.*;
import twitter4j.api.*;
import java.util.*;

Twitter twitter;
String searchString = "#brokendreams";
List<Status> tweets;
int currentTweet;
PFont f;

int amount1 = 300;
Star[] meteors = new Star[45];
StarDust[] sprinkle = {};
String chatter;

void setup() {
  size(800,600);
  f = createFont("Tahoma", 13, true);
  textFont(f, 13);

  ConfigurationBuilder cb = new ConfigurationBuilder();
  cb.setOAuthConsumerKey("---");
  cb.setOAuthConsumerSecret("---");
  cb.setOAuthAccessToken("---");
  cb.setOAuthAccessTokenSecret("---");

  TwitterFactory tf = new TwitterFactory(cb.build());

  twitter = tf.getInstance();

  getNewTweets();

  currentTweet = 0;

  dustField();

  Status status = tweets.get(currentTweet);

  for (int j = 0; j < meteors.length; j++) {
    meteors[j] = new Star(chatterText());
  }

}

void draw() {
  background(0, 35, 0);
  for (int i = 0; i < sprinkle.length; i++) {
    StarDust dust = sprinkle[i];
    dust.move();
  }

  for (int j = 0; j < meteors.length; j++) {
    meteors[j].appear();
    meteors[j].randomOrbit();
  }

  chatterText();

}

void dustField() {
  for (int i = 0; i < amount1; i++) {
    StarDust dust = new StarDust();
    dust.swish();
    sprinkle = (StarDust[])append(sprinkle, dust);
  }
}

String chatterText() {
  currentTweet += 1;
  if (currentTweet >= tweets.size()) {
    currentTweet = 0;
  }
  Status status = tweets.get(currentTweet);
  chatter = status.getText();
  return chatter;
}

void getNewTweets() {
    try {
      Query query = new Query(searchString);
      QueryResult result = twitter.search(query);
      tweets = result.getTweets();
    } catch (TwitterException te) {
      System.out.println("Failed to search tweets: " + te.getMessage());
      System.exit(-1);
    } 
}

void refreshTweets() {
  while (true) {
    getNewTweets();
    println("Updated Tweets"); 
    delay(30000);
  }
}
class Star {

  float x, y;
  float xmove, ymove;
  float radius;
  color linecol, fillcol;
  float alpha;
  String msg;
  float frag1, frag2, frag3, frag4;

  Status status;

  Star(String message) {

    msg = message;
    x = random(width);
    y = random(height);
    radius = random(20, 60) + 10;
    linecol = color(random(255), random(255), random(255));
    fillcol = color(random(255), random(255), random(255));
    alpha = random(200);
    xmove = sin(random(2) / 2);
    ymove = sin(random(2) / 2);
    frag1 = random(radius/5);
    frag2 = random(radius/3);
    frag3 = random(radius/4);
    frag4 = random(radius/2);

  }

  void appear() {

    if (mouseX > x-(radius/2) && mouseX < x+(radius/2) && mouseY > y-(radius/2) && mouseY < y+(radius/2)) {

      strokeWeight(1);
      stroke(linecol);
      noFill();
      ellipse(x, y, radius, radius);

    } else {

      noStroke();
      fill(fillcol, alpha);
      ellipse(x, y, radius, radius);

    }

    fill(fillcol);
    noStroke();
    beginShape();
    vertex(x - (radius/3), y + frag1 - frag2);
    vertex(x, y - (radius/3));
    vertex(x, y);
    endShape(CLOSE);

    fill(linecol, alpha);
    beginShape();
    vertex(x, y);
    vertex(x, y - (radius/3));
    vertex(x + (radius/4), y - frag3 - frag4);
    vertex(x + (radius/3), y + frag1 - frag2);
    endShape(CLOSE);

    fill(fillcol);
    beginShape();
    vertex(x, y);
    vertex(x + (radius/3), y + frag1 - frag2);
    vertex(x + (radius/4), y + frag3);
    endShape(CLOSE);

    fill(linecol, alpha);
    beginShape();
    vertex(x, y);
    vertex(x + (radius/4), y + frag3);
    vertex(x + (radius/5), y + frag2);
    vertex(x, y + (radius/3));
    vertex(x - (radius/3), y + frag1 - frag2);
    endShape(CLOSE);

  }

  void randomOrbit() {

    x += xmove;
    y += ymove;
    if (x > (width + radius)) { x = 0 - radius; }
    if (x < (0 - radius)) { x = width + radius; }
    if (y > (height + radius)) { y = 0 - radius; }
    if (y < (0 - radius)) { y = height + radius; }
    appear();
    displayTweet();

  }

  void displayTweet() {

    if (mouseX > x-(radius/2) && mouseX < x+(radius/2) && mouseY > y-(radius/2) && mouseY < y+(radius/2) && mousePressed) {
      x = mouseX;
      y = mouseY;
      fill(255);
      text(msg, mouseX + 30, mouseY, 200, 200);
      mouseReleased();

    }

  }

  void mouseReleased() {alpha = 80;}

}
class StarDust {

  float x, y;
  float xmove, ymove;
  float radius;
  float alpha, beta;

  Status status;

  StarDust() {
    x = random(width);
    y = random(height);
    radius = random(2, 4);
    alpha = random(255);
    beta = random(155);
    xmove = random(1.9) - 0.9;
    ymove = random(1.9) - 0.9;

  }

  void flipColor() {

      fill(random(255), random(255), random(255), beta);
      stroke(random(255), random(255), random(255), beta);

  }

  void swish() {

    flipColor();
    rect(x, y, radius, radius);

  }

  void move() {

    swish();
    x += xmove;
    y += ymove;
    if (x > (width + radius)) { x = 0 - radius; }
    if (x < (0 - radius)) { x = width + radius; }
    if (y > (height + radius)) { y = 0 - radius; }
    if (y < (0 - radius)) { y = height + radius; }
    squarespray(xmove);

  }

  void squarespray(float spray) {
    stroke(random(175, 255), random(255), 0, alpha);
    strokeWeight(random(7));
    point(x + random(radius), y + random(spray));
    point(y + sin(spray) * radius, x - spray);
    point(random(spray) - 60 + y, random(radius) + x - 30);
  }

}

-Sorry I didn't comment. This is a habit I'm still working on developing. However I don't believe anything is relevant after the main lines involving Twitter4j.

-In the code above "---" is a substitute for my keys.

-This is the code otherwise exactly as I've exported it from JavaScript mode and would like to run from my browser.

-I've run Processing sketches on my website before; this is the first involving Twitter4j.

回答1:

Your comment is correct: your sketch won't work under JavaScript mode, because you're using a Java library. As long as you depend on a Java library, your code will only work in Java mode. You might want to check out the JavaScript console for error messages.

To solve the issue, you could try to look for an equivalent JavaScript library and use that instead of twitter4j. Then your code would work in JavaScript mode. That's probably the correct thing to do.

The reason I say that is it's a huge pain to get Java applications to run in the browser. You'd have to create an applet, and then either sign the jar with a paid certificate, or have your users modify their Java security settings- and even then, your users will get a bunch of security warnings and prompts before they run your applet.

You're better off either deploying as a runnable jar or platform-specific executable, or switching entirely to JavaScript mode by finding an equivalent JavaScript library.