Why JavaFX stucks when running a process? - mysql

I am building an application using JavaFX. Application does some CRUD operations with the MySQL Database. So currently, I have 2 functions.
User Registration.
Email Validation (Check if email already exists in the database).
User registration is called in a JFoenix Button event. When it clicked it is calling separate 3 functions in another class as follows,
public static int insertUser(User user) {
int status = 0;
try {
Connection con = DbConnection.getConnection();
PreparedStatement ps = con.prepareStatement("INSERT INTO users (name, password, email, country) VALUES (?, ?, ?, ?)");
ps.setString(1, user.getName());
ps.setString(2, user.getPassword());
ps.setString(3, user.getEmail());
ps.setString(4, user.getCountry());
status = ps.executeUpdate();
con.close();
}catch(Exception ex) {
ex.printStackTrace();
}
return status;
}
public static int updateTime(String email, String timestamp) {
int status = 0;
try {
Connection con = DbConnection.getConnection();
PreparedStatement ps = con.prepareStatement("UPDATE users SET timestamp = ? WHERE email = ?");
ps.setString(1, timestamp);
ps.setString(2, email);
status = ps.executeUpdate();
con.close();
}catch(Exception ex) {
ex.printStackTrace();
}
return status;
}
The problem is when I click the Button I see it is getting stuck while running that process. So I put that code inside the following,
Platform.runLater(() -> {
try {
} catch (Exception ex) {
Exceptions.printStackTrace(ex);
}
});
Now it is somewhat okay but I see it is getting a little stuck after clicking (Ripple effect is not working well and also the mouse hover effect is not working as usual).
And Email Validation is done when the user types an email in the text field and the key released event is triggered and it is checking for the database result. The code for checking email is as follows,
public static boolean emailAvailability(String email) {
boolean status = false;
try {
Connection con = DbConnection.getConnection();
PreparedStatement ps = con.prepareStatement("SELECT email FROM users WHERE email = ?");
ps.setString(1, email);
ResultSet rs = ps.executeQuery();
status = rs.next();
con.close();
}catch(Exception ex) {
ex.printStackTrace();
}
return status;
}
In the key event also it is getting stuck more. Can't type a character for some milliseconds.
I don't see any issue with my code because I have done this many times with Java Swing and all are perfectly working fine in Swing. And if a button is getting stuck with the running process I just put those codes inside the following and it works perfect,
new Thread(new Runnable() {
public void run() {
}
}).start();
I am not going to or trying to compare Java Swing and JavaFX But I need to know why JavaFX is behaving like this? What should I do to avoid this and run the program smoothly with the CSS effects if it is a huge process or not? Really appreciate it if anybody can help me. Thanks in advance.
UPDATE
Here is my signUp code. Executes when button clicks,
private void signUp(ActionEvent event) {
if (name.getText.equals("") && name.getText().isEmpty()) {
if (!name.getStyleClass().contains("error-class")) {
name.getStyleClass().add("error-class");
nameImageValidation.setImage(new Image("danger.png"));
nameImageValidation.setVisible(true);
}
} else {
name.getStyleClass().removeIf(style -> style.equals("error-class"));
nameImageValidation.setVisible(false);
}
if (password.getText.equals("") && password.getText().isEmpty()) {
if (!password.getStyleClass().contains("error-class")) {
password.getStyleClass().add("error-class");
passwordImageValidation.setImage(new Image("danger.png"));
passwordImageValidation.setVisible(false);
}
} else {
password.getStyleClass().removeIf(style -> style.equals("error-class"));
passwordImageValidation.setVisible(false);
}
if (email.getText.equals("") && email.getText().isEmpty()) {
if (!email.getStyleClass().contains("error-class")) {
email.getStyleClass().add("error-class");
emailImageValidation.setImage(new Image("danger.png"));
emailImageValidation.setVisible(false);
}
} else {
email.getStyleClass().removeIf(style -> style.equals("error-class"));
emailImageValidation.setVisible(false);
}
if (country.getText.equals("") && country.getText().isEmpty()) {
if (!country.getStyleClass().contains("error-class")) {
country.getStyleClass().add("error-class");
countryImageValidation.setImage(new Image("danger.png"));
countryImageValidation.setVisible(false);
}
} else {
country.getStyleClass().removeIf(style -> style.equals("error-class"));
countryImageValidation.setVisible(false);
}
if(emailValidation() && passwordValidation() && fieldsValidation()) {
User user = new User(name.getText(), email.getText(), password.getText(), country.getText());
int insertStatus = UserController.insertUser(user);
Timestamp timestamp = new Timestamp(System.currentTimeMillis());
if (insertStatus > 0) {
int updateStatus = UserController.updateTime(email.getText(), timestamp.toString());
if(updateStatus > 0) {
// Go to Login Page
} else {
showAlert(); // Error Message
}
} else {
showAlert(); // Error Message
}
} else {
showAlert(); // Error Message
}
}
Here the validateEmail code. Executes when user typing the email. Triggered when Key Released and when performing this after type a character have to wait some time and then appear next character and go...
private void validateEmail(KeyEvent event) {
boolean status = UserController.emailAvailability(email.getText());
if (!status) {
email.getStyleClass().removeIf(style -> style.equals("success-class"));
emailImageValidation.setImage(new Image("safe.png"));
emailImageValidation.setVisible(true);
} else {
email.getStyleClass().removeIf(style -> style.equals("error-class"));
emailImageValidation.setImage(new Image("danger.png"));
emailImageValidation.setVisible(true);
}
}

