Problem changing position in hashmap with keyPressed '<' and '>'
in
Contributed Library Questions
•
2 years ago
Hi,
I have a sketch that collects tweets to a hashmap using Twitter4j. At the moment I have a very simple method setup that displays the tweet fom the hasmap to the screen as a string but I have the problem that it only displays the last tweet collected. What would be really great is if I could control the hashmap iterator with keypressed commands so that I can effectively scroll through the hashmap and have the updated string displayed for the user so they can explore the collected tweets.
So the code I have so far searches for and collects tweets to a hashmap and stores the last tweet in the hashmap to a string and displays it to the screen and what would be great is a method to press < to scroll back through the hashmap (thus updating the string displayed) and accordingly to be able to press > to scroll forwards through the hash.
Here is my code in full (apologies as it is quite long) with the important bits in bold. EDIT: here is a stripped down function from my program that includes the minimum number amount of code and libraries to run, I've attempted to integrate
amnon.owed's suggestions but I'm still stuck sadly.
Here is a link to the necessary library: http://twitter4j.org/en/index.html
import twitter4j.conf.*;
import twitter4j.internal.async.*;
import twitter4j.internal.org.json.*;
import twitter4j.internal.logging.*;
import twitter4j.http.*;
import twitter4j.api.*;
import twitter4j.util.*;
import twitter4j.internal.http.*;
import twitter4j.*;
int currentTweet;
String searchString;
String consumerKey = "---";
String consumerSecret = "---";
String accessToken = "---";
String accessTokenSecret = "---";
final int TIME_STEP = 1;
final int NUM_SEARCHES = 20;
final long DAY_DURATION = 1000*60*60*24;
Twitter twitter = new TwitterFactory().getInstance();
HashMap<Long,Tweet> tweets=new HashMap<Long,Tweet>();
public void setup(){
searchString = "News of the World";
searchTwitter(searchString);
twitter = new TwitterFactory().getOAuthAuthorizedInstance(consumerKey,consumerSecret, new AccessToken(accessToken,accessTokenSecret));
size(910,400);
}
public void searchTwitter(String searchQuery) {
twitter4j.Query query = new twitter4j.Query(searchQuery);
//twitter4j.Query.setGeoCode(new GeoLocation(52.30, 13.25), 1000.0, twitter4j.Query.KILOMETERS); // if we want to only get tweets from the region berlin
query.rpp(100);
Date referenceDate=new Date();
for(int i=0; i<NUM_SEARCHES; i++) {
String d=new SimpleDateFormat("yyyy-MM-dd").format(referenceDate);
//println("executing search for date: "+d);
query.until(d);
// execute search
try {
QueryResult result = twitter.search(query);
for (Tweet tweet : result.getTweets()) {
// first check if ID is unique?
if (tweets.get(tweet.getId())==null) {
// filter out tweets with GPS loc
GeoLocation loc=tweet.getGeoLocation();
if (loc!=null) {
tweets.put(tweet.getId(),tweet);
//println("adding tweet: "+tweet);
}
} else {
//println("skipping: "+tweet.getId());
}
}
}
catch(TwitterException e) {
println(e.getMessage());
}
referenceDate.setTime(referenceDate.getTime()-TIME_STEP*DAY_DURATION);
}
}
public void draw(){
background (0);
fill(242,242,242);
// text(tweets.toString(), 15, 15,220,220);
text((String)tweets.get(currentTweet), 15,15,220,220);
}
// void addTweet(String value) {
// int n = tweets.size();
// tweets.put(n, value);
// }
void keyPressed() {
if (key == ',') {
if (currentTweet>0) {
currentTweet--;
}
}
else if (key == '.') {
if (currentTweet<tweets.size()-1) {
currentTweet++;
}
}
}
EDIT: Here is my program in full, sorry that it is so long..
import processing.core.*;
import processing.xml.*;
//import javax.media.opengl.*;
//import processing.opengl.*;
import controlP5.*;
import peasy.org.apache.commons.math.*;
import peasy.*;
import peasy.org.apache.commons.math.geometry.*;
import twitter4j.conf.*;
import twitter4j.internal.async.*;
import twitter4j.internal.org.json.*;
import twitter4j.internal.logging.*;
import twitter4j.http.*;
import twitter4j.api.*;
import twitter4j.util.*;
import twitter4j.internal.http.*;
import twitter4j.*;
import toxi.geom.*;
import toxi.processing.*;
import peasy.*;
import java.applet.*;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.event.MouseEvent;
import java.awt.event.KeyEvent;
import java.awt.event.FocusEvent;
import java.awt.Image;
import java.io.*;
import java.net.*;
import java.text.*;
import java.util.*;
import java.util.zip.*;
import java.util.regex.*;
import twitter4j.internal.util.*;
import twitter4j.api.*;
import toxi.geom.mesh.*;
import peasy.org.apache.commons.math.geometry.*;
import twitter4j.util.*;
import peasy.org.apache.commons.math.*;
import twitter4j.*;
import toxi.geom.mesh2d.*;
import peasy.*;
import twitter4j.internal.org.json.*;
import twitter4j.internal.logging.*;
import toxi.util.datatypes.*;
import toxi.math.waves.*;
import toxi.geom.mesh.subdiv.*;
import toxi.geom.*;
import toxi.util.events.*;
import processing.xml.*;
import processing.core.*;
import twitter4j.conf.*;
import twitter4j.internal.async.*;
import peasy.test.*;
import toxi.math.conversion.*;
import twitter4j.internal.http.*;
import toxi.math.noise.*;
import toxi.processing.*;
import toxi.util.*;
import twitter4j.http.*;
import controlP5.*;
//import processing.opengl.*;
import toxi.math.*;
import java.applet.*;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.event.MouseEvent;
import java.awt.event.KeyEvent;
import java.awt.event.FocusEvent;
import java.awt.Image;
import java.io.*;
import java.net.*;
import java.text.*;
import java.util.*;
import java.util.zip.*;
import java.util.regex.*;
public class TwitterExp extends PApplet {
boolean a = true;
boolean button = false;
boolean buttona = false;
int x = 750;
int y = 106;
int w = 20;
int h = 20;
int xa = 750;
int ya = 50;
int wa = 20;
int ha = 20;
PImage bg, texmap;
PFont font;
int sDetail = 55; //Sphere detail
float[] cx, cz, sphereX, sphereY, sphereZ;
float sinLUT[], cosLUT[], sincos_precision = 0.5f;
int sincos_length = PApplet.parseInt(360.0f / sincos_precision);
float r = 600;
// r = earth radius in px. 6371 is earth radius in km.
float pxToKm = 6371.0f / r;
int inRange;
String searchString;
String searchState = "";
String consumerKey = "---";
String consumerSecret = "---";
String accessToken = "---";
String accessTokenSecret = "---";
PeasyCam cam;
PeasyDragHandler PanDragHandler;
PFont imhelix;
ControlP5 controlP5;
PMatrix3D currCameraMatrix;
//final String SEARCH_QUERY="hello";
final int TIME_STEP = 1;
final int NUM_SEARCHES = 20;
final long DAY_DURATION = 1000*60*60*24;
Twitter twitter = new TwitterFactory().getInstance();
Map<Long, Tweet> tweets = new LinkedHashMap<Long, Tweet>();
ListIterator<Tweet> iterator;
Tweet currentTweet;
ToxiclibsSupport gfx;
SimpleThread thread1;
public void setup(){
searchString = "";
imageMode(CENTER);
ArrayList<Tweet> messages = new ArrayList<Tweet>(tweets.values());
iterator = messages.listIterator();
controlP5 = new ControlP5(this);
cam = new PeasyCam(this, 1500);
cam.setMinimumDistance(750);
cam.setMaximumDistance(2000);
cam.rotateZ(-HALF_PI);
cam.rotateZ(-HALF_PI);
cam.rotateY(HALF_PI);
cam.rotateY(HALF_PI);
cam.rotateX(QUARTER_PI);
cam.setResetOnDoubleClick(false);
cam.setCenterDragHandler(null);
bezierDetail(30);
font = createFont("Verdana", 13);
textFont(font);
twitter = new TwitterFactory().getOAuthAuthorizedInstance(consumerKey,consumerSecret, new AccessToken(accessToken,accessTokenSecret));
size(910,400,P3D);
//hint(DISABLE_OPENGL_ERROR_REPORT);
frameRate(30);
rectMode(CENTER);
texmap = loadImage("Earthc.jpg");
initializeSphere(sDetail);
gfx=new ToxiclibsSupport(this);
//searchTwitter(SEARCH_QUERY);
thread1 = new SimpleThread(1000,"a");
thread1.start();
controlP5 = new ControlP5(this);
}
public void hud(PeasyCam cam)
{
cam.beginHUD();
pushMatrix();
translate(100, height-120, 0);
// fill(255, 200);
noStroke();
fill(242,242,242);
float tw = textWidth(searchString);
fill(210,210,210);
noStroke();
// rect(-90,107,tw+10,20);
//fill (175);
// rect (x, y, w, h);
fill(242,242,242);
// text(tweets.toString(), 120, 120,220,220);
if (currentTweet != null) {
text(currentTweet.toString(), 120,120,220,220);
}
fill(242,242,242);
text(searchString, 10, 390);
text("Controls:", 736, 20);
text("1 = Geographic Map", 736, 37);
text("2 = Population Map", 736, 50);
text("3 = Economic Map", 736, 63);
text("Enter = Search", 736, 80);
text("Delete = Clear Search", 736, 93);
text("Backspace = Delete", 736, 106);
text("Mouse + Drag = Navigate", 736, 119);
text("MouseWheel = Zoom", 736, 132);
stroke(242,242,242);
if(second()%2 == 0)
line(tw+-82, 110, tw+-87, 110);
popMatrix();
cam.endHUD();
}
public void searchTwitter(String searchQuery) {
twitter4j.Query query = new twitter4j.Query(searchQuery);
//twitter4j.Query.setGeoCode(new GeoLocation(52.30, 13.25), 1000.0, twitter4j.Query.KILOMETERS); // if we want to only get tweets from the region berlin
query.rpp(100);
Date referenceDate=new Date();
for(int i=0; i<NUM_SEARCHES; i++) {
String d=new SimpleDateFormat("yyyy-MM-dd").format(referenceDate);
//println("executing search for date: "+d);
query.until(d);
// execute search
try {
QueryResult result = twitter.search(query);
for (Tweet tweet : result.getTweets()) {
// first check if ID is unique?
if (tweets.get(tweet.getId())==null) {
// filter out tweets with GPS loc
GeoLocation loc=tweet.getGeoLocation();
if (loc!=null) {
tweets.put(tweet.getId(),tweet);
//println("adding tweet: "+tweet);
}
} else {
//println("skipping: "+tweet.getId());
}
}
}
catch(TwitterException e) {
println(e.getMessage());
}
referenceDate.setTime(referenceDate.getTime()-TIME_STEP*DAY_DURATION);
}
}
public void draw() {
directionalLight(255, 255, 255, 0, -1, 0);
//lights();
ambientLight(255, 255, 255);
translate(80, 50, 0);
float fov = PI/3.0f;
float cameraZ = (height/2.0f) / tan(fov/2.0f);
perspective(fov, PApplet.parseFloat(width)/PApplet.parseFloat(height),
cameraZ/40.0f, cameraZ*40.0f);
inRange = 0;
background(25,25,25);
renderGlobe();
stroke(255);
//gfx.origin(300);
//searchTwitter(SEARCH_QUERY);
int a = thread1.getCount();
// iterate over all collected tweets
for(Tweet tweet : tweets.values()) {
GeoLocation loc=tweet.getGeoLocation();
// convert geo location into cartesian world coordinates
Vec3D p=new Vec3D(600,radians((float)loc.getLongitude())-HALF_PI,radians((float)loc.getLatitude())).toCartesian();
// create a box at the computed position
AABB box=new AABB(p,2);
noStroke();
fill(255,120,0);
// draw box at position
gfx.box(box);
// text(tweets,15,15);
fill(255);
}
textMode(SCREEN);
hud(cam);
controlP5.draw();
}
class SimpleThread extends Thread {
boolean running; // Is the thread running? Yes or no?
int wait; // How many milliseconds should we wait in between executions?
String id; // Thread name
int count; // counter
boolean doSearch = false; // search trigger
public boolean getRunning(){
return running;
}
// Constructor, create the thread
// It is not running by default
SimpleThread (int w, String s) {
wait = w;
running = false;
id = s;
count = 0;
}
public void start () {
// Set running equal to true
running = true;
// Print messages
println("Starting thread (will execute every " + wait + " milliseconds.)");
// Do whatever start does in Thread, don't forget this!
super.start();
}
// We must implement run, this gets triggered by start()
public void run () {
while (running) {
if (doSearch) {
searchTwitter(searchString);
println("Search for " + searchString + " done");
doSearch = false;
}
// println(id + ": " + count);
count++;
// Ok, let's wait for however long we should wait
// try {
// } catch (Exception e) {
// }
}
System.out.println(id + ": thread is done!"); // The thread is done when we get to the end of run()
}
public void search() {
doSearch = true;
}
public int getCount() {
return count;
}
public void quit() {
System.out.println("Quitting.");
running = false; // Setting running to false ends the loop in run()
// IUn case the thread is waiting. . .
interrupt();
}
}
public void keyPressed() {
if (key == CODED && keyCode == LEFT && iterator.hasPrevious()) {
currentTweet = iterator.previous();
}
else if (key == CODED && keyCode == RIGHT && iterator.hasNext()) {
currentTweet = iterator.next();
}
if(((key>='A')&&(key<='Z')) || ((key>='a')&&(key<='z')) || (key==' ')){
searchString += key;
}
if(key == DELETE){
tweets.clear();
}
if(key == '1'){
texmap = loadImage("Earthc.jpg");
}
if(key == '2'){
texmap = loadImage("Earthd.jpg");
}
if(key == '3'){
texmap = loadImage("world32kc.jpg");
}
else if(key == ENTER){thread1.search();
}
if(key == BACKSPACE){
if(searchString.length()>0)
searchString = searchString.substring(0,searchString.length()-1);
}
}
public void renderGlobe()
{
pushMatrix();
translate(0,0,0);
fill(255);
stroke(0);
//sphere(r);
noFill();
pushMatrix();
rotateY(radians(-90));
rotateZ(radians(180));
noStroke();
textureMode(IMAGE);
texturedSphere(r, texmap);
popMatrix();
popMatrix();
}
// Converts 3D cartesian coordinates to polar coordinates
//
// theVector : vector to convert
// returns : vector containing 'length', 'angleY' and 'angleZ',
// so that rotating a point (length, 0, 0) first
// around the y-axis with angleY and then around the
// z-axis with angleZ results again in point (x, y, z)
public PVector cartesianToPolar(PVector theVector) {
PVector res = new PVector();
res.x = theVector.mag();
if (res.x > 0) {
res.y = -atan2(theVector.z, theVector.x);
res.z = asin(theVector.y / res.x);
}
else {
res.y = 0;
res.z = 0;
}
return res;
}
class Satellite {
float lat, lng, x, y, z, elevation;
String[] positions;
int id;
Satellite(int id, float _lat, float _lng, float _elevation) {
this.id = id;
elevation = _elevation;
lat = radians(_lat);
lng = radians(90f-_lng);
positions = new String[0];
}
public void display() {
lat += .001f;
//lng += .008;
pushMatrix();
translate(x, y, z);
fill(255);
stroke(0);
box(20);
float[] rotations = cam.getRotations();
rotateX(rotations[0]);
rotateY(rotations[1]);
rotateZ(rotations[2]);
text("Satellite #" + id + " " + lat + " " + lng, 20, 0);
fill(255);
popMatrix();
}
}
class locationOnGlobe {
float lat, lng, x, y, z;
locationOnGlobe(float _lat, float _lng) {
lat = radians(_lat);
lng = radians(90f-_lng);
}
public void display() {
lng += random(0.001f, 0.0005f);
pushMatrix();
translate(x, y, z);
fill(255, 0, 0);
noStroke();
sphere(10);
popMatrix();
update();
}
public void update() {
x = r*cos(lat)*cos(lng);
y = r*cos(lat)*sin(lng);
z = r*sin(lat);
}
}
public void initializeSphere(int res)
{
sinLUT = new float[sincos_length];
cosLUT = new float[sincos_length];
for (int i = 0; i < sincos_length; i++) {
sinLUT[i] = (float) Math.sin(i * DEG_TO_RAD * sincos_precision);
cosLUT[i] = (float) Math.cos(i * DEG_TO_RAD * sincos_precision);
}
float delta = (float)sincos_length/res;
float[] cx = new float[res];
float[] cz = new float[res];
// Calc unit circle in XZ plane
for (int i = 0; i < res; i++) {
cx[i] = -cosLUT[(int) (i*delta) % sincos_length];
cz[i] = sinLUT[(int) (i*delta) % sincos_length];
}
// Computing vertexlist vertexlist starts at south pole
int vertCount = res * (res-1) + 2;
int currVert = 0;
// Re-init arrays to store vertices
sphereX = new float[vertCount];
sphereY = new float[vertCount];
sphereZ = new float[vertCount];
float angle_step = (sincos_length*0.5f)/res;
float angle = angle_step;
// Step along Y axis
for (int i = 1; i < res; i++) {
float curradius = sinLUT[(int) angle % sincos_length];
float currY = -cosLUT[(int) angle % sincos_length];
for (int j = 0; j < res; j++) {
sphereX[currVert] = cx[j] * curradius;
sphereY[currVert] = currY;
sphereZ[currVert++] = cz[j] * curradius;
}
angle += angle_step;
}
sDetail = res;
}
public void texturedSphere(float r, PImage t)
{
int v1,v11,v2;
beginShape(TRIANGLE_STRIP);
texture(t);
float iu=(float)(t.width-1)/(sDetail);
float iv=(float)(t.height-1)/(sDetail);
float u=0,v=iv;
for (int i = 0; i < sDetail; i++) {
vertex(0, -r, 0,u,0);
vertex(sphereX[i]*r, sphereY[i]*r, sphereZ[i]*r, u, v);
u+=iu;
}
vertex(0, -r, 0,u,0);
vertex(sphereX[0]*r, sphereY[0]*r, sphereZ[0]*r, u, v);
endShape();
// Middle rings
int voff = 0;
for(int i = 2; i < sDetail; i++) {
v1=v11=voff;
voff += sDetail;
v2=voff;
u=0;
beginShape(TRIANGLE_STRIP);
texture(t);
for (int j = 0; j < sDetail; j++) {
vertex(sphereX[v1]*r, sphereY[v1]*r, sphereZ[v1++]*r, u, v);
vertex(sphereX[v2]*r, sphereY[v2]*r, sphereZ[v2++]*r, u, v+iv);
u+=iu;
}
// Close each ring
v1=v11;
v2=voff;
vertex(sphereX[v1]*r, sphereY[v1]*r, sphereZ[v1]*r, u, v);
vertex(sphereX[v2]*r, sphereY[v2]*r, sphereZ[v2]*r, u, v+iv);
endShape();
v+=iv;
}
u=0;
// Add the northern cap
beginShape(TRIANGLE_STRIP);
texture(t);
for (int i = 0; i < sDetail; i++) {
v2 = voff + i;
vertex(sphereX[v2]*r, sphereY[v2]*r, sphereZ[v2]*r, u, v);
vertex(0, r, 0,u,v+iv);
u+=iu;
}
//vertex(0, r, 0,u, v+iv);
vertex(sphereX[voff]*r, sphereY[voff]*r, sphereZ[voff]*r, u, v);
endShape();
}
static public void main(String args[]) {
PApplet.main(new String[] { "--bgcolor=#c0c0c0", "TwitterExp" });
}
}
Many thanks for your help.
- Tom
1