I have a simple login servlet which checks the email and password if the user is registered or not , now I'm trying to work on a JavaFX app which does the same job by reading from the servlet the information, my servlet works perfect but I don't know how to interact with my servlet from JavaFX , how can I send a response from the servlet to JavaFX ? I've searched a lot but couldn't find anything
Here's my servlet :
import java.io.*;
import java.security.Principal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.ServletConfig;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
#WebServlet("/HelloServlet")
public class HelloServlet extends HttpServlet {
//int attempts = 3;
Date date;
/**
*
*/
private static final long serialVersionUID = -5498866193863633001L;
/**
* HashMap to store all users credentials
*/
private final Map<String, String> credentialsPairs = new HashMap<>();
#Override
public void init(ServletConfig config) throws ServletException {
String delimiter = ",";
String line = "";
/**
* Credentials file will be there in WEB-INF directory as it provide secured
* access only.
*/
String credentialFile = "/WEB-INF/accounts.txt";
/**
* Read the file and prepare Map with username as key and password as value We
* have put this code in init method as it is called once only that will avoid
* overhead of iterating values from file for each request
*/
InputStream is = null;
InputStreamReader isr = null;
BufferedReader br = null;
ServletContext context = config.getServletContext();
try {
/**
* Open stream of file
*/
is = context.getResourceAsStream(credentialFile);
if (is != null) {
/**
* Read the file line by line and store email as a key and password as value
*/
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
while ((line = br.readLine()) != null) {
String[] credentials = line.split(delimiter);
// credentials[0] is email and credentials[1] is password
credentialsPairs.put(credentials[0], credentials[1]);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (br != null) {
br.close();
}
if (isr != null) {
isr.close();
}
if (is != null) {
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void service(HttpServletRequest request, HttpServletResponse response) throws
IOException, ServletException {
/**
* Get user entered credentials
*/
String userEmail = request.getParameter("email");
String userPassword = request.getParameter("password");
PrintWriter out = response.getWriter();
boolean isValidUser = false;
/**
* Get value from Map for user entered email address.
*/
String password = credentialsPairs.get(userEmail);
/**
* If User with entered email address found then we will get password for that
* user
*/
if (password != null) {
/**
* Compare password entered by user with one that is retrieved from file
*/
if (password.equals(userPassword)) {
isValidUser = true;
}
}
}
HttpSession session = request.getSession();
if (isValidUser) {
//HttpSession session = request.getSession();
session.setAttribute("email", userEmail);
//request.getRequestDispatcher("welcome.jsp").include(request, response);
response.sendRedirect("welcome.jsp");
//response.setContentType("text/html");
//response.sendError(HttpServletResponse.SC_FOUND,"Hello");
}
else {
int loginAttempt;
if (session.getAttribute("loginCount") == null)
{
session.setAttribute("loginCount", 0);
loginAttempt = 0;
}
else
{
loginAttempt = (Integer) session.getAttribute("loginCount");
}
//this is 3 attempt counting from 0,1,2
if (loginAttempt >= 2 )
{
long lastAccessedTime = session.getLastAccessedTime();
date = new Date();
long currentTime = date.getTime();
long timeDiff = currentTime - lastAccessedTime;
// 20 minutes in milliseconds
if (timeDiff >= 1200000)
{
//invalidate user session, so they can try again
session.invalidate();
}
else
{
// Error message
session.setAttribute("message","You have exceeded the 3 failed login
attempt. Please try loggin in in 20 minutes.");
//request.getRequestDispatcher("fail.jsp");
out.println("You have exceeded the 3 failed login attempt. Please
try loggin in in 20 minutes.");
}
}
else
{
loginAttempt++;
int allowLogin = 3-loginAttempt;
session.setAttribute("message","loginAttempt= "+loginAttempt+". Invalid
username or password. You have "+allowLogin+" attempts remaining. Please try again!");
out.println("Invalid email or password , please try again");
final String message = "The requested page not found";
response.sendError(HttpServletResponse.SC_NOT_FOUND,message);
}
session.setAttribute("loginCount",loginAttempt);
}
}
public void destroy() {
/**
* Free up the map
*/
credentialsPairs.clear();
}
}
Here's my JavaFX code :
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class HelloApplication extends Application {
TextField tName;
TextField tPassword;
ComboBox comboBox;
Button login;
VBox vBox;
BorderPane borderPane;
URL url = null;
HttpURLConnection con = null;
int flag =0;
#Override
public void start(Stage stage) throws IOException {
stage.setTitle("login Page");
stage.setResizable(false);
setDesign();
comboBox.setOnAction(e->{
if(comboBox.getSelectionModel().isSelected(0)){
flag =0;
}else if (comboBox.getSelectionModel().isSelected(1)){
flag =1;
}
});
login.setOnAction(e->{
if(flag==0){
try {
System.out.println("get");
String name =tName.getText();
String password =tPassword.getText();
url = new URL("http://localhost:8080/try8_war_exploded/login?
email="+name+"&password="+password);
con = (HttpURLConnection)url.openConnection();
con.setRequestMethod("GET");
con.setRequestProperty("Content-Type","text/html");
con.setConnectTimeout(5000);
con.setReadTimeout(5000);
} catch(Exception c) {
c.printStackTrace();
}
}
else {
}
int status = 0;
StringBuffer data = new StringBuffer();
try {
status = con.getResponseCode();
if(status > 299) {
System.out.println("error "+status);
System.out.println(con.getErrorStream());
return;
}
BufferedReader in = new BufferedReader(new
InputStreamReader(con.getInputStream()));
String str = null;
while((str=in.readLine()) != null) data.append(str);
System.out.println("here");
System.out.println(str);
in.close();
con.disconnect();
} catch(Exception c) {
c.printStackTrace();
}
});
Scene scene =new Scene(borderPane,350,180);
stage.setScene(scene);
stage.show();
}
public void setDesign(){
borderPane = new BorderPane();
borderPane.setPadding(new Insets(20,20,20,20));
vBox = new VBox(10);
vBox.setAlignment(Pos.CENTER);
HBox hBox1 =new HBox(5);
hBox1.setAlignment(Pos.CENTER);
HBox hBox2 =new HBox(5);
hBox2.setAlignment(Pos.CENTER);
Label label1= new Label("E-mail");
tName = new TextField();
tName.setMaxWidth(150);
hBox1.getChildren().addAll(label1,tName);
Label label2= new Label("Password");
tPassword = new TextField();
tPassword.setMaxWidth(150);
hBox2.getChildren().addAll(label2,tPassword);
comboBox = new ComboBox();
comboBox.getItems().add("Get");
comboBox.getItems().add("Post");
comboBox.getSelectionModel().selectFirst();
login = new Button("Login");
vBox.getChildren().addAll(hBox1,hBox2,comboBox,login);
borderPane.setTop(vBox);
}
public static void main(String[] args) {
launch();
}
}
I'm posting the entire codes so that everything is clear
Related
I am converting my activity unto a fragment, then I received an error which I think I just need to add some code, what should I add
private class AsyncLogin extends AsyncTask<String, String, String> {
ProgressDialog pdLoading = new ProgressDialog(NotifMainActivity.this);
HttpURLConnection conn;
URL url = null;
errors are from the "NotifMainActivity.this" it says "in progress dialog cannot be applied" I have included an image for you to see the error in actual.Click here to see the image
Update. So I have change the "NotifMainActivity.this" with getActivity as suggested by sir Kashif Anwar but doing so made the function of the fragment to not work maybe you can provide me an alternative solution.
Here is the whole code of the fragment(this fragment is the activity of a recyclerview)
package com.capstone.jmilibraryapp;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
public class NotifMainActivity extends Fragment {
// CONNECTION_TIMEOUT and READ_TIMEOUT are in milliseconds
public static final int CONNECTION_TIMEOUT = 10000;
public static final int READ_TIMEOUT = 15000;
private RecyclerView mRVFishPrice;
private AdapterNotif mAdapter;
/*#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_notifmainactivity);
//Make call to AsyncTask
new AsyncLogin().execute();
}*/
View myView;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
myView = inflater.inflate(R.layout.activity_notifmainactivity, container, false);
return myView;
}
private class AsyncLogin extends AsyncTask<String, String, String> {
ProgressDialog pdLoading = new ProgressDialog(getActivity());
HttpURLConnection conn;
URL url = null;
#Override
protected void onPreExecute() {
super.onPreExecute();
//this method will be running on UI thread
pdLoading.setMessage("\tLoading...");
pdLoading.setCancelable(false);
pdLoading.show();
}
#Override
protected String doInBackground(String... params) {
try {
// Enter URL address where your json file resides
// Even you can make call to php file which returns json data
url = new URL("http://192.168.1.101/notif.php");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return e.toString();
}
try {
// Setup HttpURLConnection class to send and receive data from php and mysql
conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(READ_TIMEOUT);
conn.setConnectTimeout(CONNECTION_TIMEOUT);
conn.setRequestMethod("GET");
// setDoOutput to true as we recieve data from json file
conn.setDoOutput(true);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
return e1.toString();
}
try {
int response_code = conn.getResponseCode();
// Check if successful connection made
if (response_code == HttpURLConnection.HTTP_OK) {
// Read data sent from server
InputStream input = conn.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
StringBuilder result = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
// Pass data to onPostExecute method
return (result.toString());
} else {
return ("unsuccessful");
}
} catch (IOException e) {
e.printStackTrace();
return e.toString();
} finally {
conn.disconnect();
}
}
#Override
protected void onPostExecute(String result) {
//this method will be running on UI thread
pdLoading.dismiss();
List<DataNotif> data=new ArrayList<>();
pdLoading.dismiss();
try {
JSONArray jArray = new JSONArray(result);
// Extract data from json and store into ArrayList as class objects
for(int i=0;i<jArray.length();i++){
JSONObject json_data = jArray.getJSONObject(i);
DataNotif fishData = new DataNotif();
fishData.NotifTitle= json_data.getString("notif_Title");
fishData.NotifMessage= json_data.getString("notif_Message");
// fishData.sizeName= json_data.getString("size_name");
fishData.Date= json_data.getString("notif_date");
data.add(fishData);
}
// Setup and Handover data to recyclerview
mRVFishPrice = (RecyclerView)myView.findViewById(R.id.fishPriceList);
mAdapter = new AdapterNotif(getActivity(), data);
mRVFishPrice.setAdapter(mAdapter);
mRVFishPrice.setLayoutManager(new LinearLayoutManager(getActivity()));
} catch (JSONException e) {
Toast.makeText(getActivity(), e.toString(), Toast.LENGTH_LONG).show();
Toast.makeText(getActivity(), "There maybe some error try again",Toast.LENGTH_LONG).show();
}
}
}
}
You should use getActivity() instead of class name,
like this
ProgressDialog pd = new ProgressDialog( getActivity() );
Hope it helps!
I am making an IRC client in a javafx fxml project.
I am having difficulties understanding the structure of the project. I get the MVC pattern however i don't know where i have to position the main code part of the client(object initialisation and communication start).
I want to be able to update a textarea with a String from a serverConnection object when the server sends a message.
So where do i position the code and how do i notify my controller that it has to update its text passing the String simultaneously?
This is the application class:
package jircclient;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.util.concurrent.*;
public class JircClient extends Application
{
#Override
public void start(Stage stage) throws Exception
{
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
Scene scene = new Scene(root);
stage.setTitle("jircClient");
stage.setScene(scene);
stage.show();
System.out.println("Stage SET!");
//This is where i thought that i could write the main part of the program
//but the stage will not load unless the start method finishes
//Creating a serverConnetion is not a problem since it's only an object
//but starting the communication does not let the method we are in to exit
//since it sticks in a while loop forever until i probably cancel it using a
//button (not implemented yet)
//serverConnection server1 = new serverConnection();
//server1.startCommunication();
}
public static void main(String[] args) throws Exception
{
//In this method i cannot go further unless i close the stage-window
//The purpose of it is to launch the start method
Application.launch(args);
}
}
This is the controller class:
package jircclient;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.TextArea;
public class FXMLDocumentController implements Initializable
{
#FXML
private TextArea txt;
#FXML
private void handleButtonAction(ActionEvent event)
{
//In here i will be handling events, however i will need to have
//access to serverConnection objects
System.out.println("You clicked me!");
}
#Override
public void initialize(URL url, ResourceBundle rb)
{
}
}
This is the serverConnection class:
package jircclient;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
public class serverConnection
{
//VARIABLES
private clientInfo client;
private String server_to_connect = "someserver";
private String channel_to_connect = "#somechannel";
private String serv_resp;
private int port = 6667;
private Socket socket;
private BufferedWriter writer;
private BufferedReader reader;
private ArrayList<channel> channels;
//DEFAULT CONSTRUCTOR
public serverConnection() {client = new clientInfo("test1", "test1", "test1");}
//FULL CONSTRUCTOR
public serverConnection(String server_to_connect, int port, String channel_to_connect) throws IOException
{
client = new clientInfo("test1", "test1", "test1");
this.server_to_connect = server_to_connect;
this.port = port;
this.channel_to_connect = server_to_connect;
try
{
//Creating socket connection
this.socket = new Socket(this.server_to_connect,port);
//Socket output writer
writer = new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream()));
//Socket input writer
reader = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
serv_resp = null;
System.out.println("Connection established.");
}
catch(UnknownHostException exc)
{
System.out.println("ERROR: "+ exc.toString());
}
catch(IOException exc)
{
System.out.println("ERROR: "+ exc.toString());
}
finally
{
System.out.println("Closing connection.");
socket.close();
}
}
//server response getter
public String getServerResponse()
{
return serv_resp;
}
//Introduction to server and listen
public void startCommunication() throws IOException
{
this.socket = new Socket(this.server_to_connect,port);
writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
serv_resp = null;
writer.write("NICK " + client.getClientNickname() + "\r\n");
writer.write("USER " + client.getClientLogin() + " 0 * : " +
client.getClientRealName() + "\r\n");
while ((serv_resp = reader.readLine()) != null)
{
System.out.println(serv_resp);
//FXMLDocumentController.txt.setText(serv_resp);
if (serv_resp.indexOf("004") >= 0)
{
break;
}
else if (serv_resp.indexOf("433") >= 0)
{
System.out.println("Nickname is already in use.");
return;
}
}
//Get channel list
writer.write("LIST \r\n");
writer.flush();
//Join desired client
writer.write("JOIN " + channel_to_connect + "\r\n");
writer.flush();
//keep listening
while ((serv_resp = reader.readLine()) != null)
{
//FXMLDocumentController.txt.setText(serv_resp);
if (serv_resp.startsWith("PING "))
{
this.pingPong();
} else
{
System.out.println(serv_resp);
}
}
}
//Ping respond
public void pingPong() throws IOException
{
writer.write("PONG " + serv_resp.substring(5) + "\r\n");
writer.flush();
}
}
I believe there is no need to add the fxml document since it's big and there is no need.
I also have to state that oracle tutorials were not helpful as they only use the event handling in the controller and they don't implement any other logic.
Here is one possible way to do this:
Give your ServerConnection class a callback to call when it receives a message:
public class ServerConnection {
private Consumer<String> messageCallback ;
public void setMessageCallback(Consumer<String> messageCallback) {
this.messageCallback = mesasgeCallback ;
}
// other fields and methods as before...
public void startCommunication() throws IOException {
// code as before ...
while ((servResp = reader.readLine()) !=null) {
if (messageCallback != null) {
messageCallback.accept(servResp);
}
// etc....
}
// etc
}
}
Now instantiate your ServerConnection class from the controller and pass it a callback:
public class FXMLDocumentController {
ServerConnection serverConnection ;
// ...
public void initialize() {
serverConnection = new ServerConnection();
serverConnection.setMessageCallback(message ->
Platform.runLater(() -> txt.appendText(message+"\n")));
Thread serverThread = new Thread(() -> serverConnection.startListening());
serverThread.setDaemon(true); // thread will not stop application from exiting
serverThread.start();
}
// ...
}
the data is not getting updated in the database .
im developing a login functionality where im also registering the user. After the registration, i want to display the details that was used during registration.
im posting my code for the servlet that im using :
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class UserController extends HttpServlet {
private static final long serialVersionUID = 1L;
private static final int Id = 0;
private static final String Password = null;
private static final String Username = null;
private static final int Userid = 0;
private static String INSERT_OR_EDIT = "/user.jsp";
private static String LIST_USER = "/listUser.jsp";
public static String PARAM_USERNAME = "uname";
public static String PARAM_PASSWORD = "pass";
private UserDao dao;
private Connection connection;
public UserController() {
super();
dao = new UserDao();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
String forward="";
String act = request.getParameter("act");
if (act != null && !act.equalsIgnoreCase("null") && act.equalsIgnoreCase("login")) {
forward= "/Login.jsp";
}
else if (act != null && !act.equalsIgnoreCase("null") && act.equalsIgnoreCase("delete"))
{
int userId = Integer.parseInt(request.getParameter("userId"));
dao.deleteUser(userId);
forward = LIST_USER;
request.setAttribute("users", dao.getAllUsers());
} else if (act!=null && !act.equalsIgnoreCase("null") && act.equalsIgnoreCase("edit")){
forward = INSERT_OR_EDIT;
int userId = Integer.parseInt(request.getParameter("userId"));
User user1 = dao.getUserById(userId);
request.setAttribute("user", user1);
} else if (act!=null && !act.equalsIgnoreCase("null") && act.equalsIgnoreCase("listUser")){
forward = LIST_USER;
request.setAttribute("users", dao.getAllUsers());
} else if (act!=null && !act.equalsIgnoreCase("null") && act.equalsIgnoreCase("register")){
forward = "/reg.jsp";
// request.setAttribute("users", dao.getAllUsers());
} else
forward = "/Login.jsp";
RequestDispatcher view = request.getRequestDispatcher(forward);
view.forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out=response.getWriter();
String act = request.getParameter("act");
if (act != null && !act.equalsIgnoreCase("null") && act.equalsIgnoreCase("login")) {
String str=request.getParameter("username");
String str1=request.getParameter("password");
if(str.equalsIgnoreCase("shreya")&&str1.equalsIgnoreCase("singh"))
{
System.out.println("Login!");
request.setAttribute("users",dao.getAllUsers());
request.getRequestDispatcher("/listUser.jsp").forward(request, response);
}else
{
System.out.println("Login failed!");
}
}
else
{
}
User user = new User();
Details details = new Details();
user.setFirstName(request.getParameter("firstName"));
user.setLastName(request.getParameter("lastName"));
details.setUsername(request.getParameter("uname"));
details.setPassword(request.getParameter("pass"));
if (act != null && !act.equalsIgnoreCase("null") && act.equalsIgnoreCase("register"))
{
String userid=request.getParameter("userid");
String username=request.getParameter("username");
String password=request.getParameter("password");
String id=request.getParameter("id");
if(userid.equals("") || username.equals("") || password.equals("") || id.equals(""))
{
out.println("Please insert valid data");
}
RequestDispatcher rd = request.getRequestDispatcher("/listUser.jsp");
rd.include(request, response);
}
else
{
RequestDispatcher rd = request.getRequestDispatcher("/listUser.jsp");
rd.include(request, response);
try {
PreparedStatement preparedStatement = connection.
prepareStatement("select * from details where id=?");
preparedStatement.setInt(1, Id);
ResultSet rs = preparedStatement.executeQuery();
if (rs.next()) {
details.setUserid(rs.getInt("userid"));
details.setUsername(rs.getString("username"));
details.setPassword(rs.getString("password"));
details.setId(rs.getInt("id"));
}
PreparedStatement preparedStatement1 = connection.
prepareStatement( "insert into details values(?,?,?,?)");
preparedStatement1.setInt(1, Userid);
preparedStatement1.setString(2, Username);
preparedStatement1.setString(3, Password);
preparedStatement1.setInt(4, Id);
int i=preparedStatement1.executeUpdate();
if(i>0)
{
System.out.println("Data update sucessfully");
System.out.print("Student record successfully inserted");
RequestDispatcher rd1 = request.getRequestDispatcher("/registration.jsp");
rd1.include(request, response);
}
}
catch (Exception e)
{
System.out.println(e);
}
}
}
}
ive been stuck on this since i dont remember when . help would be appreciated.
How i can refresh listfragment? no tutorials from net work :(
i have no idea, how reload this listfragment. I tried reload by transaktionmanager, but its colide with ActionBar.TabListener, this is not support.v4. how can i retrieve new data from loadermanager and update listfragment?
Activity:
package sk.test;
import android.app.ActionBar;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.app.FragmentTransaction;
import android.support.v4.app.LoaderManager;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import java.util.List;
import java.util.Locale;
import sk.test.frags.TodoFragment;
import sk.test.prefs.EditPreferences;
import sk.test.task.DataListLoader;
import sk.test.xml.Item;
public class MainActivity extends FragmentActivity implements ActionBar.TabListener {
SectionsPagerAdapter mSectionsPagerAdapter;
/**
* The {#link ViewPager} that will host the section contents.
*/
ViewPager mViewPager;
private TodoFragment todoFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Set up the action bar.
final ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Create the adapter that will return a fragment for each of the three
// primary sections of the app.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
// When swiping between different sections, select the corresponding
// tab. We can also use ActionBar.Tab#select() to do this if we have
// a reference to the Tab.
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
});
// For each of the sections in the app, add a tab to the action bar.
for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
// Create a tab with text corresponding to the page title defined by
// the adapter. Also specify this Activity object, which implements
// the TabListener interface, as the callback (listener) for when
// this tab is selected.
actionBar.addTab(
actionBar.newTab()
.setText(mSectionsPagerAdapter.getPageTitle(i))
.setTabListener(this));
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
switch (item.getItemId()) {
case R.id.action_settings:
startActivity(new Intent(getApplicationContext(), EditPreferences.class));
return true;
case R.id.refresh:
//HERE CODE FOR RELOAD todoFragment.reloadData() ????
return true;
default:
return true;
}
}
#Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
// When the given tab is selected, switch to the corresponding page in
// the ViewPager.
mViewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
#Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
/**
* A {#link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
private boolean wantDone = false;
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
todoFragment = new TodoFragment();
this.wantDone = position == 0 ? false : true;
Bundle args = new Bundle();
args.putBoolean(TodoFragment.TASK_TYPE, this.wantDone);
todoFragment.setArguments(args);
return todoFragment;
}
#Override
public int getCount() {
return 2;
}
public boolean getWantDone(){
return this.wantDone;
}
#Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
switch (position) {
case 0:
return getString(R.string.todotask_planned).toUpperCase(l);
case 1:
return getString(R.string.todotask_done).toUpperCase(l);
}
return null;
}
}
}
ListFragment:
package sk.test;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import android.util.Log;
import android.view.View;
import android.widget.ListView;
import java.util.List;
import sk.test.adapter.CustomArrayAdapter;
import sk.test.task.DataListLoader;
import sk.test.xml.Item;
/**
* Created by Peter on 29.7.2013.
*/
public class TodoFragment extends ListFragment implements LoaderManager.LoaderCallbacks<List<Item>> {
public static String TASK_TYPE = "taskType";
private static final String XML_SOURCE = "http://******/";
private boolean wantDone = false;
CustomArrayAdapter mAdapter;
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.i("TODOLIST", "DataListFragment.onActivityCreated");
this.wantDone = getArguments().getBoolean(TASK_TYPE);
// Initially there is no data
setEmptyText("No Data Here");
// Create an empty adapter we will use to display the loaded data.
mAdapter = new CustomArrayAdapter(getActivity());
setListAdapter(mAdapter);
// Start out with a progress indicator.
setListShown(false);
// Prepare the loader. Either re-connect with an existing one,
// or start a new one.
getLoaderManager().initLoader(0, null, this);
setHasOptionsMenu(true);
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
// Insert desired behavior here.
Log.i("TODOLIST", "Item clicked: " + id);
}
#Override
public Loader<List<Item>> onCreateLoader(int i, Bundle bundle) {
Log.i("TODOLIST", "DataListFragment.onCreateLoader");
return new DataListLoader(getActivity(), this.wantDone);
}
#Override
public void onLoadFinished(Loader<List<Item>> listLoader, List<Item> items) {
mAdapter.setData(items);
Log.i("TODOLIST", "DataListFragment.onLoadFinished");
// The list should now be shown.
if (isResumed()) {
setListShown(true);
} else {
setListShownNoAnimation(true);
}
}
#Override
public void onLoaderReset(Loader<List<Item>> listLoader) {
}
public void reloadData(){
//UPDATE LIST.. HOW?
}
}
Loader:
package sk.test;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.support.v4.content.AsyncTaskLoader;
import android.util.Log;
import org.simpleframework.xml.Serializer;
import org.simpleframework.xml.core.Persister;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import sk.test.commons.Commons;
import sk.test.xml.Item;
import sk.test.xml.Response;
/**
* Created by Peter Chovan on 29.7.2013.
*/
public class DataListLoader extends AsyncTaskLoader<List<Item>> {
private List<Item> todoTasks;
private boolean wantDone;
SharedPreferences prefs;
public DataListLoader(Context context, boolean wantDone) {
super(context);
this.wantDone = wantDone;
prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
}
#Override
public List<Item> loadInBackground() {
Log.i("TODOLIST", "DataListLoader.loadInBackground");
String xmlData = getXmlData(prefs.getString("service_url", "http://*****/"));
List<Item> entries = new ArrayList<Item>();
String state = wantDone ? "WANT DONE" : "WANT PLANNED";
if (xmlData != null) {
xmlData = xmlData.replaceAll("<([^/]+?)/>", "<$1> </$1>");
Serializer serializer = new Persister();
try {
Response res = serializer.read(Response.class, xmlData, false);
for (Item i : res.getItems().getItem()) {
if (i.isDone() == wantDone) {
entries.add(i);
}
}
} catch (Exception e) {
for (StackTraceElement s : e.getStackTrace()) {
Log.e("TEST serializer", s.toString());
}
}
} else {
Log.e("TODOLIST DATA", "NULL");
}
return entries;
}
public String getXmlData(String uri) {
try {
URL url = new URL(uri);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setDoOutput(true);
con.setRequestProperty("Accept", "application/xml");
Map<String, String> params = new HashMap<String, String>();
params.put("user", prefs.getString("service_login", "devel"));
params.put("pass", prefs.getString("service_password", "devel"));
params.put("class", "GetList");
OutputStreamWriter wr = new OutputStreamWriter(con.getOutputStream());
wr.write(Commons.getRequestData(params)); //add request params
wr.flush();
String xmlData = readStream(con.getInputStream());
wr.close();
con.disconnect();
return xmlData;
} catch (Exception e) {
for (StackTraceElement s : e.getStackTrace()) {
Log.e("TODOLIST", "doInBackground" + s.toString());
}
}
return null;
}
private String readStream(InputStream in) {
BufferedReader reader = null;
String result = "";
try {
reader = new BufferedReader(new InputStreamReader(in));
String line;
while ((line = reader.readLine()) != null) {
result += line + "\n";
}
return result;
} catch (IOException e) {
for (StackTraceElement s : e.getStackTrace()) {
Log.e("TODOLIST", "ReadStream || " + s.toString());
}
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
for (StackTraceElement s : e.getStackTrace()) {
Log.e("TODOLIST", "ReadStream || " + "Error while closing Reader");
}
}
}
}
return null;
}
/**
* Called when there is new data to deliver to the client. The
* super class will take care of delivering it; the implementation
* here just adds a little more logic.
*/
#Override
public void deliverResult(List<Item> listOfData) {
if (isReset()) {
// An async query came in while the loader is stopped. We
// don't need the result.
if (listOfData != null) {
onReleaseResources(listOfData);
}
}
List<Item> oldApps = listOfData;
todoTasks = listOfData;
if (isStarted()) {
// If the Loader is currently started, we can immediately
// deliver its results.
super.deliverResult(listOfData);
}
// At this point we can release the resources associated with
// 'oldApps' if needed; now that the new result is delivered we
// know that it is no longer in use.
if (oldApps != null) {
onReleaseResources(oldApps);
}
}
/**
* Handles a request to start the Loader.
*/
#Override
protected void onStartLoading() {
if (todoTasks != null) {
// If we currently have a result available, deliver it
// immediately.
deliverResult(todoTasks);
}
if (takeContentChanged() || todoTasks == null) {
// If the data has changed since the last time it was loaded
// or is not currently available, start a load.
forceLoad();
}
}
/**
* Handles a request to stop the Loader.
*/
#Override
protected void onStopLoading() {
// Attempt to cancel the current load task if possible.
cancelLoad();
}
/**
* Handles a request to cancel a load.
*/
#Override
public void onCanceled(List<Item> apps) {
super.onCanceled(apps);
// At this point we can release the resources associated with 'apps'
// if needed.
onReleaseResources(apps);
}
/**
* Handles a request to completely reset the Loader.
*/
#Override
protected void onReset() {
super.onReset();
// Ensure the loader is stopped
onStopLoading();
// At this point we can release the resources associated with 'apps'
// if needed.
if (todoTasks != null) {
onReleaseResources(todoTasks);
todoTasks = null;
}
}
/**
* Helper function to take care of releasing resources associated
* with an actively loaded data set.
*/
protected void onReleaseResources(List<Item> apps) {
}
}
Use this to restart the Loader: getLoaderManager().restartLoader(0, null, this);
This is a class for a simple stopwatch for JavaFX, style the Label object as desired
package aaa;
import java.text.SimpleDateFormat;
import java.util.Date;
import javafx.beans.property.SimpleStringProperty;
/**
*
* #author D07114915
*/
public class KTimer extends Thread {
private Thread thread = null;
private SimpleDateFormat sdf = new SimpleDateFormat("mm:ss:S");
private String[] split;
private SimpleStringProperty min, sec, millis, sspTime;
private long time;
public static void main(String[] args) {
KTimer t = new KTimer();
t.startTimer(00);
}
public KTimer() {
min = new SimpleStringProperty("00");
sec = new SimpleStringProperty("00");
millis = new SimpleStringProperty("00");
sspTime = new SimpleStringProperty("00:00:00");
}
public void startTimer(long time) {
this.time = time;
thread = new Thread(this);
thread.setPriority(Thread.MIN_PRIORITY);
thread.start();
}
public void stopTimer(long time) {
if (thread != null) {
thread.interrupt();
}
this.time = time;
setTime(time);
}
public void setTime(long time) {
this.time = time;
split = sdf.format(new Date(time)).split(":");
min.set(split[0]);
sec.set(split[1]);
if (split[2].length() == 1) {
split[2] = "0" + split[2];
}
millis.set(split[2].substring(0, 2));
sspTime.set(min.get() + ":" + sec.get() + ":" + millis.get());
}
public long getTime() {
return time;
}
public SimpleStringProperty getSspTime() {
return sspTime;
}
#Override
public void run() {
try {
while (!thread.isInterrupted()) {
setTime(time);
sleep(10);
time = time + 10;
}
} catch (Exception e) {
}
}
}//end of class
Now just get a listener on the property for your GUI
Add vars
KTimer ktimer;
Label timeLabel;
in your class initialize the vars
//Clock
ktimer = new KTimer();
timeLabel = new Label(ktimer.getSspTime().get());
ktimer.getSspTime().addListener(new InvalidationListener() {
#Override
public void invalidated(Observable observable) {
timeLabel.setText(ktimer.getSspTime().get());
}
});
then call the method to start and stop wherever you need to
Stop and reset is
ktimer.stopTimer(0);
Start and Pause timer is
ktimer.startTimer(ktimer.getTime());
Any improvements appreciated as the class is a bit CPU hungry..., but you can adjust the run thread and setTime(time) functions to suit the application
Here's a slightly different version (maybe better) and I'm not sure the synchronized methods are really necessary
package aaa;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import javafx.beans.property.SimpleStringProperty;
/**
*
* #author D07114915
*/
public class KTimer {
private SimpleDateFormat sdf = new SimpleDateFormat("mm:ss:S");
private String[] split;
private SimpleStringProperty sspTime;
private long time;
private Timer t = new Timer("Metronome", true);
private TimerTask tt;
boolean timing = false;
public KTimer() {
sspTime = new SimpleStringProperty("00:00:00");
}
public void startTimer(final long time) {
this.time = time;
timing = true;
tt = new TimerTask() {
#Override
public void run() {
if (!timing) {
try {
tt.cancel();
} catch (Exception e) {
e.printStackTrace();
}
} else {
updateTime();
}
}
};
t.scheduleAtFixedRate(tt, 10, 10);
}
public synchronized void stopTimer() {
timing = false;
}
public synchronized void updateTime() {
this.time = this.time + 10;
split = sdf.format(new Date(this.time)).split(":");
sspTime.set(split[0] + ":" + split[1] + ":" + (split[2].length() == 1 ? "0" + split[2] : split[2].substring(0, 2)));
}
public synchronized void moveToTime(long time) {
stopTimer();
this.time = time;
split = sdf.format(new Date(time)).split(":");
sspTime.set(split[0] + ":" + split[1] + ":" + (split[2].length() == 1 ? "0" + split[2] : split[2].substring(0, 2)));
}
public synchronized long getTime() {
return time;
}
public synchronized SimpleStringProperty getSspTime() {
return sspTime;
}
}
Building on KEV's answer and various demos I found across the internet, here's a simple "count up" timer with 100ms precision:
package fxtimer;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.util.Duration;
public class FXTimer extends Application {
private Timeline timeline;
private Label timerLabel = new Label(), splitTimerLabel = new Label();
private DoubleProperty timeSeconds = new SimpleDoubleProperty(),
splitTimeSeconds = new SimpleDoubleProperty();
private Duration time = Duration.ZERO, splitTime = Duration.ZERO;
#Override
public void start(Stage primaryStage) {
// Configure the Label
// Bind the timerLabel text property to the timeSeconds property
timerLabel.textProperty().bind(timeSeconds.asString());
timerLabel.setTextFill(Color.RED);
timerLabel.setStyle("-fx-font-size: 4em;");
splitTimerLabel.textProperty().bind(splitTimeSeconds.asString());
splitTimerLabel.setTextFill(Color.BLUE);
splitTimerLabel.setStyle("-fx-font-size: 4em;");
// Create and configure the Button
Button button = new Button();
button.setText("Start / Split");
button.setOnAction(new EventHandler() {
#Override
public void handle(Event event) {
if (timeline != null) {
splitTime = Duration.ZERO;
splitTimeSeconds.set(splitTime.toSeconds());
} else {
timeline = new Timeline(
new KeyFrame(Duration.millis(100),
new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent t) {
Duration duration = ((KeyFrame)t.getSource()).getTime();
time = time.add(duration);
splitTime = splitTime.add(duration);
timeSeconds.set(time.toSeconds());
splitTimeSeconds.set(splitTime.toSeconds());
}
})
);
timeline.setCycleCount(Timeline.INDEFINITE);
timeline.play();
}
}
});
// Setup the Stage and the Scene (the scene graph)
StackPane root = new StackPane();
Scene scene = new Scene(root, 300, 250);
// Create and configure VBox
// gap between components is 20
VBox vb = new VBox(20);
// center the components within VBox
vb.setAlignment(Pos.CENTER);
// Make it as wide as the application frame (scene)
vb.setPrefWidth(scene.getWidth());
// Move the VBox down a bit
vb.setLayoutY(30);
// Add the button and timerLabel to the VBox
vb.getChildren().addAll(button, timerLabel, splitTimerLabel);
// Add the VBox to the root component
root.getChildren().add(vb);
primaryStage.setTitle("FX Timer");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}