Picker (classe base)
Picker é a base comum de todas as janelas de seleção do CrossFly (data, hora, arquivo, foto, cor, código de barras, coordenada). Cada picker abre, deixa o usuário interagir e, ao confirmar, fecha-se sozinho entregando o resultado de forma assíncrona, via callback, ao código que o abriu.
Entender o padrão desta página é entender todos os pickers de uma vez.
🟡 · Pacote:
dev.crossfly.ui.picker· Estende:Window· Transição:FADEpor padrão
O padrão central: getAnswer() + show(onAnswer)
Picker.getAnswer()produz o valor selecionado (cada subclasse sobrescreve para devolver o tipo concreto:String,Integer,LatLon…). Na base, retornanull.Window.show(RunnableWith<Object> onAnswer)consome esse valor quando a janela é fechada.
O elo entre os dois está em Window.hide():
public void hide() {
...
Object answer = this instanceof Picker ? ((Picker) this).getAnswer() : null;
if (onAnswer != null && answer != null)
onAnswer.run(answer);
...
}
Consequências práticas (todas confirmadas no código):
- O callback
onAnswersó dispara emhide()e somente segetAnswer() != null. Ao cancelar, as subclasses fazemgetAnswer()retornarnull— então oonAnswernão é chamado. Quem precisa reagir ao cancelamento deve sobrescreveronHide()/onRemove()ou usar o callback específico da subclasse. show(onAnswer)é thread-safe: se chamado fora da paint thread, é reagendado e bloqueia até concluir.- O valor entregue é
Object; o consumidor faz cast para o tipo concreto do picker.
Isto contrasta com
Alert/ActionSheet, que estendemWindowmas nãoPicker— nelesshow(onAnswer)não dispara e a resposta vem por callbacks de botão.
Exemplo completo (copiar, colar e rodar)
package com.exemplo;
import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;
import dev.crossfly.ui.picker.*;
/** Tela principal executável. Aponte o launcher (classname) e rode: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
@Override
public void onShow() throws Exception
{
super.onShow();
setLayout(new VerticalLayout());
Button abrir = new Button("Abrir picker");
abrir.onAction(c ->
{
// Qualquer subclasse de Picker segue o mesmo padrão show(onAnswer)
DatePicker dp = new DatePicker();
dp.show(answer ->
{
// 'answer' é o Object devolvido por getAnswer(); só chega aqui se != null
String data = (String) answer;
Hint.show("Selecionado: " + data, 2000);
});
});
add(LAY_AUTO, abrir);
}
}
Os trechos abaixo mostram só o miolo (o que vai dentro de
onShow()). Para rodar, coloque-os no esqueletoMainWindowacima.
Uso básico (forma genérica de qualquer picker)
DatePicker dp = new DatePicker();
dp.show(answer ->
{
// 'answer' é o Object devolvido por getAnswer(); só chega aqui se != null
String data = (String) answer;
Debug.log("Selecionado: " + data);
});
Métodos públicos
| Método | Retorno | Descrição |
|---|---|---|
getAnswer() |
Object |
Resultado do picker, ou null se cancelado. Sobrescrito por cada subclasse. |
show(RunnableWith<Object> onAnswer) |
void |
Abre o picker; entrega o valor via callback ao fechar (herdado de Window). |
Tipos devolvidos por subclasse
| Picker | getAnswer() devolve |
|---|---|
DatePicker |
String (data conforme LocaleFormats.dateFormat/dateSeparator) |
TimePicker |
String (HH:MM, 24h) |
FilePicker |
— (esqueleto vazio; herda null da base) |
PhotoPicker |
String (caminho ou "ERROR: ...") |
ColorPicker |
Integer (RGB sem alpha) |
BarcodePicker |
String (payload lido) |
LocationPicker |
LatLon |
Boas práticas
- Sempre faça o cast do
Objectpara o tipo concreto da tabela acima. - Para reagir ao cancelamento, não conte com
onAnswer— use o callback específico (onSelect/onCapture) ou sobrescrevaonHide(). - Pickers de hardware (
PhotoPicker,BarcodePicker,LocationPicker) liberam recursos ao fechar; não reaproveite a mesma instância apóshide().
Erros comuns
- Esperar
onAnswerno cancelamento — não dispara, porquegetAnswer()devolvenull. - Esquecer o cast — o callback recebe
Object.
Veja também
- Guia da área:
ui/· Receitas:cookbook/ - Subclasses:
DatePicker·TimePicker·FilePicker·PhotoPicker·ColorPicker·BarcodePicker·LocationPicker