Twitter ListView Sample(JDK8,Twitter4j)

This is a very simple sample application just searching for twitter which match a word.
This code shows you following functions
1. How to customize the content of a ListView (see code1-1,1-2)
2. Searching for twitter by using Task class on background thread and Twitter4j(code2-1,2-2,2-3)
3. How to use Lambda expressions.(code1-2,2-1,2-2)
(For more details, see this site Lambda Expressions (The Java™ Tutorials > Learning the Java Language > Classes and Objects), Method References (The Java™ Tutorials > Learning the Java Language > Classes and Objects))


  • Figure1(The sample application screen)


  • code1-1(TwitterInfoCell.java)

If you customize the content of ListView, create a class extends ListCell and set the specific Node by using setGraphic method.
Like the following implementation in TwitterInfoCell

public class TwitterInfoCell extends ListCell<TwitterInfo>{
    @Override
    protected void updateItem(TwitterInfo t, boolean bln) {
        if (t != null){
            setGraphic(getTwitterInfoCell(t));  // ***set the content of the graphic
        }
    }
    private Node getTwitterInfoCell(TwitterInfo info) {
        HBox node = new HBox();
        node.setSpacing(10);
        Image image = new Image(info.getImageURL(), 48, 48, true, false);
        ImageView imageView = new ImageView(image);
        Text name = new Text(info.getName());
        name.setWrappingWidth(450);
        Text text = new Text(info.getText());
        text.setWrappingWidth(450);
        VBox vbox = new VBox();
        vbox.getChildren().addAll(name, text);
        node.getChildren().addAll(imageView, vbox);
        return node;
    }
}
  • code1-2(TwitterListViewSample.java)

You need to call the setCellFactory method to redefine the implementation of the ListView

...
        listView.setCellFactory(p -> new TwitterInfoCell());   // *** Lambda expression for CallBack Interface
...
  • code2-1(TwitterSearchTask.java)

It is very easy to use the Twitter4j to get twitter which matches the word. Just use TwitterStream FilterQuery and StatusAdapter.
You can get the information about Twitter4j here Twitter4J - A Java library for the Twitter API
Java SE8 provides some useful Functional Interface, like Consumer Interface in following code

public class TwitterSearchTask extends Task<Void>{
    private String searchText;
    private ObservableList<TwitterInfo> list;
    private TwitterStream stream;

    public TwitterSearchTask(String searchText, ObservableList<TwitterInfo> list) {
        this.searchText = searchText;
        this.list = list;
    }

    @Override
    protected Void call() throws Exception {
        updateMessage("searching tweet ...");
        FilterQuery query = new FilterQuery();
        query.track(new String[]{searchText});  // set the search word
        stream = new TwitterStreamFactory(getTwitterConf()).getInstance();
        addListener(p -> list.add(0, new TwitterInfo(p)));   // *** Lambda expression for onStatus method
        stream.filter(query);
        return null;
    }

    private void addListener(Consumer<Status> consumer){  // *** Functional Interface
        stream.addListener(
        new StatusAdapter(){
            @Override
            public void onStatus(Status status){
               consumer.accept(status);    // *** here
            }
        });
    }
    private Configuration getTwitterConf() {
        ConfigurationBuilder builder = new ConfigurationBuilder();
        builder.setDebugEnabled(false);
// You can get the Configuration keys here. [https://dev.twitter.com/:title]
        builder.setOAuthConsumerKey("xxxxxxxxxxxxxxxxxxxxxx");
        builder.setOAuthConsumerSecret("xxxxxxxxxxxxxxxxxxx");
        builder.setOAuthAccessToken("xxxxxxxxxxxxxxxxxxxxxx");
        builder.setOAuthAccessTokenSecret("xxxxxxxxxxxxxxxx");
        return builder.build();
    }

    public void shutdownStream(){
        if (stream != null){
            stream.shutdown();
        }
    }
}
  • code2-2(TwitterListViewSample.java)

When you click the Start button, TwitterSearchTask performs work on background thread.

.....
        startButton.setOnAction(this::handleStart);   // *** Using method reference instead of lambda expression
        EventHandler<KeyEvent> stopFire = e -> {  // *** Lambda expression for Stop Button
            if (e.getCode() == KeyCode.ENTER) {
                stopButton.fire();
            }
        };
        stopButton.setOnKeyPressed(stopFire);
        stopButton.setOnAction(this::handleStop);  // *** method reference for Stop Button
.....
    private void handleStart(ActionEvent e) {
        if (searchText.getText().isEmpty()) {
            searchText.requestFocus();
            searchProgressMessage.setText("enter the search key");
            searchProgressMessage.setFill(Color.RED);
            return;
        }
        searchProgressMessage.setFill(Color.BLUE);
        listView.getItems().clear();
        task = new TwitterSearchTask(searchText.getText(), listView.getItems());
        searchProgressMessage.textProperty().bind(task.messageProperty());
        executor.submit(task);
        startButton.setDisable(true);
        stopButton.setDisable(false);
    }
    private void handleStop(ActionEvent e) {
       if (task != null){
           task.shutdownStream();
           task.cancel();
       }
       startButton.setDisable(false);
       stopButton.setDisable(true);
       searchProgressMessage.textProperty().unbind();
       searchProgressMessage.setText(null);
    }
  • code2-3(TwitterListViewSample.java)

Do not forget to stop the task and shut down the executor.

    @Override
    public void stop() throws Exception {
        if (task != null) {
            task.shutdownStream();
            task.cancel();
        }
        if (executor != null){
            executor.shutdownNow();
        }
    }

This screen show you the files of this application.

All code is here GitHub - tomoTaka01/TwitterListViewSample: JavaFX Application showing Tweet using Twitter4J

Using Lambda expressions is so fun, isn't it?
Anyway I keep coding...