How to finish editing in DatePicker on Android TV if we control the remote control - datepicker

I have a dialog that has two labels, a DatePicker, and two Back and Apply buttons. By default, the focus belongs to the "Apply" button. We start editing the DatePicker by pressing the up button on the remote. We have set the date and want to go down to the "Apply" button. But this is not possible, because with DatePicker you can not go to the button, because when you press the "Down" button on the remote, the date changes. I would like that after setting the date, I would press the Enter button on the remote control and focus would be given to the "Apply" button. Is it possible?
Below is the code of the dialog:
public class DateSelector {
public static void showSubscriptionDateDialog(Context context, long expiredAt, DateSetListener listener) {
Dialog dialog = new Dialog(context, R.style.DialogTheme);
dialog.setContentView(R.layout.dialog_subscription_date);
DatePicker datePicker = dialog.findViewById(R.id.date_picker);
TextView dateLabel = dialog.findViewById(R.id.subscription_date);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(expiredAt);
AtomicInteger dayForSave = new AtomicInteger();
dayForSave.set(calendar.get(Calendar.DATE));
AtomicInteger monthForSave = new AtomicInteger();
monthForSave.set(calendar.get(Calendar.MONTH));
AtomicInteger yearForSave = new AtomicInteger();
yearForSave.set(calendar.get(Calendar.YEAR));
setDateLabel(yearForSave, monthForSave, dayForSave, dateLabel);
Button buttonBack = dialog.findViewById(R.id.button_back);
buttonBack.setOnClickListener(v -> {
dialog.dismiss();
});
Button buttonClear = dialog.findViewById(R.id.button_clear);
buttonClear.setOnClickListener(v -> {
calendar.set(yearForSave.get(), monthForSave.get(), dayForSave.get());
listener.onDateSelected(calendar.getTimeInMillis());
dialog.dismiss();
});
datePicker.init(yearForSave.get(), monthForSave.get(), dayForSave.get(),
(view, year1, monthOfYear, dayOfMonth) -> {
yearForSave.set(year1);
monthForSave.set(monthOfYear);
dayForSave.set(dayOfMonth);
setDateLabel(yearForSave, monthForSave, dayForSave, dateLabel);
});
buttonClear.requestFocus();
dialog.show();
}
private static void setDateLabel(AtomicInteger yearForSave, AtomicInteger monthForSave,
AtomicInteger dayForSave, TextView dateLabel) {
Calendar calendar = Calendar.getInstance();
Locale locale = Locale.getDefault();
SimpleDateFormat dateFormat = new SimpleDateFormat("EE, d MMMM, yyyy", locale);
calendar.set(yearForSave.get(), monthForSave.get(), dayForSave.get());
String expirationDate = dateFormat.format(calendar.getTime());
dateLabel.setText(expirationDate);
}
public interface DateSetListener {
void onDateSelected(long expiredAt);
}
}

I have found a solution to this problem. You can hang the listener on the dialog and catch the click of the Apply button. Here is the code that solves this problem:
dialog.setOnKeyListener((dialog1, keyCode, event) -> {
if (buttonApply.hasFocus() || buttonBack.hasFocus()) return false;
if (event.getAction() == KeyEvent.ACTION_DOWN) {
if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
buttonApply.requestFocus();
return true;
}
}
return false;
});

Related

Swap the type of link depending on model object

