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))
- Java version
- 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(); } }
- Figure2(TreeView screen by JavaFX sample application(FYR:http://d.hatena.ne.jp/tomoTaka/20130521/1369089435))
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...