JavaFX: Problems to use setOnCloseRequest within a Controller - javafx-2

I want to use setOnCloseRequest after my stage has been started but i get almost a NullPointerException although i set the right controller.
I click on a menuitem to open the stage and after the menu is open i want to use the close button. I think the method tries to access until the controller has been initialized.Actually i want to say: Please controller you are just allowed to do something after you are initialized.
THis is my code of the controller.
if (KundenDatenController.getInstance() != null) {
((Stage) (KundenDatenController.getInstance().kundenControllerPane.
getScene().getWindow())).setOnCloseRequest(new EventHandler<WindowEvent>() {
#Override
public void handle(WindowEvent t) {
t.consume();
if (generalControler.controlEmptyTextField(pflichtfelder)) {
((Stage) (kundenControllerPane.getScene().getWindow())).close();
} else if (!generalControler.controlEmptyTextField(pflichtfelder)) {
FXOptionPane.showConfirmDialog((Stage) (kundenControllerPane.getScene().getWindow()),
"Sollen die Eingaben wirklich verworfen werden?",
"Programm schliessen");
if (status.equals("Laden")) {
KundenUebersichtController.getInstance().setStatus("Aufnehmen");
}
}
}
});

Related

How do I replace Asynctask with RxJava Observer?

I have a test project with Room database. Using Asynctask I can successfully insert an object with some test data into the database. I'm trying to learn RxJava and replace Asynctask with RxJava's observer, but it doesn't work. I have read alot of documentation and watched tutorials, but I don't think I quite get it. Here's the relevant code:
Here I set my Room object with the data from my List:
for(ObjectForArray item: listToDatabase) {
myRoomEntity.setName( item.getName() );
Log.d( "TAG", myRoomEntity.getName() );
}
Then I try to use RxJava Observable to insert data into the database. This was originally and successfully done using Asynctask:
Observable<MyRoomEntity> myRX = Observable
.just(myRoomEntity)
.subscribeOn( Schedulers.io() )
.observeOn( AndroidSchedulers.mainThread() );
myRX.subscribe( new Observer<MyRoomEntity>() {
#Override
public void onSubscribe(Disposable d) {
Log.d("TAG ONSUBSCRIBE", d.toString());
try {
myViewModel.insertDatabase( myRoomEntity );
Log.d( "TAG", "Populating database Success" );
}catch(Error error) {
Log.d( "TAG", error.toString() );
}
}
The OnNext, OnError and OnComplete are empty.
When I run the project it crashes with the error:
Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
I'm obviously using RxJava wrong since the point is to do asynchronous tasks away from the main thread.
i have use RX java in replace of Asyntask as it has been deprecated in android 9
there are multiple replacements that android provides like Executors, threads, Listenable Futures , Coroutines 🔥, so you are looking how to implement this with rxjava and how RX Java java helps your to migrate just add these dependencies first in gradle
implementation "io.reactivex.rxjava2:rxjava:2.2.20"
implementation "io.reactivex.rxjava2:rxandroid:2.1.1"
once you import lets start working with RX java i will let you know where you can put background task, pre execute, on post execute like asynctask
lets start codding with Rx java first , i have comment in the method that will help you to put the code
Observable.fromCallable(new Callable<Boolean>() {
#Override
public Boolean call() throws Exception {
/// here is your background task
return true;
}
}).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Boolean>() {
#Override
public void onSubscribe(Disposable d) {
//// pre execute here is my progress dialog
showProgressDialog(getString(R.string.scanning));
}
#Override
public void onNext(Boolean aBoolean) {
//// here is on sucess you can do anystuff here like
if (aBoolean){
/// if its value true you can go ahead with this
}
}
#Override
public void onError(Throwable e) {
/// this helps you to go if there is any error show dialog whatever you wants here
Log.e("error of kind",e.getMessage() );
}
#Override
public void onComplete() {
/// when your task done means post execute
}
});
once its done lets start working with implementation
Observable.fromCallable(new Callable<Boolean>() {
#Override
public Boolean call() throws Exception {
/// here is your background task
uribitmap = getScannedBitmap(original, points);
uri = Utils.getUri(getActivity(), uribitmap);
scanner.onScanFinish(uri);
return true;
}
}).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Boolean>() {
#Override
public void onSubscribe(Disposable d) {
//// pre execute here is my progress dialog
showProgressDialog(getString(R.string.scanning));
}
#Override
public void onNext(Boolean aBoolean) {
//// here is on sucess you can do anystuff here like
if (aBoolean){
/// if its value true you can go ahead with this
}
}
#Override
public void onError(Throwable e) {
/// this helps you to go if there is any error show dialog whatever you wants here
Log.e("error of kind",e.getMessage() );
}
#Override
public void onComplete() {
/// when your task done means post execute
uribitmap.recycle();
dismissDialog();
}
});
now i will do this with executors :
/// pre execute you can trigger to progress dialog
showProgressDialog(getString(R.string.scanning));
ExecutorService executors = Executors.newSingleThreadExecutor();
executors.execute(new Runnable() {
#Override
public void run() {
//// do background heavy task here
final Bitmap uribitmap = getScannedBitmap(original, points);
uri = Utils.getUri(getActivity(), uribitmap);
scanner.onScanFinish(uri);
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
//// Ui thread work like
uribitmap.recycle();
dismissDialog();
}
});
}
});
You are getting this error because you are trying to insert an Object on the main (UI) thread.
You should do something like this:
Observable.fromCallable(() -> myViewModel.insertDatabase( myRoomEntity ))
.subscribeOn( Schedulers.io() )
.observeOn( AndroidSchedulers.mainThread() );
And then use an Observer to subscribe to the Observable.
Please try restructuring your code like this:
Completable.fromAction(() -> myViewModel.insertDatabase(myRoomEntity))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(() -> Log.d("TAG", "Populating database Success"),
throwable -> Log.d("TAG", throwable.toString()))
Considerations:
If your myRoomEntity is not available before this whole construct gets subscribed, make sure you use defer http://reactivex.io/documentation/operators/defer.html
Your subscribe section handlers are operating on "main", that's why you were receiving a crash.
If possible, avoid unnecessary just calls