When you trigger a function from the GUI, execution happens in the main thread. Now, these calls are blocking, which means that until they return, the main thread can't update the GUI.
There are generally two ways to solve this:
Async functions, that yield (allows other code to run) until the resource they are waiting for become available
Threads, which means running part of the program in parrallel, which most likely will require you to think about locks etc.
I suggest you look into these two things, as they are quite central to making good apps that are connected to other services and IO

Related

If I want to connect to the database it crashes?

using System;
using Xamarin.Forms;
using UIKit;
using MySql.Data.MySqlClient;
namespace test.project
{
public partial class ViewController : UIViewController
{
partial void UIButton197_TouchUpInside(UIButton sender)
{
if (textBoxName.Text == "" || textBoxpasswd.Text == "")
{
var alert = UIAlertController.Create("Fehler", "Bitte geben sie Benutzername und Password ein", UIAlertControllerStyle.Alert);
alert.AddAction(UIAlertAction.Create("Ok", UIAlertActionStyle.Default, null));
PresentViewController(alert, true, null);
// Fehlerüberprüfung wenn leer ist
}
else
{
try
{
MySqlConnection con = new MySqlConnection("Server=localhost;Port=8889;database=app;User Id=root;Password=;charset=utf8");
if (con.State == System.Data.ConnectionState.Closed)
{
con.Open();
MySqlCommand cmd = new MySqlCommand("INSERT INTO users(id, username, passwd, rank) VALUES(#user, #pass, #rank)", con);
cmd.Parameters.AddWithValue("#user", textBoxName.Text);
cmd.Parameters.AddWithValue("#pass", textBoxpasswd.Text);
cmd.Parameters.AddWithValue("#rank", 0);
cmd.ExecuteNonQuery();
errorLabel.Text = "ausgeführt";
}
else
{
errorLabel.Text = "no connection";
}
}
catch
{
errorLabel.Text = "catch";
}
}
}
protected ViewController(IntPtr handle) : base(handle)
{
// Note: this .ctor should not contain any initialization logic.
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
// Perform any additional setup after loading the view, typically from a nib.
}
public override void DidReceiveMemoryWarning()
{
base.DidReceiveMemoryWarning();
// Release any cached data, images, etc that aren't in use.
}
}
}
I try to. connect to the the Database but afte the line con.open the Programm crashes
There is obviously an issue with establishing a connection to the database.
You have defined the server as: Server=localhost
Is this absolutely correct? I highly doubt that you are running a full MySQL server on the device itself? If you are running the server on the device, is the server process running?
What is the execption that the application closes with?
CONNECTION_TIMEOUT? Probably a firewall issue
CONNECTION_REFUSED? The MySQL server process is not running.
You should also design your application to be hardened against database failures, maybe wrapping the connection with a try:
try {
connection.open();
} catch (Exception e) {
// TODO handle the connection error properly
System.err.println("An error has occurred.");
e.printStackTrace();
}

