i wanna ask you exactly about the action that when i click on the button, the result will be inserted directly and automatically into their "input id" ... how can i do it in the android??
Well, if you are not familiar with Android, then I will advise you to take some tutorials about Android basics and Java.
Apart from that, Android does provide geocoding functionality, you should have latitude and longitude to run the following code:
Geocoder geocoder;
List<Address> addresses;
geocoder = new Geocoder(this, Locale.getDefault());
addresses = geocoder.getFromLocation(latitude, longitude, 1); // Here 1 represent max location result to returned, by documents it recommended 1 to 5
String address = addresses.get(0).getAddressLine(0);
String city = addresses.get(0).getLocality();
String state = addresses.get(0).getAdminArea();
String country = addresses.get(0).getCountryName();
String postalCode = addresses.get(0).getPostalCode();
String knownName = addresses.get(0).getFeatureName();
If you don't have the latitude and longitude of the user and wanted to access it also from an android device, you can use the following process:
AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Activity
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.TextView;
public class MainActivity extends Activity {
TextView textview;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.geo_locations);
// check if GPS enabled
GPSTracker gpsTracker = new GPSTracker(this);
if (gpsTracker.getIsGPSTrackingEnabled())
{
String stringLatitude = String.valueOf(gpsTracker.latitude);
textview = (TextView)findViewById(R.id.fieldLatitude);
textview.setText(stringLatitude);
String stringLongitude = String.valueOf(gpsTracker.longitude);
textview = (TextView)findViewById(R.id.fieldLongitude);
textview.setText(stringLongitude);
String country = gpsTracker.getCountryName(this);
textview = (TextView)findViewById(R.id.fieldCountry);
textview.setText(country);
String city = gpsTracker.getLocality(this);
textview = (TextView)findViewById(R.id.fieldCity);
textview.setText(city);
String postalCode = gpsTracker.getPostalCode(this);
textview = (TextView)findViewById(R.id.fieldPostalCode);
textview.setText(postalCode);
String addressLine = gpsTracker.getAddressLine(this);
textview = (TextView)findViewById(R.id.fieldAddressLine);
textview.setText(addressLine);
}
else
{
// can't get location
// GPS or Network is not enabled
// Ask user to enable GPS/network in settings
gpsTracker.showSettingsAlert();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.varna_lab_geo_locations, menu);
return true;
}
}
GPS Tracker
import java.io.IOException;
import java.util.List;
import java.util.Locale;
import android.app.AlertDialog;
import android.app.Service;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings;
import android.util.Log;
/**
* Create this Class from tutorial :
* http://www.androidhive.info/2012/07/android-gps-location-manager-tutorial
*
* For Geocoder read this : http://stackoverflow.com/questions/472313/android-reverse-geocoding-getfromlocation
*
*/
public class GPSTracker extends Service implements LocationListener {
// Get Class Name
private static String TAG = GPSTracker.class.getName();
private final Context mContext;
// flag for GPS Status
boolean isGPSEnabled = false;
// flag for network status
boolean isNetworkEnabled = false;
// flag for GPS Tracking is enabled
boolean isGPSTrackingEnabled = false;
Location location;
double latitude;
double longitude;
// How many Geocoder should return our GPSTracker
int geocoderMaxResults = 1;
// The minimum distance to change updates in meters
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters
// The minimum time between updates in milliseconds
private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute
// Declaring a Location Manager
protected LocationManager locationManager;
// Store LocationManager.GPS_PROVIDER or LocationManager.NETWORK_PROVIDER information
private String provider_info;
public GPSTracker(Context context) {
this.mContext = context;
getLocation();
}
/**
* Try to get my current location by GPS or Network Provider
*/
public void getLocation() {
try {
locationManager = (LocationManager) mContext.getSystemService(LOCATION_SERVICE);
//getting GPS status
isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
//getting network status
isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
// Try to get location if you GPS Service is enabled
if (isGPSEnabled) {
this.isGPSTrackingEnabled = true;
Log.d(TAG, "Application use GPS Service");
/*
* This provider determines location using
* satellites. Depending on conditions, this provider may take a while to return
* a location fix.
*/
provider_info = LocationManager.GPS_PROVIDER;
} else if (isNetworkEnabled) { // Try to get location if you Network Service is enabled
this.isGPSTrackingEnabled = true;
Log.d(TAG, "Application use Network State to get GPS coordinates");
/*
* This provider determines location based on
* availability of cell tower and WiFi access points. Results are retrieved
* by means of a network lookup.
*/
provider_info = LocationManager.NETWORK_PROVIDER;
}
// Application can use GPS or Network Provider
if (!provider_info.isEmpty()) {
locationManager.requestLocationUpdates(
provider_info,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES,
this
);
if (locationManager != null) {
location = locationManager.getLastKnownLocation(provider_info);
updateGPSCoordinates();
}
}
}
catch (Exception e)
{
//e.printStackTrace();
Log.e(TAG, "Impossible to connect to LocationManager", e);
}
}
/**
* Update GPSTracker latitude and longitude
*/
public void updateGPSCoordinates() {
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
/**
* GPSTracker latitude getter and setter
* #return latitude
*/
public double getLatitude() {
if (location != null) {
latitude = location.getLatitude();
}
return latitude;
}
/**
* GPSTracker longitude getter and setter
* #return
*/
public double getLongitude() {
if (location != null) {
longitude = location.getLongitude();
}
return longitude;
}
/**
* GPSTracker isGPSTrackingEnabled getter.
* Check GPS/wifi is enabled
*/
public boolean getIsGPSTrackingEnabled() {
return this.isGPSTrackingEnabled;
}
/**
* Stop using GPS listener
* Calling this method will stop using GPS in your app
*/
public void stopUsingGPS() {
if (locationManager != null) {
locationManager.removeUpdates(GPSTracker.this);
}
}
/**
* Function to show settings alert dialog
*/
public void showSettingsAlert() {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);
//Setting Dialog Title
alertDialog.setTitle(R.string.GPSAlertDialogTitle);
//Setting Dialog Message
alertDialog.setMessage(R.string.GPSAlertDialogMessage);
//On Pressing Setting button
alertDialog.setPositiveButton(R.string.action_settings, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which)
{
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
mContext.startActivity(intent);
}
});
//On pressing cancel button
alertDialog.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which)
{
dialog.cancel();
}
});
alertDialog.show();
}
/**
* Get list of address by latitude and longitude
* #return null or List<Address>
*/
public List<Address> getGeocoderAddress(Context context) {
if (location != null) {
Geocoder geocoder = new Geocoder(context, Locale.ENGLISH);
try {
/**
* Geocoder.getFromLocation - Returns an array of Addresses
* that are known to describe the area immediately surrounding the given latitude and longitude.
*/
List<Address> addresses = geocoder.getFromLocation(latitude, longitude, this.geocoderMaxResults);
return addresses;
} catch (IOException e) {
//e.printStackTrace();
Log.e(TAG, "Impossible to connect to Geocoder", e);
}
}
return null;
}
/**
* Try to get AddressLine
* #return null or addressLine
*/
public String getAddressLine(Context context) {
List<Address> addresses = getGeocoderAddress(context);
if (addresses != null && addresses.size() > 0) {
Address address = addresses.get(0);
String addressLine = address.getAddressLine(0);
return addressLine;
} else {
return null;
}
}
/**
* Try to get Locality
* #return null or locality
*/
public String getLocality(Context context) {
List<Address> addresses = getGeocoderAddress(context);
if (addresses != null && addresses.size() > 0) {
Address address = addresses.get(0);
String locality = address.getLocality();
return locality;
}
else {
return null;
}
}
/**
* Try to get Postal Code
* #return null or postalCode
*/
public String getPostalCode(Context context) {
List<Address> addresses = getGeocoderAddress(context);
if (addresses != null && addresses.size() > 0) {
Address address = addresses.get(0);
String postalCode = address.getPostalCode();
return postalCode;
} else {
return null;
}
}
/**
* Try to get CountryName
* #return null or postalCode
*/
public String getCountryName(Context context) {
List<Address> addresses = getGeocoderAddress(context);
if (addresses != null && addresses.size() > 0) {
Address address = addresses.get(0);
String countryName = address.getCountryName();
return countryName;
} else {
return null;
}
}
#Override
public void onLocationChanged(Location location) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
Some tutorials:
https://www.androidhive.info/2012/07/android-gps-location-manager-tutorial/
https://www.tutorialspoint.com/android/android_location_based_services.htm
https://www.rishabhsoft.com/blog/android-geocoding-and-reverse-geocoding
https://developers.google.com/maps/documentation/geocoding/start
https://www.tutorialspoint.com/android/android_location_based_services.htm
Related
I implemented Drag and Drop feature as recommended in other threads in this forum. I have a cellFactory on a TreeView and set the events on the cells.
tvProject.setCellFactory(new Callback<TreeView<PlanningItem>, TreeCell<PlanningItem>>() {
#Override
public PlanningCheckBoxTreeCell call(TreeView<PlanningItem> siTreeView) {
final PlanningCheckBoxTreeCell source = new PlanningCheckBoxTreeCell();
final PlanningCheckBoxTreeCell target = new PlanningCheckBoxTreeCell();
source.setOnDragDetected(new EventHandler<MouseEvent>() {
public void handle(MouseEvent event) {
/* drag was detected, start drag-and-drop gesture */
System.out.println("onDragDetected");
/* allow any transfer mode */
Dragboard db = source.startDragAndDrop(TransferMode.ANY);
/* put a string on dragboard */
ClipboardContent content = new ClipboardContent();
content.putString(source.getText());
db.setContent(content);
event.consume();
}
});
target.setOnDragOver(new EventHandler<DragEvent>() {
public void handle(DragEvent event) {
/* data is dragged over the target */
System.out.println("onDragOver");
...
event.consume();
}
});
The setOnDragDetected is executed/hit as wanted but all other events are NOT (I did not post them all here: setOnDragOver,setOnDragEntered,setOnDragExited,setOnDragDropped,setOnDragDone).
The PlanningCheckBoxTreeCell is a custom implementation of a treecell as follows:
public class PlanningCheckBoxTreeCell extends CheckBoxTreeCell<PlanningItem> {
public PlanningCheckBoxTreeCell() {
}
#Override
public void updateItem(PlanningItem item, boolean empty) {
super.updateItem(item, empty);
if (!empty) {
setText(null);
}
}
}
UPDATE PlanningItem:
package at.v2c2.testplaygroundui;
import java.io.Serializable;
public class PlanningItem implements Serializable {
private static final long serialVersionUID = 1L;
private Double scene = null;
private Integer path = null;
private String move = null;
/**
* #return the scene
*/
public Double getScene() {
return scene;
}
/**
* #param scene the scene to set
*/
private void setScene(Double scene) {
this.scene = scene;
}
/**
* #return the path
*/
public Integer getPath() {
return path;
}
/**
* #param path the path to set
*/
private void setPath(Integer path) {
this.path = path;
}
/**
* #return the move
*/
public String getMove() {
return move;
}
/**
* #param move the move to set
*/
private void setMove(String move) {
this.move = move;
}
public PlanningItem(Object item) {
super();
if (item instanceof Double) {
setScene((Double) item);
} else if (item instanceof Integer) {
setPath((Integer) item);
} else if (item instanceof String) {
setMove((String) item);
}
}
}
UPDATE The MCVE:
package at.v2c2.testplaygroundui;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.TreeCell;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.DataFormat;
import javafx.scene.input.DragEvent;
import javafx.scene.input.Dragboard;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.Callback;
public final class TestplaygroundUi extends Application {
private final DataFormat objectDataFormat = new DataFormat("application/x-java-serialized-object");
/**
* Constructor.
*/
public TestplaygroundUi() {
// empty.
}
/**
* #param args Program arguments.
*/
public static void main(final String[] args) {
launch(args);
}
#Override
public void start(final Stage primaryStage) throws Exception {
TreeItem<PlanningItem> treeItemRoot = new TreeItem<>(new PlanningItem(1.0));
TreeItem<PlanningItem> nodeItemA = new TreeItem<>(new PlanningItem(2));
TreeItem<PlanningItem> nodeItemB = new TreeItem<>(new PlanningItem(2));
treeItemRoot.getChildren().addAll(nodeItemA, nodeItemB);
TreeItem<PlanningItem> nodeItemA1 = new TreeItem<>(new PlanningItem("A1"));
TreeItem<PlanningItem> nodeItemB1 = new TreeItem<>(new PlanningItem("B1"));
nodeItemA.getChildren().addAll(nodeItemA1);
nodeItemB.getChildren().addAll(nodeItemB1);
TreeView<PlanningItem> treeView = new TreeView<>(treeItemRoot);
treeView.setCellFactory(new Callback<TreeView<PlanningItem>, TreeCell<PlanningItem>>() {
#Override
public TreeCell<PlanningItem> call(TreeView<PlanningItem> siTreeView) {
final TreeCell<PlanningItem> cell = new TreeCell<>();
cell.setOnDragDetected(new EventHandler<MouseEvent>() {
public void handle(MouseEvent event) {
/* drag was detected, start drag-and-drop gesture */
System.out.println("onDragDetected");
/* allow any transfer mode */
Dragboard db = cell.startDragAndDrop(TransferMode.MOVE);
/* put a string on dragboard */
ClipboardContent content = new ClipboardContent();
content.put(objectDataFormat, cell.getItem());
// content.putString("Hello");// cell.getText());
db.setContent(content);
event.consume();
}
});
cell.setOnDragOver(new EventHandler<DragEvent>() {
public void handle(DragEvent event) {
/* data is dragged over the target */
System.out.println("onDragOver");
/*
* accept it only if it is not dragged from the same node and if it has a string data
*/
if (event.getGestureSource() != cell && event.getDragboard().hasString()) {
/* allow for both copying and moving, whatever user chooses */
event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
}
event.consume();
}
});
cell.setOnDragEntered(new EventHandler<DragEvent>() {
public void handle(DragEvent event) {
/* the drag-and-drop gesture entered the target */
System.out.println("onDragEntered");
/* show to the user that it is an actual gesture target */
if (event.getGestureSource() != cell && event.getDragboard().hasString()) {
// target.setFill(Color.GREEN);
}
event.consume();
}
});
cell.setOnDragExited(new EventHandler<DragEvent>() {
public void handle(DragEvent event) {
System.out.println("onDragExited");
/* mouse moved away, remove the graphical cues */
// target.setFill(Color.BLACK);
event.consume();
}
});
cell.setOnDragDropped(new EventHandler<DragEvent>() {
public void handle(DragEvent event) {
/* data dropped */
System.out.println("onDragDropped");
/* if there is a string data on dragboard, read it and use it */
Dragboard db = event.getDragboard();
boolean success = false;
if (db.hasString()) {
cell.setText(db.getString());
success = true;
}
/*
* let the source know whether the string was successfully transferred and used
*/
event.setDropCompleted(success);
event.consume();
}
});
cell.setOnDragDone(new EventHandler<DragEvent>() {
public void handle(DragEvent event) {
/* the drag-and-drop gesture ended */
System.out.println("onDragDone");
/* if the data was successfully moved, clear it */
if (event.getTransferMode() == TransferMode.MOVE) {
cell.setText("");
}
event.consume();
}
});
return cell;
};
});
StackPane root = new StackPane();
root.getChildren().add(treeView);
Scene scene = new Scene(root, 300, 250);
primaryStage.setScene(scene);
primaryStage.setTitle("Test TreeView");
primaryStage.show();
}
}
Thanks in advance
I am trying to run a simple Android Thing project that simply captures and renders the captured image in the display. I took the sample code from (https://github.com/googlecodelabs/androidthings-imageclassifier/tree/master/imageclassifier-add-camera) without the image recognition part. But I'm getting the following error-
I/InstantRun: starting instant run server: is main process
I/CameraManagerGlobal: Connecting to camera service
D/CameraHandler: Using camera id 0
W/CameraHandler: Cannot capture image. Camera not initialized.
D/CameraHandler: Opened camera.
So it seems it detects the camera but it can't capture images from the camera. Anyone faced similar issues on AndroidThings platform?
Main Camera Handler code provided below-
public class CameraHandler {
private static final String TAG = CameraHandler.class.getSimpleName();
public static final int IMAGE_WIDTH = 320;
public static final int IMAGE_HEIGHT = 240;
private static final int MAX_IMAGES = 1;
private CameraDevice mCameraDevice;
private CameraCaptureSession mCaptureSession;
/**
* An {#link android.media.ImageReader} that handles still image capture.
*/
private ImageReader mImageReader;
// Lazy-loaded singleton, so only one instance of the camera is created.
private CameraHandler() {
}
private static class InstanceHolder {
private static CameraHandler mCamera = new CameraHandler();
}
public static CameraHandler getInstance() {
return InstanceHolder.mCamera;
}
/**
* Initialize the camera device
*/
public void initializeCamera(Context context,
Handler backgroundHandler,
ImageReader.OnImageAvailableListener imageAvailableListener) {
// Discover the camera instance
CameraManager manager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
String[] camIds = {};
try {
camIds = manager.getCameraIdList();
} catch (CameraAccessException e) {
Log.d(TAG, "Cam access exception getting IDs", e);
}
if (camIds.length < 1) {
Log.d(TAG, "No cameras found");
return;
}
String id = camIds[0];
Log.d(TAG, "Using camera id " + id);
// Initialize the image processor
mImageReader = ImageReader.newInstance(IMAGE_WIDTH, IMAGE_HEIGHT,
ImageFormat.JPEG, MAX_IMAGES);
mImageReader.setOnImageAvailableListener(
imageAvailableListener, backgroundHandler);
// Open the camera resource
try {
manager.openCamera(id, mStateCallback, backgroundHandler);
} catch (CameraAccessException cae) {
Log.d(TAG, "Camera access exception", cae);
}
}
/**
* Callback handling device state changes
*/
private final CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
#Override
public void onOpened(#NonNull CameraDevice cameraDevice) {
Log.d(TAG, "Opened camera.");
mCameraDevice = cameraDevice;
}
#Override
public void onDisconnected(#NonNull CameraDevice cameraDevice) {
Log.d(TAG, "Camera disconnected, closing.");
closeCaptureSession();
cameraDevice.close();
}
#Override
public void onError(#NonNull CameraDevice cameraDevice, int i) {
Log.d(TAG, "Camera device error, closing.");
closeCaptureSession();
cameraDevice.close();
}
#Override
public void onClosed(#NonNull CameraDevice cameraDevice) {
Log.d(TAG, "Closed camera, releasing");
mCameraDevice = null;
}
};
/**
* Begin a still image capture
*/
public void takePicture() {
if (mCameraDevice == null) {
Log.w(TAG, "Cannot capture image. Camera not initialized.");
return;
}
// Here, we create a CameraCaptureSession for capturing still images.
try {
mCameraDevice.createCaptureSession(
Collections.singletonList(mImageReader.getSurface()),
mSessionCallback,
null);
} catch (CameraAccessException cae) {
Log.d(TAG, "access exception while preparing pic", cae);
}
}
/**
* Callback handling session state changes
*/
private CameraCaptureSession.StateCallback mSessionCallback =
new CameraCaptureSession.StateCallback() {
#Override
public void onConfigured(#NonNull CameraCaptureSession cameraCaptureSession) {
// The camera is already closed
if (mCameraDevice == null) {
return;
}
// When the session is ready, we start capture.
mCaptureSession = cameraCaptureSession;
triggerImageCapture();
}
#Override
public void onConfigureFailed(#NonNull CameraCaptureSession cameraCaptureSession) {
Log.w(TAG, "Failed to configure camera");
}
};
/**
* Execute a new capture request within the active session
*/
private void triggerImageCapture() {
try {
final CaptureRequest.Builder captureBuilder =
mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
captureBuilder.addTarget(mImageReader.getSurface());
captureBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON);
//captureBuilder.set(CaptureRequest.CONTROL_AWB_MODE, CaptureRequest.CONTROL_AWB_MODE_AUTO);
Log.d(TAG, "Capture request created.");
mCaptureSession.capture(captureBuilder.build(), mCaptureCallback, null);
} catch (CameraAccessException cae) {
Log.d(TAG, "camera capture exception");
}
}
/**
* Callback handling capture session events
*/
private final CameraCaptureSession.CaptureCallback mCaptureCallback =
new CameraCaptureSession.CaptureCallback() {
#Override
public void onCaptureProgressed(#NonNull CameraCaptureSession session,
#NonNull CaptureRequest request,
#NonNull CaptureResult partialResult) {
Log.d(TAG, "Partial result");
}
#Override
public void onCaptureCompleted(#NonNull CameraCaptureSession session,
#NonNull CaptureRequest request,
#NonNull TotalCaptureResult result) {
session.close();
mCaptureSession = null;
Log.d(TAG, "CaptureSession closed");
}
};
private void closeCaptureSession() {
if (mCaptureSession != null) {
try {
mCaptureSession.close();
} catch (Exception ex) {
Log.e(TAG, "Could not close capture session", ex);
}
mCaptureSession = null;
}
}
/**
* Close the camera resources
*/
public void shutDown() {
closeCaptureSession();
if (mCameraDevice != null) {
mCameraDevice.close();
}
}
}
The pitfall with camera:
Check the permissions in Manifest file, and restart the device.
The camera-permission is granted not after installing the application, but first after install and RESTART of device.
see https://developer.android.com/things/sdk/index.html
I don't know how to put clob data which is of more than 66k in Oracle Forms.
The text field will take a long data type and that too not more than 66k. I have a clob data and wanted to display.
The easiest way to display this is too make a forms bean (PJC).
Then you can display it in a JTextPane which is big enough.
You can then make a function that gives you piece of 32000 characters from the clob and give them to the bean.
package be.axi.oracle.forms.jpc;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.text.BadLocationException;
import oracle.forms.handler.IHandler;
import oracle.forms.properties.ID;
import oracle.forms.ui.CustomEvent;
import oracle.forms.ui.VBean;
/**
* A TextArea to get more than 64k texts
* #author Francois Degrelle
* #version 1.1
*/
public class BigTextArea extends VBean implements FocusListener, KeyListener
{
private static final long serialVersionUID = 1L;
public final static ID ADDTEXT = ID.registerProperty("ADD_TEXT");
public final static ID VALUE = ID.registerProperty("VALUE");
public final static ID SHOW = ID.registerProperty("SHOW");
public final static ID CLEAR = ID.registerProperty("CLEAR");
public final static ID GETTEXT = ID.registerProperty("GET_TEXT");
public final static ID GETLENGTH = ID.registerProperty("GET_LENGTH");
public final static ID pLostFocus = ID.registerProperty("BEAN_QUITTED");
private IHandler m_handler;
private int iStart = 0 ;
private int iChunk = 8192 ;
private StringBuffer sb = new StringBuffer();
protected JTextPane jtp = new JTextPane();
public BigTextArea()
{
super();
try
{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
SwingUtilities.updateComponentTreeUI(this);
}
catch (Exception ex)
{
ex.printStackTrace();
}
JScrollPane ps = new JScrollPane(jtp);
ps.setBorder(null);
add(ps);
ps.setVisible(true);
}
public void init(IHandler handler)
{
m_handler = handler;
super.init(handler);
addFocusListener(this);
jtp.addFocusListener(this);
jtp.addKeyListener(this);
}
public boolean setProperty(ID property, Object value)
{
//
// add text to the TextArea
//
if (property == ADDTEXT)
{
sb.append(value.toString()) ;
printMemory();
return true;
}
//
// display the whole text
//
else if(property == SHOW)
{
jtp.setText(sb.toString());
jtp.setCaretPosition(0);
sb = new StringBuffer();
System.gc();
printMemory();
return true ;
}
//
// clear the TextArea
//
else if(property == CLEAR) {
jtp.setText("");
return true ;
}
else
{
return super.setProperty(property, value);
}
}
/*-----------------------------------*
* Get the result string from Forms *
*-----------------------------------*/
public Object getProperty(ID pId)
{
//
// returns the text length
//
if (pId == GETLENGTH)
{
return "" + jtp.getText().length();
}
//
// returns the chunks
//
else if (pId == GETTEXT) {
String s = "" ;
int iLen = jtp.getText().length() ;
while (iStart < iLen)
{
try{
if(iStart+iChunk <= iLen) s = jtp.getText(iStart,iChunk);
else s = jtp.getText(iStart,iLen-iStart);
iStart += iChunk ;
return s ;
}
catch (BadLocationException ble) { ble.printStackTrace(); return ""; }
}
iStart = 0 ;
return "" ;
}
else
{
return super.getProperty(pId);
}
} // getProperty()
/*--------------------------*
* handle the focus events *
*--------------------------*/
public void focusGained(FocusEvent e)
{
if (e.getComponent() == this)
{
// put the focus on the component
jtp.requestFocus();
}
try
{
m_handler.setProperty(FOCUS_EVENT, e);
}
catch ( Exception ex )
{
;
}
}
public void focusLost(FocusEvent e)
{
CustomEvent ce = new CustomEvent(m_handler, pLostFocus);
dispatchCustomEvent(ce);
}
/*--------------------------*
* Handle the Key listener *
*--------------------------*/
public void keyPressed(KeyEvent e)
{
/*
** Allows TAB key to exit the item
** and continue the standard Forms navigation
*/
if ( (e.getKeyCode() == KeyEvent.VK_TAB) )
{
try
{
m_handler.setProperty(KEY_EVENT, e);
}
catch ( Exception ex )
{
}
}
}
public void keyTyped(KeyEvent e)
{
}
public void keyReleased(KeyEvent e)
{
}
// utility to output the memory available
private void printMemory() {
System.out.println("Java memory in use = "
+ (Runtime.getRuntime().totalMemory()
- Runtime.getRuntime().freeMemory()));
}
}
When i put all code in a SSCCE, it works as expected i.e first and third cells are editable. When tab on last column, takes to next row.
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import java.util.ArrayList;
import java.util.List;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.application.Platform;
import javafx.beans.property.ListProperty;
import javafx.beans.property.SimpleListProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellEditEvent;
import javafx.scene.control.TablePosition;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Callback;
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* #author Yunus
*/
public class CollectionForm extends Application{
private TableView table = new TableView();
private ObservableList<Collection> collectionList = FXCollections.<Collection>observableArrayList();
ListProperty<Collection> collectionListProperty = new SimpleListProperty<>();
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) {
// single cell selection mode
table.getSelectionModel().setCellSelectionEnabled(true);
//Create a custom cell factory so that cells can support editing.
Callback<TableColumn, TableCell> editableFactory = new Callback<TableColumn, TableCell>() {
#Override
public TableCell call(TableColumn p) {
return new EditableTableCell();
}
};
//A custom cell factory that creates cells that only accept numerical input.
Callback<TableColumn, TableCell> numericFactory = new Callback<TableColumn, TableCell>() {
#Override
public TableCell call(TableColumn p) {
return new NumericEditableTableCell();
}
};
Button b = createSaveCollectionBtn();
//Create columns
TableColumn colMNO = createMNOColumn(editableFactory);
TableColumn colName = createNameColumn(editableFactory);
TableColumn colQty = createQuantityColumn(numericFactory);
table.getColumns().addAll(colMNO, colName, colQty);
//Make the table editable
table.setEditable(true);
collectionListProperty.set(collectionList);
table.itemsProperty().bindBidirectional(collectionListProperty);
collectionList.add(new Collection());
collectionList.add(new Collection());
Scene scene = new Scene(new Group());
stage.setTitle("Table View Sample");
final VBox vbox = new VBox();
vbox.setSpacing(5);
vbox.getChildren().addAll(b, table);
vbox.setPadding(new Insets(10, 0, 0, 10));
((Group) scene.getRoot()).getChildren().addAll(vbox);
stage.setScene(scene);
stage.show();
}
private void handleCollection(ActionEvent event){
for (Collection collection : collectionList) {
System.out.println("MNO: "+collection.getMno()+" Quantity: "+collection.getQuantity());
}
}
private Button createSaveCollectionBtn(){
Button btn = new Button("Save Collection");
btn.setId("btnSaveCollection");
btn.setOnAction(this::handleCollection);
return btn;
}
private TableColumn createQuantityColumn(Callback<TableColumn, TableCell> editableFactory) {
TableColumn colQty = new TableColumn("Quantity");
colQty.setMinWidth(25);
colQty.setId("colQty");
colQty.setCellValueFactory(new PropertyValueFactory("quantity"));
colQty.setCellFactory(editableFactory);
colQty.setOnEditCommit(new EventHandler<CellEditEvent<Collection, Long>>() {
#Override
public void handle(CellEditEvent<Collection, Long> t) {
((Collection) t.getTableView().getItems().get(t.getTablePosition().getRow())).setQuantity(t.getNewValue());
}
});
return colQty;
}
private TableColumn createMNOColumn(Callback<TableColumn, TableCell> editableFactory) {
TableColumn colMno = new TableColumn("M/NO");
colMno.setMinWidth(25);
colMno.setId("colMNO");
colMno.setCellValueFactory(new PropertyValueFactory("mno"));
colMno.setCellFactory(editableFactory);
colMno.setOnEditCommit(new EventHandler<CellEditEvent<Collection, String>>() {
#Override
public void handle(CellEditEvent<Collection, String> t) {
((Collection) t.getTableView().getItems().get(t.getTablePosition().getRow())).setMno(t.getNewValue());
}
});
return colMno;
}
private TableColumn createNameColumn(Callback<TableColumn, TableCell> editableFactory) {
TableColumn colName = new TableColumn("Name");
colName.setEditable(false);
colName.setMinWidth(100);
colName.setId("colName");
colName.setCellValueFactory(new PropertyValueFactory<Collection, String>("name"));
colName.setCellFactory(editableFactory);
//Modifying the firstName property
colName.setOnEditCommit(new EventHandler<CellEditEvent<Collection, String>>() {
#Override
public void handle(CellEditEvent<Collection, String> t) {
((Collection) t.getTableView().getItems().get(t.getTablePosition().getRow())).setName(t.getNewValue());
}
});
return colName;
}
/**
*
* #author Graham Smith
*/
public class EditableTableCell<S extends Object, T extends String> extends AbstractEditableTableCell<S, T> {
public EditableTableCell() {
}
#Override
protected String getString() {
return getItem() == null ? "" : getItem().toString();
}
#Override
protected void commitHelper( boolean losingFocus ) {
commitEdit(((T) textField.getText()));
}
}
/**
*
* #author Graham Smith
*/
public class NumericEditableTableCell<S extends Object, T extends Number> extends AbstractEditableTableCell<S, T> {
private final NumberFormat format;
private boolean emptyZero;
private boolean completeParse;
/**
* Creates a new {#code NumericEditableTableCell} which treats empty strings as zero,
* will parse integers only and will fail if is can't parse the whole string.
*/
public NumericEditableTableCell() {
this( NumberFormat.getInstance(), true, true, true );
}
/**
* The integerOnly and completeParse settings have a complex relationship and care needs
* to be take to get the correct result.
* <ul>
* <li>If you want to accept only integers and you want to parse the whole string then
* set both integerOnly and completeParse to true. Strings such as 1.5 will be rejected
* as invalid. A string such as 1000 will be accepted as the number 1000.</li>
* <li>If you only want integers but don't care about parsing the whole string set
* integerOnly to true and completeParse to false. This will parse a string such as
* 1.5 and provide the number 1. The downside of this combination is that it will accept
* the string 1x and return the number 1 also.</li>
* <li>If you want to accept decimals and want to parse the whole string set integerOnly
* to false and completeParse to true. This will accept a string like 1.5 and return
* the number 1.5. A string such as 1.5x will be rejected.</li>
* <li>If you want to accept decimals and don't care about parsing the whole string set
* both integerOnly and completeParse to false. This will accept a string like 1.5x and
* return the number 1.5. A string like x1.5 will be rejected because ti doesn't start
* with a number. The downside of this combination is that a string like 1.5x3 will
* provide the number 1.5.</li>
* </ul>
*
* #param format the {#code NumberFormat} to use to format this cell.
* #param emptyZero if true an empty cell will be treated as zero.
* #param integerOnly if true only the integer part of the string is parsed.
* #param completeParse if true an exception will be thrown if the whole string given can't be parsed.
*/
public NumericEditableTableCell( NumberFormat format, boolean emptyZero, boolean integerOnly, boolean completeParse ) {
this.format = format;
this.emptyZero = emptyZero;
this.completeParse = completeParse;
format.setParseIntegerOnly(integerOnly);
}
#Override
protected String getString() {
return getItem() == null ? "" : format.format(getItem());
}
/**
* Parses the value of the text field and if matches the set format
* commits the edit otherwise it returns the cell to it's previous value.
*/
#Override
protected void commitHelper( boolean losingFocus ) {
if( textField == null ) {
return;
}
try {
String input = textField.getText();
if (input == null || input.length() == 0) {
if(emptyZero) {
setText( format.format(0) );
commitEdit( (T)new Integer( 0 ));
}
return;
}
int startIndex = 0;
ParsePosition position = new ParsePosition(startIndex);
Number parsedNumber = format.parse(input, position);
if (completeParse && position.getIndex() != input.length()) {
throw new ParseException("Failed to parse complete string: " + input, position.getIndex());
}
if (position.getIndex() == startIndex ) {
throw new ParseException("Failed to parse a number from the string: " + input, position.getIndex());
}
commitEdit( (T)parsedNumber );
} catch (ParseException ex) {
//Most of the time we don't mind if there is a parse exception as it
//indicates duff user data but in the case where we are losing focus
//it means the user has clicked away with bad data in the cell. In that
//situation we want to just cancel the editing and show them the old
//value.
if( losingFocus ) {
cancelEdit();
}
}
}
}
/**
* Provides the basis for an editable table cell using a text field. Sub-classes can provide formatters for display and a
* commitHelper to control when editing is committed.
*
* #author Graham Smith
*/
public abstract class AbstractEditableTableCell<S, T> extends TableCell<S, T> {
protected TextField textField;
public AbstractEditableTableCell() {
}
/**
* Any action attempting to commit an edit should call this method rather than commit the edit directly itself. This
* method will perform any validation and conversion required on the value. For text values that normally means this
* method just commits the edit but for numeric values, for example, it may first parse the given input. <p> The only
* situation that needs to be treated specially is when the field is losing focus. If you user hits enter to commit the
* cell with bad data we can happily cancel the commit and force them to enter a real value. If they click away from the
* cell though we want to give them their old value back.
*
* #param losingFocus true if the reason for the call was because the field is losing focus.
*/
protected abstract void commitHelper(boolean losingFocus);
/**
* Provides the string representation of the value of this cell when the cell is not being edited.
*/
protected abstract String getString();
#Override
public void startEdit() {
super.startEdit();
if (textField == null) {
createTextField();
}
setGraphic(textField);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
Platform.runLater(new Runnable() {
#Override
public void run() {
textField.selectAll();
textField.requestFocus();
}
});
}
#Override
public void cancelEdit() {
super.cancelEdit();
setText(getString());
setContentDisplay(ContentDisplay.TEXT_ONLY);
//Once the edit has been cancelled we no longer need the text field
//so we mark it for cleanup here. Note though that you have to handle
//this situation in the focus listener which gets fired at the end
//of the editing.
textField = null;
}
#Override
public void updateItem(T item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
if (isEditing()) {
if (textField != null) {
textField.setText(getString());
}
setGraphic(textField);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
} else {
setText(getString());
setContentDisplay(ContentDisplay.TEXT_ONLY);
}
}
}
private void createTextField() {
textField = new TextField(getString());
textField.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2);
textField.setOnKeyPressed(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent t) {
if (t.getCode() == KeyCode.ENTER) {
commitHelper(false);
} else if (t.getCode() == KeyCode.ESCAPE) {
cancelEdit();
} else if (t.getCode() == KeyCode.TAB) {
commitHelper(false);
TableColumn nextColumn = getNextColumn(!t.isShiftDown());
TablePosition focusedCellPosition = getTableView().getFocusModel().getFocusedCell();
if (nextColumn != null) {
//if( focusedCellPosition.getColumn() ){}focusedCellPosition.getTableColumn()
System.out.println("Column: "+focusedCellPosition.getColumn());
System.out.println("nextColumn.getId();: "+nextColumn.getId());
if( nextColumn.getId().equals("colMNO") ){
collectionList.add(new Collection());
getTableView().edit((getTableRow().getIndex())+1,getTableView().getColumns().get(0) );
getTableView().layout();
} else {
getTableView().edit(getTableRow().getIndex(), nextColumn);
}
}else{
getTableView().edit((getTableRow().getIndex())+1,getTableView().getColumns().get(0) );
}
}
}
});
textField.focusedProperty().addListener(new ChangeListener<Boolean>() {
#Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
//This focus listener fires at the end of cell editing when focus is lost
//and when enter is pressed (because that causes the text field to lose focus).
//The problem is that if enter is pressed then cancelEdit is called before this
//listener runs and therefore the text field has been cleaned up. If the
//text field is null we don't commit the edit. This has the useful side effect
//of stopping the double commit.
if (!newValue && textField != null) {
commitHelper(true);
}
}
});
}
/**
*
* #param forward true gets the column to the right, false the column to the left of the current column
* #return
*/
private TableColumn<S, ?> getNextColumn(boolean forward) {
List<TableColumn<S, ?>> columns = new ArrayList<>();
for (TableColumn<S, ?> column : getTableView().getColumns()) {
columns.addAll(getLeaves(column));
}
//There is no other column that supports editing.
if (columns.size() < 2) {
return null;
}
int currentIndex = columns.indexOf(getTableColumn());
int nextIndex = currentIndex;
if (forward) {
nextIndex++;
if (nextIndex > columns.size() - 1) {
nextIndex = 0;
}
} else {
nextIndex--;
if (nextIndex < 0) {
nextIndex = columns.size() - 1;
}
}
return columns.get(nextIndex);
}
private List<TableColumn<S, ?>> getLeaves(TableColumn<S, ?> root) {
List<TableColumn<S, ?>> columns = new ArrayList<>();
if (root.getColumns().isEmpty()) {
//We only want the leaves that are editable.
if (root.isEditable()) {
columns.add(root);
}
return columns;
} else {
for (TableColumn<S, ?> column : root.getColumns()) {
columns.addAll(getLeaves(column));
}
return columns;
}
}
}
public class Collection {
private int id;
private String mno;
private String name;
private float quantity;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getMno() {
return mno;
}
public void setMno(String mno) {
this.mno = mno;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public float getQuantity() {
return quantity;
}
public void setQuantity(float quantity) {
this.quantity = quantity;
}
}
}
The problem is when i take the same code to a controller and add this table programmatically, does not work as before: it jumps next line and go to third.
Before asking the TableView to edit the cell it's important to make sure that it has focus, that the cell in question is in view, and that the view layout is up to date. This is probably because of the way TableView uses virtual cells.
Add these three lines before any call to TableView#edit:
getTableView().requestFocus();
getTableView().scrollTo(rowToEdit);
getTableView().layout();
// getTableView().edit goes here.
This solved this problem for me.
I have found this code for searching for a specific user, using Parse. But when i run the code, it crashes.
What is wrong with the code???
The following is the link to the codes https://teamtreehouse.com/forum/tutorial-adding-search-to-ribbit-app
Here is the code
package com.twaa9l.isnap;
import java.util.List;
import android.app.AlertDialog;
import android.app.ListActivity;
import android.os.Bundle;
import android.support.v4.app.NavUtils;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import com.parse.FindCallback;
import com.parse.ParseException;
import com.parse.ParseQuery;
import com.parse.ParseRelation;
import com.parse.ParseUser;
import com.parse.SaveCallback;
public class EditFriendsActivity extends ListActivity {
public static final String TAG = EditFriendsActivity.class.getSimpleName();
protected List<ParseUser> mUsers;
protected ParseRelation<ParseUser> mFriendsRelation;
protected ParseUser mCurrentUser;
protected EditText sUsername;
protected Button mSearchButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.activity_edit_friends);
// Show the Up button in the action bar.
setupActionBar();
getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
}
#Override
protected void onResume() {
super.onResume();
mCurrentUser = ParseUser.getCurrentUser();
mFriendsRelation = mCurrentUser.getRelation(ParseConstants.KEY_FRIENDS_RELATION);
sUsername = (EditText)findViewById(R.id.searchFriend);
mSearchButton = (Button)findViewById(R.id.searchButton);
///////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////The New Code for Search Users by Username///////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
mSearchButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Get text from each field in register
String username = sUsername.getText().toString();
//String password = mPassword.getText().toString();
///Remove white spaces from any field
/// and make sure they are not empty
username = username.trim();
//password = password.trim();
//Check if fields not empty
if(username.isEmpty()){
AlertDialog.Builder builder = new AlertDialog.Builder(EditFriendsActivity.this);
builder.setMessage(R.string.login_error_message)
.setTitle(R.string.login_error_title)
.setPositiveButton(android.R.string.ok, null);
AlertDialog dialog = builder.create();
dialog.show();
}
else{
//Login User
setProgressBarIndeterminateVisibility(true);
ParseQuery<ParseUser> query = ParseUser.getQuery();
query.whereEqualTo("username", username);
query.orderByAscending(ParseConstants.KEY_USERNAME);
query.setLimit(200);
query.findInBackground(new FindCallback<ParseUser>() {
#Override
public void done(List<ParseUser> users, ParseException e) {
setProgressBarIndeterminateVisibility(false);
if(e == null){
//Success we have Users to display
//Get users match us
mUsers = users;
//store users in array
String[] usernames = new String[mUsers.size()];
//Loop Users
int i = 0;
for(ParseUser user : mUsers){
usernames[i] = user.getUsername();
i++;
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(
EditFriendsActivity.this,
android.R.layout.simple_list_item_checked,
usernames
);
setListAdapter(adapter);
addFriendCheckmarks();
}
else{
//No Users to Display
Log.e(TAG, e.getMessage());
AlertDialog.Builder builder = new AlertDialog.Builder(EditFriendsActivity.this);
builder.setMessage(e.getMessage())
.setTitle(R.string.error_title)
.setPositiveButton(android.R.string.ok, null);
AlertDialog dialog = builder.create();
dialog.show();
}
}
});
}
}
});
}
/**
* Set up the {#link android.app.ActionBar}.
*/
private void setupActionBar() {
getActionBar().setDisplayHomeAsUpEnabled(true);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// This ID represents the Home or Up button. In the case of this
// activity, the Up button is shown. Use NavUtils to allow users
// to navigate up one level in the application structure. For
// more details, see the Navigation pattern on Android Design:
//
// http://developer.android.com/design/patterns/navigation.html#up-vs-back
//
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
if(getListView().isItemChecked(position)){
//Add Friends
mFriendsRelation.add(mUsers.get(position));
}
else{
//Remove Friend
mFriendsRelation.remove(mUsers.get(position));
}
mCurrentUser.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
if(e != null){
Log.e(TAG, e.getMessage());
}
}
});
}
private void addFriendCheckmarks(){
mFriendsRelation.getQuery().findInBackground(new FindCallback<ParseUser>() {
#Override
public void done(List<ParseUser> friends, ParseException e) {
if(e == null){
//List Returned - look for a match
for(int i = 0; i < mUsers.size(); i++){
ParseUser user = mUsers.get(i);
for(ParseUser friend : friends){
if(friend.getObjectId().equals(user.getObjectId())){
//we have a match
getListView().setItemChecked(i, true);
}
}
}
}
else{
Log.e(TAG, e.getMessage());
}
}
});
}
}