Android - Back button behavior

I have a project with 2 activities, the first one is the "SplashActivity" - where I load some network data - the second one, the MainActivity.
Inside of my MainActivity I have a fragment and inside of this fragment a webview. My first point is, when the user clicks on back button, the SplashScreen is open again.
The back button should behave like:
When the user doesn't navigate inside of my webview, close the app.
When the user navigates in webview, use the back history of the browswer.
I read about back stack here: http://developer.android.com/training/implementing-navigation/temporal.html#back-webviews
I didn't understand at all how it should work, because I have all cases "mixed". Anyone knows what should I do to fix this problem?
Any idea or sample code will be appreciate!
Define Webview wb as a global variable. Then try this;
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(event.getAction() == KeyEvent.ACTION_DOWN){
switch(keyCode)
{
case KeyEvent.KEYCODE_BACK:
if(wb.canGoBack() == true){
wb.goBack();
}else{
new AlertDialog.Builder(this).setIcon(android.R.drawable.ic_dialog_alert).setTitle("Application will be closed")
.setMessage("Close app?")
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
finish();
System.exit(0);
}
}).setNegativeButton("No", null).show();
}
return true;
}
}
return super.onKeyDown(keyCode, event);
}
}

Post render event in JavaFX

I'm trying to add a click event listener to the label of all column-headers of a TableView, as follows:
for (final Node header : tblView.lookupAll(".column-header > .label")) {
if ((header != null) && (header instanceof Label)) {
final Label headerLabel = (Label) header;
// ...
}
}
Now, the problem is that if I do this in the initialize()-function of the Controller, the Scenegraph is not yet rendered and the above code won't work. Hence my question: Is there some kind of a post-render event?
many thanks in advance.
There is a WINDOW_SHOWN event in javafx.stage.WindowEvents. That is not (imo) "Post render event" but you can utilize it in similar manner, by adding an event handler to the Stage (which extends from Window).
In the initialize method of controller class, get the primary stage and then:
stage.addEventHandler(WindowEvent.WINDOW_SHOWN, new EventHandler<WindowEvent>() {
#Override
public void handle(WindowEvent window) {
Platform.runLater(new Runnable() {
#Override
public void run() {
addListenerToColumnHeaders();
}
});
}
});
Hope this helps, since didn't try myself.

org.eclipse.swt.browser.Browser does not open in Eclipse RAP application

Wonder if somebody can help me with this. I am trying to open an embedded browser in an Eclipse RAP applications. All examples I have seen look something like:
link.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent event) {
try {
Browser b = new Browser(parent, SWT.NONE);
b.setText("<html><body>This is Unicode HTML content from memory</body></html>");
} catch (SWTError e) {
// Error handling here
}
}
});
That doesn't do anything (visually) though. When I replace the Browser with ExternalBrowser like so:
link.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent event) {
try {
int browserStyle = ExternalBrowser.LOCATION_BAR;
ExternalBrowser.open( "myPage", "http://www.stackoverflow.com", browserStyle );
} catch (SWTError e) {
// Error handling here
}
}
});
It works. Although not exactly as desired.
I am using Eclipse RCP 1.4.2 on OS X 10.8.2.
Any insight is highly appreciated.
When you create a new widget, you have to trigger a re-layout to make it visible. Depending on your layout, it may be sufficient to call parent.layout(). If the parent is also contained in a layout and shrunken to its preferred size, you will have to call layout() on its parent. If unsure, layout the top-level shell.

disabling sound in a single application in blackberry

I just did a dictionary application in blackberry along with a speech to text conversion support .Everything is working fine. Now i wanted to disable the sound when the user needs So how can i do it programmatically .Please help me
Try this
use the flag value as reference
if flag value is true then user click on item then it will play the sound
else sound wont play and display one dialog that Do you want enable sound with two options yes or no
if user click on yes then make flag value as true and item.setText("Voice Disable"); otherwise no action means no changes in flag
in your list item click listener write condition as following
if(flag==true)
{
write your logic to play
}
sample code is
public class app extends UiApplication{
public static void main(String[] args) {
new app().enterEventDispatcher();
}
public app() {
pushScreen(new SampleScreen());
}
}
class SampleScreen extends MainScreen
{
static boolean flag=true;
MenuItem item=null;
public SampleScreen() {
// use the flag value as reference
// if flag value is true then user click on item then it will play the sound
// else sound wont play and display one dialog that Do you want enable sound with two options yes or no
// if user click on yes then make flag value as true and item.setText("Voice Disable"); otherwise no action means no changes in flag
// in your list item click listner write condition as following
// if(flag==true)
// {
// write your logic to play
// }
// you already implement
item=new MenuItem("Voice Disable",0,100) {
public void run() {
if(flag)
{
flag=false;
item.setText("Voice Enable");
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
Dialog.inform("Voice Disable succesfully");
}
});
}else{
flag=true;
item.setText("Voice Disable");
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
Dialog.inform("Voice Enable succesfully");
}
});
}
}
};
addMenuItem(item);
}
}

Resources