I am calling a new xaml application with some parameter inputs using the word new, but it does not seem to be working. I am also attempting to use onclosing to set it to null. When launching it for the first time it works (everything is new), but launching it after it finished, it seems to continue its previous state (brings to finished score board). Here is the snipplet of the code . . .
quizUI = new QuizzUI.MainWindow(App.User, true);
quizUI.Closed += (o, s) =>
{
quizUI = null;
};
quizUI.LaunchQuiz(qSet);
this is hooked to a button event. does anyone know how i can absolutely new this object's state every time? the two paramters are user's info and second one is to shortcut without prompt screen/loading screen.
Here is the code for QuizzUI.MainWindow.LaunchQuizz:
public void LaunchQuiz(GameQuizzSet quiz)
{
this.Hide();
quizz = new QuizzContainer()
{
QSet = quiz,
};
if (isShortCutted)
{
bool? diag = quizz.ShowDialog();
if (diag.HasValue)
{
quizz.Close();
Close();
}
}
else
{
quizz.ShowDialog();
this.Show();
}
}
the QuizzUI.MainWindow allows the user to select their profile and which quiz to execute.
Related
I have an Android application that uses Back Command to go back to the start screen.
The start screen has a label with a number inside, that I want to update when the back command is used.
I could figure out a solution with the code inside the back command, but I don't know if my approach is the best, since the ClassOne gets sort of loaded twice.
Here is the code I already have:
public class ClassOne {
public ClassOne(ClassPojo classPojo) {
// I want to change the text of this label when calling the back command
labelOne.setText(classPojo.getStringTest());
formOne.show();
}
}
public class ClassTwo {
public ClassTwo(Form a , ClassPojo classPojo) {
Command back = new Command("A") {
#Override
public void actionPerformed(ActionEvent evt) {
// I am adding the new value for the label here inside the back command
classPojo.setStringTest("testing");
a.showBack();
new ClassOne(classPojo);
}
};
formTwo.setBackCommand(back);
}
I'm not sure what the problem is, your example is a bit generic. However, a complete minimal example where the startScreen form instance is not recreated is this one:
Form startScreen = new Form("Start screen", BoxLayout.y());
Wrapper<Integer> count = new Wrapper<>(1);
Label numberLabel = new Label(count.get() + "");
Button button1 = new Button("Go to Form 2");
startScreen.addAll(numberLabel, button1);
startScreen.show();
button1.addActionListener(l -> {
Form form2 = new Form("Form 2", BoxLayout.y());
Label label = new Label("Use the back button");
form2.add(label);
form2.getToolbar().setBackCommand("Back", Toolbar.BackCommandPolicy.ALWAYS, ll -> {
count.set(count.get() + 1);
numberLabel.setText(count.get() + "");
startScreen.showBack();
});
form2.show();
});
If you don't even want to recreate the form2 instance, then you can do so:
Form startScreen = new Form("Start screen", BoxLayout.y());
Wrapper<Integer> count = new Wrapper<>(1);
Label numberLabel = new Label(count.get() + "");
Button button1 = new Button("Go to Form 2");
startScreen.addAll(numberLabel, button1);
startScreen.show();
Form form2 = new Form("Form 2", BoxLayout.y());
Label label = new Label("Use the back button");
form2.add(label);
form2.getToolbar().setBackCommand("Back", Toolbar.BackCommandPolicy.ALWAYS, ll -> {
count.set(count.get() + 1);
numberLabel.setText(count.get() + "");
startScreen.showBack();
});
button1.addActionListener(l -> {
form2.show();
});
In my opinion, whether or not to recreate the instances of a Form should be evaluated on a case-by-case basis. Among the variables between taking into consideration, according to my modest opinion, there is also the readability of the code and what it does, especially in complex cases.
The overhead of recreating a form instance is negligible so that wouldn't be a problem but in recent years we try to reuse form instances more. Not because of the performance.
The benefit is in minor behaviors e.g. scroll position within the form. These are very hard to replicate.
During testing, I found an easy solution that is adding the label to the constructor. I hope this snippet can be helpful.
public ClassTwo(Form a, ClassPojo classPojo, Label label) {
Command back = new Command("A") {
#Override
public void actionPerformed(ActionEvent evt) {
label.setText(classPojo.getStringTest());
a.showBack();
}
};
I am using two AutocompleteTextFilters as depended filters. I want the second one filter to change its options depending on the suggestion of the first filter.
I have bind an event listener on the first filter so as when it loose focus it triggers a proccess on the second filter.
The proble is that the second filter never changes its options. I even have setup hardcoded values in case somethig was wrong on my code but no luck.
The code I use is below:
public CreateSubmission(com.codename1.ui.util.Resources resourceObjectInstance, Map<String, ProjectType> projectTypes) {
this.projectTypes = projectTypes;
initGuiBuilderComponents(resourceObjectInstance);
gui_ac_projecttype.clear();
gui_ac_projecttype.setCompletion( this.projectTypes.keySet().toArray( new String[0]) );
gui_ac_projecttype.addFocusListener( new ProjectTypeFocusListener( this ));
gui_ac_steps.setCompletion( new String[]{"t10", "t20"});
}
public void makeSteps (String selection) {
ProjectType projectType = this.projectTypes.get( selection );
if (projectType != null) {
this.selectedProjectType = selection;
int length = projectType.projectSteps.length;
String[] steps = new String[ length ];
for(int i =0; i < length; i ++) {
steps[i] = projectType.projectSteps[i].projectStep;
}
// String[] s = gui_ac_steps.getCompletion();
gui_ac_steps.setCompletion( new String[]{"t1", "t2"} );
gui_ac_steps.repaint();
}
else {
}
}
public class ProjectTypeFocusListener implements FocusListener{
private CreateSubmission parent;
public ProjectTypeFocusListener( CreateSubmission parent ) {
this.parent = parent;
}
#Override
public void focusGained(Component cmp) {
//throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
#Override
public void focusLost(Component cmp) {
this.parent.makeSteps (
((AutoCompleteTextField)cmp).getText()
);
//throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
On the above code the initialization happens on "public CreateSubmission" method.
"gui_ac_projecttype" is the first AutocompletionTextField that triggers the whole proccess through it's FocusListener handler (class ProjectTypeFocusListener )
"gui_ac_steps" is the second AutocompleteTextField filter that must change its values. On the code above I initialize it's suggestions to "t10", "t20". Those two values are shown correctly.
Later from iside the FoculListenerHandler's method "ProjectTypeFocusListener.focusLost" I call method "makeSteps" which sets the suggestion options to "t1", "t2 and then I repaint the component. These two last values are never shown. It remains on the first values "t10", "t20".
The Strange thing is that in debugger when I ask gui_ac_steps.getCompletion(); to see the current options ( the code that is commentd out into makeSteps method) I get the correct values "t1", "t2".
But on the screen it keeps showing "t10", "t20".
any help is aprreciated.
You shouldn't do anything "important" in a focus listener. Especially not with a text field. They are somewhat unreliable because the text field switches to native editing and in effect transfers the focus there. The problem is that some events are delayed due to the back and forth with the native editing so by the time the focus event is received you've moved on to the next field.
Try something like this for this specific use case https://www.codenameone.com/blog/dynamic-autocomplete.html
It has probably been covered before, but I couldn’t google anything. What is the best approach for making an iPhone-style pop-up selection menu like attached picture? I've tried with a Dialog, but I haven't found an elegant way to add the Commands so they appear nicely and both trigger the action and close the dialog at the same time. And showing a Cancel entry separately is not supported by a ComponentGroup.
See this sample:
Form hi = new Form("Pop");
Button pop = new Button("Pop");
pop.addActionListener(e -> {
Dialog dlg = new Dialog();
// makes the dialog transparent
dlg.setDialogUIID("Container");
dlg.setLayout(BoxLayout.y());
Command optionACmd = new Command("Option A");
Command optionBCmd = new Command("Option B");
Command optionCCmd = new Command("Option C");
Command cancelCmd = new Command("Cancel");
dlg.add(
ComponentGroup.enclose(
new Button(optionACmd),
new Button(optionBCmd),
new Button(optionCCmd)
)).
add(ComponentGroup.enclose(new Button(cancelCmd)));
Command result = dlg.showStretched(BorderLayout.SOUTH, true);
ToastBar.showMessage("Command " + result.getCommandName(), FontImage.MATERIAL_INFO);
});
hi.add(pop);
hi.show();
Which results in this:
Thanks Shai!
I made it into a component in case anybody has a similar need:
class MyPopupMenu extends Dialog {
private Command cancelCmd = null;
MyPopupMenu(boolean includeCancel, Command... commands) {
this(includeCancel?new Command("Cancel"):null, commands);
}
MyPopupMenu(Command cancelOptional, Command... commands) {
super();
setDialogUIID("Container");
setLayout(BoxLayout.y());
setDisposeWhenPointerOutOfBounds(true); //close if clicking outside menu
ComponentGroup group = new ComponentGroup();
for (Command cmd : commands) {
group.add(new Button(cmd));
}
add(group);
this.cancelCmd = cancelOptional;
if (cancelCmd != null) {
add(ComponentGroup.enclose(new Button(cancelCmd)));
}
/**
* show the menu and execute the selected Command,
* or do nothing if Cancel is selected
*/
public void popup() {
Command choice = showStretched(BorderLayout.SOUTH, true);
if (choice != null && choice != cancelCmd) {
choice.actionPerformed(null);
}
}
}
This is awesome, thanks guys. Any reason my buttons seem to be so small? Trying to figure out which style needs to change to increase the height. Changing the Button padding did not seem to change anything. I used the Business theme as a starting point.
I have a pivot control and a button which does selectedIndex++ and when the selectedIndex has gone passed the last entry it will open up a messagebox asking the user if they want to quiz.
But during testing if you spam the button it will create a 0x8000ffff error when you open the MessageBox.
How do I stop this from happening? is it something to do with the ui thread being too busy or continuing to move the pivot? is the button event still running after I try to navigate out of the page?
this is what the code that does the selectedIndex++
void gotoNextQuestion()
{
if (quizPivot.SelectedIndex < App.settings.currentTest.Questions.Count() - 1)
{
//xScroll -= scrollAmount;
//moveBackground(xScroll);
if (!stoppedPaging)
{
quizPivot.SelectedIndex++;
}
//App.PlaySoundKey("next");
}
else
{
if (App.settings.testMode == App.TestModes.TrainingRecap)
{
MessageBoxResult result;
if (countAnsweredQuestions() == App.settings.currentTest.Questions.Count())
{
stoppedPaging = true;
result = MessageBox.Show("You have reviewed every training question, would you like to go back to the main menu?", "Training Over", MessageBoxButton.OKCancel);
stoppedPaging = false;
if (result == MessageBoxResult.OK)
{
positionableSpriteRadioButton.IsAnswered -= new Action<bool>(Answers_IsAnsweredCompleted);
spriteRadioButton.IsAnswered -= new Action<bool>(Answers_IsAnsweredCompleted);
App.settings.currentTest = null;
NavigationService.Navigate(new Uri("/MainPage.xaml", UriKind.Relative));
return;
}
}
}
else
{
MessageBoxResult result;
if (countAnsweredQuestions() == App.settings.currentTest.Questions.Count())
{
stoppedPaging = true;
result = MessageBox.Show("You have answered all of the questions, are you sure you want to finish?", "Are you sure you want to finish?", MessageBoxButton.OKCancel);
stoppedPaging = false;
}
else
{
checkFinishConditions();
}
}
quizPivot.SelectedIndex = 0;
//App.PlaySoundKey("begin");
}
App.settings.currentTest.currentQuestion = quizPivot.SelectedIndex;
}
Well, one thing is for sure
positionableSpriteRadioButton.IsAnswered -= new Action<bool>(Answers_IsAnsweredCompleted);
That isn't going to work. You're creating a new Action every time. So nothing will have the same reference id, and thus nothing will be removed.
Instead you should remove the Action<bool> and simply subscribe/unsubscribe with
positionableSpriteRadioButton.IsAnswered -= Answers_IsAnsweredCompleted;
And when you subscribe
positionableSpriteRadioButton.IsAnswered += Answers_IsAnsweredCompleted;
That way you can actually remove it again.
But I would recommend you not to use a pivot for this type of "wizard". It's abuse of the control, and going to give a really poor user experience.
Also, just because you navigate to another page, it doesn't mean the code stops running. All code in the same expression is executed, unless you add a return statement after the call to NavigationService.Navigate.
Also, always make sure that Navigation is on the UI thread by wrapping all calls to NavigationService.Navigate in a call to Dispatcher.BeginInvoke.
Is there a way to update the print queue status information contained in the PrintQueue object?
I've tried calling Refresh on the PrintQueue object but that doesn't really do anything. For instance, I've turned off the printer and the Control Panel correctly shows the printer as "Offline", however the QueueStatus property, as well as the IsOffline property don't reflect that - no matter how many times I call Refresh on both the PrintServer and the PrintQueue in question.
I've seen examples of how to get status information using WMI queries but I wonder - since these properties are available on the PrintQueue object - whether there is any way to use those.
After try to print your PrintDocument (System.Drawing.Printing), try to check status of printjobs.
First step:
Initialize your printDocument.
Second step:
Get your printer Name From System.Drawing.Printing.PrinterSettings.InstalledPrinters.Cast<string>();
And copy it into your printerDocument.PrinterSettings.PrinterName
Third step:
Try to print and dispose.
printerDocument.Print();
printerDocument.Dispose();
Last step: Run the check in a Task (do NOT block UI thread).
Task.Run(()=>{
if (!IsPrinterOk(printerDocument.PrinterSettings.PrinterName,checkTimeInMillisec))
{
// failed printing, do something...
}
});
Here is the implementation:
private bool IsPrinterOk(string name,int checkTimeInMillisec)
{
System.Collections.IList value = null;
do
{
//checkTimeInMillisec should be between 2000 and 5000
System.Threading.Thread.Sleep(checkTimeInMillisec);
using (System.Management.ManagementObjectSearcher searcher = new System.Management.ManagementObjectSearcher("SELECT * FROM Win32_PrintJob WHERE Name like '%" + name + "%'"))
{
value = null;
if (searcher.Get().Count == 0) // Number of pending document.
return true; // return because we haven't got any pending document.
else
{
foreach (System.Management.ManagementObject printer in searcher.Get())
{
value = printer.Properties.Cast<System.Management.PropertyData>().Where(p => p.Name.Equals("Status")).Select(p => p.Value).ToList();
break;
}
}
}
}
while (value.Contains("Printing") || value.Contains("UNKNOWN") || value.Contains("OK"));
return value.Contains("Error") ? false : true;
}
Good luck.