the title says almost everything. When I execute the expandItem() function programmatically I do not want the fired event causing a nodeExpand() call.
I have implemented the ExpandListener:
#Override
public void nodeExpand(ExpandEvent event)
{
System.out.println("This should only appear when the user clicks the node on the UI");
}
When I call the expandItem() function of the Tree class, there is always an event fired. This is the code of the original Tree class:
public boolean expandItem(Object itemId) {
boolean success = expandItem(itemId, true);
requestRepaint();
return success;
}
private boolean expandItem(Object itemId, boolean sendChildTree) {
// Succeeds if the node is already expanded
if (isExpanded(itemId)) {
return true;
}
// Nodes that can not have children are not expandable
if (!areChildrenAllowed(itemId)) {
return false;
}
// Expands
expanded.add(itemId);
expandedItemId = itemId;
if (initialPaint) {
requestRepaint();
} else if (sendChildTree) {
requestPartialRepaint();
}
fireExpandEvent(itemId);
return true;
}
What I did now to get this work is:
m_Tree.removeListener((ExpandListener)this);
m_Tree.expandItem(sItemId);
m_Tree.addListener((ExpandListener)this);
Is there any nicer approach?
You could try to create a switch to your listener. For example:
private boolean listenerDisabled;
void setListenerDisabled(boolean disabled)
{
listenerDisabled = disabled;
}
#Override
public void nodeExpand(ExpandEvent event)
{
if(listenerDisabled) return;
System.out.println("This should only appear when the user clicks the node on the UI");
}
and disable the listener when needed.
If there are more than one listener, you could try creating a subclass of Tree and overriding some methods.
Related
I am using Freshsmvvm in my project and I want to display a list of operations,
this is my method from the crud
public List<Operation> GetAll()
{
try
{
return connection.Table<Operation>().ToList();
}
catch (Exception ex)
{
StatusMessage = $"Error: {ex.Message}";
}
return null;
}
In my viewModel i'm have a list and a method to obtain the saved records
private List<Operation> _listOp;
public List<Operation> ListOp
{
get { return _listOp; }
set
{
_listOp = value;
RaisePropertyChanged();
}
}
private void GetOp()
{
ListOp = App.OperationRepository.GetAll();
}
*add the GetOp method in the constructor to load in the collectionview*
public override void Init(object initData)
{
GetOp();
}
What happens is that the list does not update, I have to close the application and when I open it again, the entered record appears.
This is the list without adding a new record
This is the list with a log after restarting the app
You can use the method OnAppearing() to refresh your list.
protected override async void OnAppearing()
{
base.OnAppearing();
ListOp = App.OperationRepository.GetAll();
}
I am trying to use AsyncTask and the activity is working perfectly but I am facing a problem. The problem comes after I have pressed back button, because pressing this button my app crashes. I have seen other posts saying that I must cancel the task in onStop() and onDestroy() but still crashes. Does anyone have any idea how can I solve that?
private class MyAsyncTask extends AsyncTask<Void, Integer, Boolean> {
#Override
protected Boolean doInBackground(Void... args0) {
for(int i=1; i<=10; i++) {
try{
if(isCancelled())
break;
publishProgress(i*10);
Thread.sleep(1000);
}catch (InterruptedException e){}
}
return null;
}
/*
* it will update the publishProgress method and it will
* update the interface (if it's necessary)
*/
#Override
protected void onProgressUpdate(Integer... values) {
int progreso = values[0].intValue();
pbarProgreso.setProgress(progreso); // showing progress
pbarProgreso.setSecondaryProgress(progreso + 5);
}
/*
* Initializing progressBar
*/
#Override
protected void onPreExecute() {
pbarProgreso.setMax(100); // maximum value for process bar
pbarProgreso.setProgress(0); // minimum value to start
}
#Override
protected void onPostExecute(Boolean result) {
if(!this.isCancelled())
Toast.makeText(getApplicationContext(), "Task finished!",
Toast.LENGTH_SHORT).show();
}
#Override
protected void onCancelled() {
Toast.makeText(getApplicationContext(), "Task cancelled!",
Toast.LENGTH_SHORT).show();
}
}
#Override
protected void onStop() {
super.onStop();
if(task != null && task.getStatus() == Status.RUNNING){
task.cancel(true);
}
}
#Override
protected void onDestroy() {
super.onDestroy();
if(task != null && task.getStatus() == Status.RUNNING) {
task.cancel(true);
}
}
It's because when you press back button, AsyncTask continues to work, and when it do context related work, that context no longer exists, and a crash happens, it's better to use a "isResumed" boolean indicator variable inside an activity, and set it to false in onPause and set to true inside onResume, and inside an AsyncTask do context related things, inside an if condition.
Or if this code is inside a fragment, can use isAdded() method, to check if fragment is active or not. Cancel is also important, but there may be a delay, between an Activity pause and AsyncTask cancel, so keeping that variable is important.
I want to fire an event when setting a value in a TextBox with setText("something")
What I tried so far
w.addChangeHandler(new ChangeHandler() {
#Override
public void onChange(ChangeEvent event) {
isChanged = true;
}
});
And I tried also to have a custom a TextBox that listen to past event
class CustomTextBox extends TextBox implements HasHandlers {
private HandlerManager handlerManager;
public CustomTextBox() {
super();
handlerManager = new HandlerManager(this);
sinkEvents(Event.ONPASTE);
}
#Override
public void onBrowserEvent(Event event) {
super.onBrowserEvent(event);
switch (event.getTypeInt()) {
case Event.ONPASTE:{
fireEvent(new TextChangeEvent());
break;
}
default:
// Do nothing
}
}
#Override
public void fireEvent(GwtEvent<?> event) {
handlerManager.fireEvent(event);
}
public HandlerRegistration addTextChangeEventHandler(TextChangeEventHandler handler) {
return handlerManager.addHandler(TextChangeEvent.TYPE, handler);
}
}
With no success, any suggestions would be appreciated.
setText won't fire events.
Add a ValueChangeHandler<String> to your TextBox, then use setValue("something", true) to fire a ValueChangeEvent<String> to all handlers while setting the new value, whether the box id disabled or not.
I have the following code:
try {
res = new Utils(ubc_context).new DownloadCalendarTask().execute().get();
} catch (InterruptedException e) {
Log.v("downloadcalendar", "interruptedexecution : " + e.getLocalizedMessage());
res = false;
} catch (ExecutionException e) {
Log.v("downloadcalendar", "executionexception : " + e.getLocalizedMessage());
res = false;
}
Log.v("displaymenu", "A");
public class Utils {
private Context context;
public Utils(Context context) {
this.context = context;
}
public class DownloadCalendarTask extends AsyncTask<Void, Void, Boolean> {
private ProgressDialog dialog;
public DownloadCalendarTask() {
dialog = new ProgressDialog(context);
}
protected void onPreExecute() {
Log.v("preexecute", "A");
dialog.setMessage("Loading calendar, please wait...");
Log.v("preexecute", "B");
dialog.show();
Log.v("preexecute", "C");
}
protected Boolean doInBackground(Void... arg0) {
// do some work here...
return (Boolean) false;
}
protected void onPostExecute() {
Log.d("utils", "entered onpostexecute");
dialog.dismiss();
}
}
}
The first part of code is attached to an onClick listener for a button. When I click the button the button flashes (as it does to show it has been clicked), and then after about 8 seconds the Loading dialog appears but never finishes.
According to logcat, as soon as I click the button onPreExecute is executed as is Dialog.show(), so my first problem is why is there this 8 second delay? During these 8 seconds, logcat shows that doInBackground is being executed. However, according to logcat (this is the second problem) onPostExecute is never called (and so Dialog.dismiss()) is never run.
Logcat shows that everything following DownloadCalendarTask().execute().get() is being executed, so it's as if onPostExecute has just been skipped.
Many thanks for your help!
You are calling AsyncTask.get() which causes the UI thread to be blocked while the AsyncTask is executing.
new DownloadCalendarTask().execute().get();
If you remove the call to get() it will perform asynchronously and give the expected result.
new DownloadCalendarTask().execute();
Edit:
You will also need to update the parameters to your onPostExecute method, they need to include the result. e.g.
protected void onPostExecute(Boolean result) {
I have a method where the user can search for a article number and if its available in the database the articlenumber gets bound to a BindingList. Now I want to let the user know if the article is not available in database. How do I do that the right way?
Just pass the message errorMessage to my interface method?
Presenter:
string errorMessage;
_view.ErrorMessage(errorMessage);
View:
public void ErrorMessage(string errorMessage)
{
MessageBox.Show(errorMessage);
}
Would you do it the same way?
We bubble an event. In the presenter you register that event:
public event PresenterEventHandler Message;
And then raise it like so:
PresenterEventArgs pe = new PresenterEventArgs("Error message", Status.Error);
this.Message(this, pe);
Then in the view:
protected override void OnInit(EventArgs e)
{
this.presenter = new MyPresenter(this, MyBusinessService.Instance);
this.presenter.Message += new PresenterEventHandler(presenter_Message);
}
void presenter_Message(object sender, PresenterEventArgs pe)
{
// display error message
}
You can pass different types of statuses back to the view in this way, and not just error messages. We have Success, Error, Locked, Warning, Help.
In the case of error messages I would call some base functionality. This way you could choose wether to update the status window on the bottom left and/or display a modal message box.
In the presenter:
_windowManager.NoItemFound(errorMessage)
In the window manager:
_statusBox.Text = errorMessage; MessageBox.Show(errorMessage);
We should not re-invent the wheel ....
You should simply throw an exception in your model.
Then, the view will catch the exception using a try catch block.
In the "catch", show your message box.
If its MVP - Passive View, then the View interface should have a property that could read:
public interface IArticleListView {
// more stuff here...
bool ErrorMessageVisible { set; }
string ErrorMessage { set; }
// more stuff here...
int ArticleNumber { get; }
}
public interface IPresenter {
public void Update();
}
public class ArticleListPresenter : IPresenter {
IViewArticleList _view;
public ArticleListPresenter(IArticleListView view) {
this._view = view;
// you could update the view here or with an update method,
// completely up to you.
}
// Assuming you are using a fine grained presenter
public void HandleArticleNumberSearch() {
bool articleNotFound;
// search for the article ...
if ( articleNotFound ) {
this._view.ErrorMessageVisible = true;
this._view.ErrorMessage = string.Format("The article #{0} was not found.", number);
}
}
}
public class ArticleList : Page, IArticleListView {
ArticleListPresenter _presenter;
public bool ErrorMessageVisible {
set { this.lblErrorMessage.Visible = value; }
}
public bool ErrorMessage {
set { this.lblErrorMessage.Text = value; }
}
public int ArticleNumber {
// You have to do some sort of validation here, but I'll keep it simple
get { return Integer.Parse(this.txtArticleNumber.Text); }
}
protected override void OnInit(EventArgs e) {
this._presenter = new ArticleListPresenter(this);
}
protected void Page_Load(object sender, EventArgs e) {
// this implementation keeps the state in the View, and updates it
// in the presenter: Passive View
if(!this.IsPostBack) {
this._presenter.Update();
}
}
protected void OnSearchArticleButtonClick(object sender, EventArgs e) {
this._presenter.HandleArticleNumberSearch();
}
}
That's what I do.
Another way I've read about would be for the model to know how to show an error (perhaps by an ErrorMessagePresenter) so the error is detached from the original presenter.
I haven't really found a use for that, for me, it always ends in the presenter and view implementing both interfaces.