I'm at complete loss how to proceed further:
I have panel with a DropDownChoice and a submit button next to it. Depending on the selected value of the DropDownChoice (Obtained upon the firing of a OnChangeAjaxBehavior attached to it, the submit button needs to either replace the whole panel with a different one, OR become an ExternalLink.
Currently, the code looks like that:
public class ReportSelectionPanel extends Panel {
protected OptionItem selectedOption ;
public ReportSelectionPanel(String id) {
super(id);
IModel<List<OptionItem>> choices = new AbstractReadOnlyModel() {
// Create a list of options to be displayed in the DropDownChoice
} ;
final IModel<OptionItem> optionModel =
new PropertyModel<OptionItem>(this,"selectedOption") ;
final DropDownChoice<OptionItem> options =
new DropDownChoice("selectChoice",optionModel,choices) ;
// I don't know what the button should be... Plain Button? A Link?
final Component button = ???
options.add( new OnChangeAjaxBehavior() {
protected void onUpdate(AjaxRequestTarget target) {
if ( selectedOption.getChild() == null ) {
// button becomes an ExternalLink.
// A new window will popup once button is clicked
} else {
// button becomes a Something, and upon clicking,
// this ReportSelectionPanel instance gets replaced by
// an new Panel instance, the type of which is
// selectedOption.getChild()
}
} ) ;
I'm really not quite sure what the commented lines should become to achieve the result. Any suggestions?
Thanks!
Eric
IMHO it's nicer to keep just one button and just react differently depending on the selected option:
final Component button = new AjaxButton("button") {
public void onClick(AjaxRequestTarget target) {
if (selectedOption.getChild() == null) {
PopupSettings popup = new PopupSettings();
popup.setTarget("'" + externalUrl + "'");
target.appendJavascript(popup.getPopupJavaScript());
} else {
ReportSelectionPanel.this.replaceWith(new ReportResultPanel("..."));
}
}
};
// not needed if options and button are inside a form
// options.add( new OnChangeAjaxBehavior() { } ) ;

User can't navigate if dialogue is open

If dialogue open and user wants to open another screen or anything they needs to close the dialogue first and then navigate, otherwise they can't.
I am having javafx dialogue working but I am unable to figured out how to restrict user not navigate anywhere else without closing current dialogue.
Code:
final TextField templateTexBox = new TextField();
final Label templateNameLabel = new Label("Template Name");
final Label templateType = new Label("Type of Template");
final CheckBox cb = new CheckBox("Set as Default Template");
final ComboBox comboBox = new ComboBox();
comboBox.getItems().addAll("Private", "Public");
comboBox.setPromptText("Select Template Type");
if (getViewModel().selectedTemplate().get() != null) {
templateTexBox.setText(getViewModel().selectedTemplate().get().getPreference().getName());
cb.setSelected(getViewModel().selectedTemplate().get().getDefaultTemplate());
comboBox.setValue(getViewModel().selectedTemplate().get().getTemplateType());
}
final Stage stage = new Stage();
stage.initModality(Modality.WINDOW_MODAL);
final Dialog dlg = new Dialog(stage, "Save Template");
dlg.getStyleClass().add(Dialog.STYLE_CLASS_CROSS_PLATFORM);
dlg.setResizable(false);
dlg.setIconifiable(false);
templateNameLabel.setWrapText(true);
templateType.setWrapText(true);
templateNameLabel.setPrefWidth(130.0);
templateType.setPrefWidth(130.0);
templateTexBox.setPromptText("Enter Text");
templateTexBox.focusedProperty().addListener(new ChangeListener<Boolean>(){
#Override
public void changed(ObservableValue observable, Boolean oldValue, Boolean newValue) {
if(!newValue){
Optional<TemplatePreferences> templateOptional = getViewModel().getAllTemplates().stream().filter(template ->template.getPreference().getName().equalsIgnoreCase(templateTexBox.getText())).findAny();
if(!templateOptional.isPresent()){
cb.setSelected(false);
}
}
}
});
HBox tmpNameBox = new HBox(templateNameLabel, templateTexBox);
HBox tmpTypeBox = new HBox(templateType, comboBox);
HBox tmpDefaultBox = new HBox(cb);
tmpNameBox.setPrefHeight(40.0);
tmpTypeBox.setPrefHeight(40.0);
VBox wrapperBox = new VBox( tmpNameBox, tmpTypeBox, tmpDefaultBox );
dlg.setContent(wrapperBox);
dlg.getActions().addAll(Dialog.ACTION_OK, Dialog.ACTION_CANCEL);
Action action = dlg.show();
if (action == Dialog.ACTION_OK) {
if (StringUtils.isNotBlank(templateTexBox.getText()) && comboBox.getValue() != null) {
//saveTemplateData(templateTexBox.getText(), String.valueOf(comboBox.getValue()), cb.isSelected());
saveFilterTemplateData(templateTexBox.getText(), String.valueOf(comboBox.getValue()), cb.isSelected());
} else {
Dialogs.create().title("Missing Required Data")
.message("Please populate both Template Name and Template Type")
.styleClass(Dialog.STYLE_CLASS_CROSS_PLATFORM).showError();
saveTemplate();
}
}
** I am using this class
import org.controlsfx.dialog.Dialogs;
I have also tried with javafx dialog and craete my code like that but I am unable to achieve what I want.
Call
dlg.initModality(Modality.NONE);
before showing the dialog (see docs)

Why does my History.newItem(someToken) not fire onValueChange()?

Even though it is correctly fired when I use History.fireCurrentHistoryState();
EDIT: All classes in the same package. Code updated -
TestHistory.java
public class TestHistory implements EntryPoint, ValueChangeHandler<String> {
static boolean isLoggedIn = false;
static final String PAGENAME = "mainscreen";
public void onModuleLoad()
{
History.addValueChangeHandler(this);
String startToken = History.getToken();
System.out.println("onModuleLoad Called..... start token= -------"+startToken+"--------");
if(!startToken.isEmpty())
History.newItem(startToken);
History.fireCurrentHistoryState(); //to execute onValueChange 1st time since 1st time history is not setup
}
#Override
public void onValueChange(ValueChangeEvent<String> event) {
String token = event.getValue();
String args = "";
int question = token.indexOf("?");
if (question != -1) {
args = token.substring(question + 1);
token = token.substring(0, question);
}
if(!isLoggedIn)
{
if(token.isEmpty() || "login".equals(token)) //1st time opened the site normally
new Login().display(false, RootPanel.get());
else {
new Login().display(true, RootPanel.get());
}
}
else //User has logged in
{
if(token.isEmpty() || "login".equals(token))
{
if(isLoggedIn)
Window.alert("Ur already logged in!!!");
else
new Login().display(false, RootPanel.get());
}
else if("withdraw".equals(token))
new Withdraw().display(RootPanel.get(), args);
else if("deposit".equals(token))
new Deposit().display(RootPanel.get(), args);
else //token not clear
Window.alert("Unrecognized token=" + token);
}
}
}
Login.java
public class Login {
static final String PAGENAME = "login";
void display(final boolean hasTypedSomeToken, Panel myPanel) //Process login
{
System.out.println("login display called");
Label displayLabel = new Label("This is the Login Page");
Label enterName = new Label("Enter ur name");
final TextBox txtName = new TextBox();
Label enterPasswd = new Label("Enter ur Passwd");
final TextBox txtPasswd = new TextBox();
Button btnLogIn = new Button("Login", new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
/* Real app will check DB. Here we r jst chckng d txt fields hv value */
if(txtName.getValue().length()>0 && txtPasswd.getValue().length()>0)
{
TestHistory.isLoggedIn = true;
if(hasTypedSomeToken) {
//History.back(); //send him to the URL(token) he bookmarked b4 loggin in
History.newItem("login",false);
History.back();
System.out.println(History.getToken());
}
else{
myPanel.clear();
Label displayLabel = new Label("Thank U for logging.);
myPanel.add(displayLabel);
}
}
}
});
myPanel.clear();
myPanel.add(displayLabel);
myPanel.add(enterName);
myPanel.add(txtName);
myPanel.add(enterPasswd);
myPanel.add(txtPasswd);
myPanel.add(btnLogIn);
}
}
Deposit.java
public class Deposit {
static final String PAGENAME = "deposit";
void display(Panel myPanel, String param)
{
System.out.println("deposit display called");
myPanel.clear();
Label displayLabel = new Label("This is the Deposit Page & ur parameter = "+param+")");
myPanel.add(displayLabel);
}
}
Withdraw.java
//similar to deposit.java
The problem was with the usage of History.newItem(). the problem was occuring when I was using the bookmarked url and calling History.newItem() with a new token. Since already a token was present for the same internal page and I was giving it a new token so there was some confusion and onValueChange() was not being called.
Now Im clear that History.newItem() should be used when there is no token attached to the current view to mark the view with a token. Generally when a user opens a site normally (with no token), we should use history.newItem to mark the 1st view.
Also worth noting is that History.fireCurrentHistoryState() just calls onValueChange with the current token. And by going through the GWT's Code I found that History.newItem() simply calls History.fireCurrentHistoryState()
Actually if I replace
if(!startToken.isEmpty())
History.newItem(startToken);
History.fireCurrentHistoryState();
in my code with
if(startToken.isEmpty())
History.newItem("login");
else
History.fireCurrentHistoryState();
& also the code
if(hasTypedSomeToken) {
//History.back(); //send him to the URL(token) he bookmarked b4 loggin in
History.newItem("login",false);
History.back();
System.out.println(History.getToken());
}
with
if(hasTypedSomeToken) {
History.fireCurrentHistoryState();
System.out.println("getToken() in Login = "+History.getToken());
}
it works pretty well.
Although newItem(...) generally fires an event, it is a no-op if the current token is the same as the one you're trying to add. If that's not the case, there's a problem with your implementation.

how to pop up calendar when button is clicked in Java SWT?

I am trying to develop Java SWT application in eclipse.
I need to populate text box using DateTime Calendar in SWT when a button is clicked.
I tried the following code but not able to see the Calendar, though it is created.
Any help would be appreciated.
Thanks
public void createPartControl(final Composite parent) {
Button button;
Label label;
final Display dev = parent.getDisplay();
Image image = new Image(dev,"C:\\Users\\rm186021\\Desktop\\Calendar.gif");
GridLayout gridLayout = new GridLayout();
gridLayout.numColumns = 3;
parent.setLayout(gridLayout);
label = new Label(parent, SWT.NULL);
label.setText("Start date ");
final Text start = new Text(parent, SWT.SINGLE | SWT.BORDER);
Button calButton = new Button(parent, SWT.PUSH);
calButton.setImage(image);
calButton.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
final Display display = new Display();
final Shell shell2 = new Shell(display);
shell2.addListener(SWT.CALENDAR, new Listener() {
public void handleEvent(Event event) {
final DateTime calendar = new DateTime(shell2,SWT.CALENDAR | SWT.POP_UP);
calendar.addSelectionListener (new SelectionAdapter () {
public void widgetSelected (SelectionEvent e) {
start.setData(" " + calendar.getYear() + "-" + (calendar.getMonth() + 1) + "-" + calendar.getDay());
System.out.println(start.getData());
//calendar.dispose();
}
});
}
});
}
});
You're creating a Shell, but never even opening it. Try calling shell2.open().
You're adding an SWT.CALENDAR listener to the Shell. This isn't going to do what you want to do. Or anything, for that matter, since Shell doesn't fire SWT.CALENDAR events. Instead, you simply need to add the DateTime to a container and hook up selection listeners to the Calendar.
SWT.POP_UP is not an appropriate style bit for Calendar.
I would recommend subclassing Dialog (call it CalendarDialog, for example), setting a FillLayout on it, adding a Calendar to it and hooking up listeners that way. Then call CalendarDialog.open().
The DateTime really shouldn't be created with code like that :) Try this instead:
calButton.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
final Shell shell2 = new Shell(dev.getActiveShell());
// new Display() won't work on many platforms if one already exists
final DateTime calendar = new DateTime(shell2, SWT.CALENDAR);
// no need to add a listener to shell2, and POP_UP doesn't work for DateTime
calendar.addSelectionListener(...);
shell2.open();
// Edward Thomson noticed it wasn't called, I missed it
}
};

