Neste post, mais um pouco de JavaFX: ObservableList, ListCell customizado, e WebView. Aproveitando o código do post anterior (um cliente bem simples de Twitter), vamos adicionar um listener à lista de tuítes para abrir uma janela quando algum tuíte for selecionado.
1. ObservableList
Uma lista do tipo ObservableList pode receber listeners para avisar quando é alterada. Assim, ao adicioná-la ao ListView, sempre que esta lista for alterada, o ListView é atualizado automaticamente. No TwitterFXController, criamos uma lista de status:
[...] // Lista onde serão mostrados os tuítes. @FXML private ListView<Status> tweets; private ObservableList<Status> listaStatus = FXCollections.observableArrayList(); [...]
E no método initialize, adicionamos a seguinte linha:
tweets.setItems(listaStatus);
2. ListCell
Quando há a necessidade de um ListView customizado, como queremos agora para o Status, precisamos chamar o setGraphic(Node) da célula, passando como parâmetro um componente com a aparência que quisermos. Para isso, criamos uma classe que extende o ListCell e cria o Node.
package br.com.matruskan.twitterfx; import java.text.SimpleDateFormat; import java.util.Locale; import javafx.scene.control.ListCell; import javafx.scene.control.ListView; import javafx.scene.text.Text; import twitter4j.Status; public class StatusCell extends ListCell{ private static final SimpleDateFormat DATEFORMAT = new SimpleDateFormat("E HH:mm", Locale.getDefault()); private ListView lista; public StatusCell(ListView lista) { super(); this.lista = lista; } @Override protected void updateItem(Status status, boolean bln) { super.updateItem(status, bln); if(status!=null){ // O mesmo código cria o Text e realiza o bind Text t = new Text( status.getText() + " ("+DATEFORMAT.format(status.getCreatedAt())+")" ); t.wrappingWidthProperty().bind(lista.widthProperty()); setGraphic(t); } } }
3. WebView
O WebView é um componente para mostrar páginas de internet. Ele é baseado no WebKit, o motor de renderização de páginas do Safari, do Chrome, entre outros. Também é útil para criar componentes novos utilizando HTML5 e javascript pois pode mostrar páginas criadas dinamicamente no código, não apenas páginas de sites. Voltando ao TwitterFXController, vamos então criar uma janela e adicionar o WebView.
// Janela com o webview private Stage stageWebView; // WebView com a página do tuíte private WebView webview;
No initialize, adicionamos:
// Preparando a janela com o tuíte stageWebView = new Stage(); webview = new WebView(); Scene scene = new Scene(webview,600,500); stageWebView.setScene(scene);
Basta agora adicionar um listener ao ListView para abrir essa janela:
// Adicionando um listener para abrir a janela tweets.getSelectionModel().selectedItemProperty().addListener( new ChangeListener() { public void changed( ObservableValue<? extends Status> ov, Status old_val, Status new_val) { if(new_val == null) return; // Acontece quando // se apaga os tuítes // para colocar os de // um novo usuário. stageWebView.setTitle(new_val.getUser().getName()); webview.getEngine().load("https://twitter.com/" + new_val.getUser().getScreenName() + "/statuses/" + new_val.getId()); stageWebView.show(); });
Veja algumas imagens do TwitterFX em ação. À esquerda, a janela principal do TwitterFX. Ao clicar em um tuíte, a janela da direita é aberta com o WebView mostrando a página do tuíte.