I'm currently playing around with Java, JForms, and the Twitter4j library. Trying to create a way to populate a vector with tweetID's in order to perform actions on them (Retweets, Favorites, replies, etc.). I'm having a bit of a problem with either:
A. Not being able to add to the vector, or
B. Not being able to read from it.
Based on what I've seen from the logger output, I'm positive I'm not adding to the array correctly. Could somebody take a look with me and see what's going on?
main.java (The code to add to the vector with the tweet ID.)
private void btn_refreshTimelineActionPerformed(java.awt.event.ActionEvent evt) {
TwitterUtilities tu = new TwitterUtilities();
Twitter twitter = tu.getConnect();
// Gets tweet information.
List<Status> statuses = null;
try {
statuses = twitter.getHomeTimeline();
} catch (TwitterException ex) {
Logger.getLogger(main.class.getName()).log(Level.SEVERE, null, ex);
}
// Init table.
DefaultTableModel model = (DefaultTableModel) tbl_tweets.getModel();
// Clear table.
model.setRowCount(0);
// Populate table.
for (Status status : statuses)
{
tu.setTargetID(status.getId());
Vector row = new Vector();
row.add(status.getUser().getName());
row.add(status.getText());
model.addRow(row);
}
}
main.java (The part where getTargetTweetID is invoked.)
private void btn_favoriteActionPerformed(java.awt.event.ActionEvent evt) {
TwitterUtilities tu = new TwitterUtilities();
Twitter twitter = tu.getConnect();
int targetIndex = tbl_tweets.getSelectedRow();
long tweetID = tu.getTargetTweetID(targetIndex);
try {
twitter.createFavorite(tweetID);
} catch (TwitterException ex) {
Logger.getLogger(main.class.getName()).log(Level.SEVERE, null, ex);
}
}
TwitterUtilities.java
public class TwitterUtilities {
public Vector tweetIDVector;
// Other stuff... but here's the important stuff.
public void setTargetID(long targetStatus)
{
this.tweetIDVector.addElement(targetStatus);
}
public long getTargetTweetID(int targetIndex)
{
// Get tweet ID for the selected tweet.
Object targetTweetID = this.tweetIDVector.get(targetIndex);
return (long) targetTweetID;
}
}
The error message that I'm getting upon runtime:
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 1
Any help would be greatly appreciated!
EDIT: After working with the suggestions, I've now updated the following code to this new setup:
TwitterUtilities.java
public class TwitterUtilities {
public Vector tweetIDVector = new Vector<>();
// More fun stuff...
public void setTargetID(long targetStatus)
{
this.tweetIDVector.addElement(targetStatus);
for (int i = 0; i <= tweetIDVector.size(); i++)
{
System.out.println(tweetIDVector.get(i));
}
}
And so now the following happens on run:
838641565769871360
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 1
EDIT 2: Changed the Vector into a List. Loading the Tweet ID's is working. Also changed the <= in the for loop to <. Now it is loading everything the way it's supposed to. Still having issues with getting data from the List in the getTargetTweetID.
Related
I have been wondering if there is a way to access all the twitter followers list.
We have tried using call to the REST API via twitter4j:
public List<User> getFriendList() {
List<User> friendList = null;
try {
friendList = mTwitter.getFollowersList(mTwitter.getId(), -1);
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (TwitterException e) {
e.printStackTrace();
}
return friendList;
}
But it returns only a list of 20 followers.
I tried using the same call in loop, but it cause a rate limit exception - says we are not allowed to make too many requests in a small interval of time.
Do we have a way around this?
You should definitely use getFollowersIDs. As the documentation says, this returns an array (list) of IDs objects. Note that it causes the list to be broken into pages of around 5000 IDs at a time. To begin paging provide a value of -1 as the cursor. The response from the API will include a previous_cursor and next_cursor to allow paging back and forth.
The tricky part is to handle the cursor. If you can do this, then you will not have the problem of getting only 20 followers.
The first call to getFollowersIDs will need to be given a cursor of -1. For subsequent calls, you need to update the cursor value, by getting the next cursor, as done in the while part of the loop.
long cursor =-1L;
IDs ids;
do {
ids = twitter.getFollowersIDs(cursor);
for(long userID : ids.getIDs()){
friendList.add(userID);
}
} while((cursor = ids.getNextCursor())!=0 );
Here is a very good reference:
https://github.com/yusuke/twitter4j/blob/master/twitter4j-examples/src/main/java/twitter4j/examples/friendsandfollowers/GetFriendsIDs.java
Now, if the user has more than around 75000 followers, you will have to do some waiting (see Vishal's answer).
The first 15 calls will yield you around 75000 IDs. Then you will have to sleep for 15 minutes. Then make another 15 calls, and so on till you get all the followers. This can be done using a simple Thread.sleep(time_in_milliseconds) outside the for loop.
Just Change like this and try, this is working for me
try {
Log.i("act twitter...........", "ModifiedCustomTabBarActivity.class");
// final JSONArray twitterFriendsIDsJsonArray = new JSONArray();
IDs ids = mTwitter.mTwitter.getFriendsIDs(-1);// ids
// for (long id : ids.getIDs()) {
do {
for (long id : ids.getIDs()) {
String ID = "followers ID #" + id;
String[] firstname = ID.split("#");
String first_Name = firstname[0];
String Id = firstname[1];
Log.i("split...........", first_Name + Id);
String Name = mTwitter.mTwitter.showUser(id).getName();
String screenname = mTwitter.mTwitter.showUser(id).getScreenName();
// Log.i("id.......", "followers ID #" + id);
// Log.i("Name..", mTwitter.mTwitter.showUser(id).getName());
// Log.i("Screen_Name...", mTwitter.mTwitter.showUser(id).getScreenName());
// Log.i("image...", mTwitter.mTwitter.showUser(id).getProfileImageURL());
}
} while (ids.hasNext());
} catch (Exception e) {
e.printStackTrace();
}
Try This...
ConfigurationBuilder confbuilder = new ConfigurationBuilder();
confbuilder.setOAuthAccessToken(accessToken)
.setOAuthAccessTokenSecret(secretToken)
.setOAuthConsumerKey(TwitterOAuthActivity.CONSUMER_KEY)
.setOAuthConsumerSecret(TwitterOAuthActivity.CONSUMER_SECRET);
Twitter twitter = new TwitterFactory(confbuilder.build()).getInstance();
PagableResponseList<User> followersList;
ArrayList<String> list = new ArrayList<String>();
try
{
followersList = twitter.getFollowersList(screenName, cursor);
for (int i = 0; i < followersList.size(); i++)
{
User user = followersList.get(i);
String name = user.getName();
list.add(name);
System.out.println("Name" + i + ":" + name);
}
listView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1 , list));
listView.setVisibility(View.VISIBLE);
friend_list.setVisibility(View.INVISIBLE);
post_feeds.setVisibility(View.INVISIBLE);
twit.setVisibility(View.INVISIBLE);
}
This is a tricky one.
You should specify whether you're using application or per user tokens and the number of users you're fetching followers_ids for.
You get just 15 calls per 15 minutes in case of an application token. You can fetch a maximum of 5000 followers_ids per call. That gives you a maximum of 75K followers_ids per 15 minutes.
If any of the users you're fetching followers_ids for has over 75K followers, you'll get the rate_limit error immediately. If you're fetching for more than 1 user, you'll need to build strong rate_limit handling in your code with sleeps and be very patient.
The same applies for friends_ids.
I've not had to deal with fetching more than 75K followers/friends for a given user but come to think of it, I don't know if it's even possible anymore.
I'm working in a project with DB. There are a method that collect info from the DB and set the info in ArrayList:
public ArrayList<Director> listAll(){
ArrayList<Director>list = new ArrayList<Director>();
Director direc = new Director();
int cont=0;
String sql = "select * from director;";
try{
ResultSet res = objBBDD.sentencia.executeQuery(sql);
while(res.next()){
direc.setCode(res.getInt("CODE"));
direc.setName(res.getString("NAME"));
direc.setNationality(res.getString("NATIONALITY"));
direc.setOscar(res.getInt("OSCAR"));
list.add(direc);
// THIS IS USE TO CONFIRM IF IT WORKS ///////////////////////////////////////
// JOptionPane.showMessageDialog(null,"Code:"+list.get(cont).getCode()+"Nombre"+list.get(cont).getName());
// cont++;
}
}catch (SQLException e) {
e.printStackTrace();
}
return list;
}
I use JOptionPane.showMessageDialog to see if I get info from DB and is added correctly to de ArrayList, and it's works.
Now the ArrayList back the invoker class, this is the method:
private void stackArray(){
ArrayList<Director>arrayDir = new ArrayList<Director> ();
ArrayList<Director>arrayDir = conexion.listAll();
// JOptionPane.showMessageDialog(null,"Code:"+arrayDir.get(0).getCode()+"Name"+arrayDir.get(0).getName());
// JOptionPane.showMessageDialog(null,"Code:"+arrayDir.get(1).getCode()+"Name"+arrayDir.get(1).getName());
// JOptionPane.showMessageDialog(null,"Code:"+arrayDir.get(2).getCode()+"Name"+arrayDir.get(2).getName());
}
Again I use the JOptionPane.showMesageDialog to show the first three positions, but it's not work, the problem, as far as I've seen, is all the positions have the same object saved (exactly the last).
Summarizing the ArrayList have the same object (last in DB), there are no problems at run or compile.
I don't know if I write something bad, or just a noob fail.
the problem, as far as I've seen, is all the positions have the same
object saved (exactly the last).
You are changing value of same instance Director. Thats why, you seen the last value of Director object. You should create new instance of Director with iteration of while loop.
ResultSet res = objBBDD.sentencia.executeQuery(sql);
while(res.next){
Director direc = new Director();// Declare Director instance here.
.....
list.add(direc);
}
I'm trying to create a list structure for a simple message board usinsg lists of topics, which are themselves lists of messages, with my own implementation of binodes. However I'm getting a null pointer exception when I'm trying to add a post to my topic.
Exception in thread "main" java.lang.NullPointerException
at TopicList.remove(TopicList.java:110)
at TopicList.addPost(TopicList.java:80)
at TestHarness.main(TestHarness.java:13)
My code is as follows:
TestHarness.main
TopicList list = new TopicList();
list.addTop(new Message("user1", "post1"), "Topic 0");
list.addTop(new Message("user2", "post2"), "Topic 1");
list.addPost(new Message("user3", "post3"), 0);
System.out.println(list);
TopicList.addPost()
public void addPost(Message m, int id){
Topic t;
t = (Topic) getTopicNode(id).head();
this.remove(getTopicNode(id)); //This is line 80 in my code
t.addMessage(m);
topiclist = new Node(t, topiclist);
}
TopicList.remove()
private void remove(Node n){
if (n.tail().equals(null)){ // this is line 110
n.prev().nullTail();
}
else{
n.prev().join(n.tail());
}
}
Thanks for helping.
if n.tail() is null, the following line will throw NPE:
if (n.tail().equals(null)){
You need to check:
if (n.tail() == null){
instead.
I am getting an array from parse.com. I am using an array, to retrieve an array:
fightList.whereContainedIn("objectId", itemListCard);
fightList.findInBackground(new FindCallback<ParseObject>() ....
My first array; itemListCard is in a specific order. After I findInBackground, my array from online, (objectId), is completely out of order. This is because I am getting it from Parse.com, so it is added to the array as it is retrieved. I need to:
1. Re-order array objectId to match itemListCard or
2. Retrieve objectId in order of itemListCard
Java code:
HomeItemList = new ArrayList<HomeItem>();
fightList.whereContainedIn("objectId", itemListCard);
fightList.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> objectId, ParseException e) {
if (e == null) {
for (int i = 0; i < objectId.size(); i = i + 2) {
HomeItem homeItem = new HomeItem();
homeItem.setHomeItemID(k);
k++;
//set Red Array
homeItem.setHomeItemRedName(objectId.get(i).getString("Name"));
homeItem.setHomeItemRedAge(objectId.get(i).getString("Age"));
homeItem.setHomeItemRedRecord(objectId.get(i).getString("Record"));
homeItem.setHomeItemRedHeight(objectId.get(i).getString("Height"));
homeItem.setHomeItemRedWeight(objectId.get(i).getString("Weight"));
homeItem.setHomeItemRedCity(objectId.get(i).getString("Location"));
homeItem.setHomeItemRedExp(objectId.get(i).getString("Experience"));
//set blue Array
homeItem.setHomeItemBlueName(objectId.get(i+1).getString("Name"));
homeItem.setHomeItemBlueAge(objectId.get(i+1).getString("Age"));
homeItem.setHomeItemBlueRecord(objectId.get(i+1).getString("Record"));
homeItem.setHomeItemBlueHeight(objectId.get(i+1).getString("Height"));
homeItem.setHomeItemBlueWeight(objectId.get(i+1).getString("Weight"));
homeItem.setHomeItemBlueCity(objectId.get(i+1).getString("Location"));
homeItem.setHomeItemBlueExp(objectId.get(i+1).getString("Experience"));
HomeItemList.add(homeItem);
}
HomeListAdapter = new HomeListAdapter(getApplicationContext(), 0, HomeItemList);
adapter.addSection(" Fight Card ", HomeListAdapter);
} else {
progressDialog.dismiss();
Log.d("Display Card", "Error parsing Card");
Log.d("Card Error:", e.getMessage());
Toast.makeText(databaseFightCard.this, "Could not retrieve parse info. Try again later", Toast.LENGTH_LONG).show();
}
listView.setAdapter(adapter);
progressDialog.dismiss();
}
});
Note
The for loop is counting by 2 because this is the structure I am going for:
objectId[0] vs objectId[1]
objectId[2] vs objectId[3]
objectId[4] vs objectId[5]
objectId[6] vs objectId[7]
....and so on
Hence the need for a specific order.
You can control the order in which the items are returned using orderByAscending() and orderByDescending().
In your case:
fightList.whereContainedIn("objectId", itemListCard);
fightList.orderByAscending("objectId");
fightList.findInBackground(new FindCallback<ParseObject>() ....
See Query Constraints section of the the Parse Android Guide.
Hope your problem is resolved, but my problem is still there
and I thought that you can help me to get out of this problem.
actually I had multiple events to publish one by one as per user
selection for eg: user select Season, Service, DateFrom and
DateTo and then clicks on the refresh button.
When the refresh button is clicked I had used the above logic to
get all the datas using the below mentioned code
public void onClick$ref(Event event){
if(lbox_service.getSelectedIndex() != 0 || lbox_season.getSelectedIndex() != 0)
{
if(lbox_service.getSelectedIndex() == 0)
{
setService_id("0");
}
else
{
setService_id(lbox_service.getSelectedItem().getValue().toString());
}
if(lbox_season.getSelectedIndex() == 0)
{
setSeason_id("0");
}
else
{
setSeason_id(lbox_season.getSelectedItem().getValue().toString());
}
System.out.println("Service Index 11 : "+ lbox_service.getSelectedIndex());
System.out.println("Season Index 11 : "+ lbox_season.getSelectedIndex());
EventQueue evtQ = EventQueues.lookup("myEventQueue", EventQueues.APPLICATION, true);
//evtQ.publish(new Event("service_id", self, lbox_service.getSelectedItem().getValue().toString()));
//evtQ.publish(new Event("season_id", self, lbox_season.getSelectedItem().getValue().toString()));
evtQ.publish(new Event("service_id", self, getService_id()));
evtQ.publish(new Event("season_id", self, getSeason_id()));
//evtQ.publish(new Event("onClickRef", null, lbox_service.getSelectedItem().getValue().toString()));
//evtQ.publish(new Event("onClickRef", null, lbox_season.getSelectedItem().getValue().toString()));
/*.publish(new Event("onClickRef", null, lbox_service.getSelectedItem().getValue().toString()));
EventQueues.lookup("myEventQu", EventQueues.DESKTOP, true).publish(new Event(
"onClickRef", null, lbox_season.getSelectedItem().getValue().toString()));*/
}
else
{
setService_id("0");
setSeason_id("0");
EventQueue evtQ = EventQueues.lookup("myEventQueue", EventQueues.APPLICATION, true);
evtQ.publish(new Event("service_id", self, getService_id()));
evtQ.publish(new Event("season_id", self, getSeason_id()));
System.out.println("Service Index : "+ lbox_service.getSelectedIndex());
System.out.println("Season Index : "+ lbox_season.getSelectedIndex());
}
}
now i had publish all my value and after that my new Controller
run that will subscribe those published values. using the
below code
public void doAfterCompose(Component comp) throws Exception {
super.doAfterCompose(comp);
EventQueues.lookup("myEventQueue", EventQueues.APPLICATION, true).subscribe(new EventListener() {
public void onEvent(Event event) throws Exception {
/*String service = (String) event.getData();
logger.info("Servive $$$$$$$$$ " + service);
//String season = (String) event.getData();
//logger.info("Season $$$$$$$$$ " + season); */
if("service_id".equals(event.getName())) {
setService_id((String) event.getData());
baseController.setFilter_bar(true);
System.out.println("Service Id :" +event.getData());
}
else if("season_id".equals(event.getName())) {
setSeason_id((String) event.getData());
baseController.setFilter_bar(true);
System.out.println("Season Id :" +event.getData());
}
/*setService_id((String) event.getData());
setSeason_id((String) event.getData());*/
/*if("season_id".equals(event.getName())){
setSeason_id((String) event.getData());
}else
{
setSeason_id("0");
}*/
System.out.println("Filter bar :" +baseController.isFilter_bar());
if(baseController.isFilter_bar() == true)
{
String dateFrom = "";
String dateTo = "";
String order = "2";
List TDRetailers = verificationStoreHibernateDao.getTraditionalRetailers(
getService_id(), getSeason_id(), dateFrom, dateTo, order);
//VerificationStoreHibernateDao storeHibernateDao = new VerificationStoreHibernateDao();
//List TDRetailers = this.verificationStoreHibernateDao.getTraditionalRetailers(service_id);
//ListModel listModel = this.retailers.getModel();
ListModelList listModelList = (ListModelList) retailer.getModel();
listModelList.clear();
listModelList.addAll(TDRetailers);
baseController.setFilter_bar(true);
}
}
});
}
but actully my problem is with running the query and with
getting those published values. Based on them I will be able to
run my Traditional getTraditionalRetailers queries.
My problem is
how to publish multiple events values. Is it the right way
that I had done.
as I had done separate publish, everytime
I publish new value The query runs, the result is that i had
mutiple time query execution. for example If i will publish two
values the queries run's for the two times and if I publish
three values the query executes for three time.
I don't know what is their problem. Help me to solve my error.
The event object passed through EventQueue is where you put your payload there. You can just define an aggregate Event class and collect information and publish them in a whole.
If you can publish all information in a whole(using an aggregate Event), this is solved automatically.