SWT: show popup menu below toolbar button after clicking on it

I want to show a popup menu below a toolbar button when the user clicks this button. I've read about the SWT.DROP_DOWN style for a ToolItem but this seems very much limited to a simple list of items according to this sample. Instead, I want to show a popup menu with, e.g., checkbox and radio button menu items.
You can make MenuItem with styles SWT.CHECK, SWT.CASCADE, SWT.PUSH, SWT.RADIO, SWT.SEPARATOR
see javadoc..
So you can "hang" swt menu to selection of dropdown on toolbar item like this
public class Test {
private Shell shell;
public Test() {
Display display = new Display();
shell = new Shell(display, SWT.SHELL_TRIM);
shell.setLayout(new FillLayout(SWT.VERTICAL));
shell.setSize(50, 100);
ToolBar toolbar = new ToolBar(shell, SWT.FLAT);
ToolItem itemDrop = new ToolItem(toolbar, SWT.DROP_DOWN);
itemDrop.setText("drop menu");
itemDrop.addSelectionListener(new SelectionAdapter() {
Menu dropMenu = null;
#Override
public void widgetSelected(SelectionEvent e) {
if(dropMenu == null) {
dropMenu = new Menu(shell, SWT.POP_UP);
shell.setMenu(dropMenu);
MenuItem itemCheck = new MenuItem(dropMenu, SWT.CHECK);
itemCheck.setText("checkbox");
MenuItem itemRadio = new MenuItem(dropMenu, SWT.RADIO);
itemRadio.setText("radio1");
MenuItem itemRadio2 = new MenuItem(dropMenu, SWT.RADIO);
itemRadio2.setText("radio2");
}
if (e.detail == SWT.ARROW) {
// Position the menu below and vertically aligned with the the drop down tool button.
final ToolItem toolItem = (ToolItem) e.widget;
final ToolBar toolBar = toolItem.getParent();
Point point = toolBar.toDisplay(new Point(e.x, e.y));
dropMenu.setLocation(point.x, point.y);
dropMenu.setVisible(true);
}
}
});
shell.open();
while(!shell.isDisposed()) {
if(!display.readAndDispatch()) display.sleep();
}
display.dispose();
}
public static void main(String[] args) {
new Test();
}
}