how to see new inserted data in textbox ? (java netbeans mysql)

I have a MySQL database in NetBeans.
When I add new data in my database by insert button, I can see my new data in output windows (because I have a code to print all data in database), but I don't know why I can't see my new data in textboxes, it means when I navigate fields by next, previous buttons I can't see my new data !!!!!!
But, when I close the program and run it again, my textboxes show my new data !
What's reason???????
my Next button code :
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
try {
if (rs.next()) {
int x = Integer.parseInt(rs.getString("id"));
String s = rs.getString("name");
String n = rs.getString("profession");
txtID.setText(Integer.toString(x));
txtName.setText(s);
txtProfession.setText(n);
} else {
rs.previous();
}
} catch (Exception e) {
System.out.println(e);
}
}
My insert button code :
private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
try {
Statement st = con.createStatement();
st.executeUpdate("INSERT INTO sample (id,name,profession) VALUES ('"+txtID.getText()+"','"+txtName.getText()+"','"+txtProfession.getText()+"');");
st.executeQuery("Select * from sample");
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
Help me please.
assuming ResultSet rs is a class level variable, with in your method jButton3ActionPerformed() change the following
st.executeQuery("Select * from sample");
to
rs = st.executeQuery("Select * from sample");
one suggestion is, you should close your database resources once you fetch the data and you can construct your Collection to hold the data for further processing.
The pagination that you are trying to use is not good practice

Thread.sleep inside IntentService causes ANRs

I have IntentService that I use to upload data to server. When this upload goes wrong (sometimes when the user does not have reception or Internet connection) then I use exponential backoff to try and upload the information again and again. I do this inside the onHandleIntent method, which to my understanding runs in separate thread:
#Override
protected void onHandleIntent(Intent intent) {
Bundle extras = intent.getExtras();
if (extras != null) {
WebPostsRest posts = new WebPostsRest(HTTPVerb.POST, Uri.parse(CONSTS_WEB.URI_POST_NEW_POST), extras, this);
double backoffMillis = 0;
int backoffexp = 0;
int iTries = CONSTS_APP_GENERAL.NO_OF_POST_TRIES;
while (iTries > 0) {
mIsSuccess = posts.runRestNoReturnData();
if (mIsSuccess) {
iTries = 0;
} else {
if (backoffexp < 11) {
backoffMillis = Math.pow(2, backoffexp) * 1000;
backoffexp++;
}
try {
Thread.sleep((int) backoffMillis);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
iTries--;
}
}
}
}
For some reason I get ANRs, which I assume come from this Thread.sleep part. Any idea why it happens and how to solve things? thank you.
I had the same problem and in my case it was causing by queue for the IntentService. Make sure you are not calling this intent service multiple times. It seems if first call of IntentService fail and use Thread.sleep() and at the same time more request are in waiting mode to use this IntentService then it throws ANR.

WebException thrown when locking screen of the Emulator (WindowsPhone8)

I have a webrequest to get a xml.That works great but when i press F12(lock screen) while the the server is requested by my app...I got a WebException.
I use a taskCompeltionSource object...Here is my code
public async Task<String> Query(DataRequestParam dataRequestParam)
{
_dataRequestParam = dataRequestParam;
try
{
Result = "";
Result = await myDownloadString(dataRequestParam);
}
catch (WebException we)//ERROR IS CAUGHT HERE
{
throw new WebException(we.Message);
}
catch (Exception ex)
{
throw new MyException(ex.Message);
}
return Result;
}
public static Task<string> myDownloadString(DataRequestParam dataRequestParam)
{
var tcs = new TaskCompletionSource<string>();
var web = new WebClient();
if (!string.IsNullOrEmpty(dataRequestParam.AuthentificationLogin))
{
System.Net.NetworkCredential account = new NetworkCredential(dataRequestParam.AuthentificationLogin, dataRequestParam.AuthentificationPassword);
web.Credentials = account;
}
web.DownloadStringCompleted += (s, e) =>
{
if (e.Error != null) tcs.TrySetException(e.Error);
else if (e.Cancelled) tcs.TrySetCanceled();
else tcs.TrySetResult(e.Result);
};
web.DownloadStringAsync(dataRequestParam.TargetUri);
return tcs.Task;
}
If you haven't disabled ApplisationIdleDetection, your process is stopped while entering Lock screen - thus you probably get the exception - like I've said in comment. Disabling will solve this issue, but you must be aware of few things:
you will still get the exception when hitting Start Button (or other case putting your app to dormant state). In this case your app is stopped and there is no way to prevent this behaviour.
you must fulfill certification requirements when disabling App Idle Detection - point 6.3
if you want to download files in the Background (lock screen, after closing/leaving app) then you can think of Background Transfers

NullPointerException error on Implementing Location API on J2me

I am trying to implement jsr-179 APi into Nokia Symbian phone for periodic location update using setLocationListener through J2me. In emulator it is working fine. While I installed Midlet on the device nokia 5230, it is given NullPointerException and the application is automatically terminating. What might be possible causes?
Below is my class, I am instantiating object for this class on a form in netbeans
class MovementTracker implements LocationListener {
LocationProvider provider;
Location lastValidLocation;
UpdateHandler handler;
boolean done;
public MovementTracker() throws LocationException
{
done = false;
handler = new UpdateHandler();
new Thread(handler).start();
//Defining Criteria for Location Provider
/*
Criteria cr = new Criteria();
cr.setHorizontalAccuracy(500);
*/
//you can place cr inside getInstance
provider = LocationProvider.getInstance(null);
//listener,interval,timeout,int maxAge
//Passing -1 selects default interval
// provider.setLocationListener(MovementTracker.this, -1, -1, -1);
provider.setLocationListener(MovementTracker.this, -1, 30000, 30000);
}
public void locationUpdated(LocationProvider provider, Location location)
{
handler.handleUpdate(location);
batteryLevel = System.getProperty("com.nokia.mid.batterylevel");
sn = System.getProperty("com.nokia.mid.networksignal");
localTime = System.currentTimeMillis();
Send_Location();
}
public void providerStateChanged(LocationProvider provider, int newState)
{
}
class UpdateHandler implements Runnable
{
private Location updatedLocation = null;
// The run method performs the actual processing of the location
public void run()
{
Location locationToBeHandled = null;
while (!done)
{
synchronized(this)
{
if (updatedLocation == null)
{
try
{
wait();
}
catch (Exception e)
{
// Handle interruption
}
}
locationToBeHandled = updatedLocation;
updatedLocation = null;
}
// The benefit of the MessageListener is here.
// This thread could via similar triggers be
// handling other kind of events as well in
// addition to just receiving the location updates.
if (locationToBeHandled != null)
processUpdate(locationToBeHandled);
}
try
{
Thread.sleep(10000); //Sleeps for 10 sec & then sends the data
}
catch (InterruptedException ex)
{
}
}
public synchronized void handleUpdate(Location update)
{
updatedLocation = update;
notify();
}
private void processUpdate(Location update)
{
latitude = update.getQualifiedCoordinates().getLatitude();
longitude = update.getQualifiedCoordinates().getLongitude();
altitude = update.getQualifiedCoordinates().getAltitude();
}
}
}
public MovementTracker() throws LocationException
...
I have not written any code for handling LocationException.
No code is very dangerous practice, just search the web for something like "java swallow exceptions".
It is quite possible that because of implementation specifics Nokia throws LocationException where emulator does not throw it. Since you don't handle exception this may indeed crash you midlet at Nokia - and you wouldn't know the reason for that because, again, you have written no code to handle it.
How can I catch that exception?
The simplest thing you can do is to display an Alert with exception message and exit the midlet after user reads and dismisses alert