I have a page with several JTextFields. All of their variable names start with txt i.e. txtCarArea, txtRopeLength,....
I have an orderObject, that has several fields and setters / getters to use them.
The textfields get filled with the values from the fields of the orderObject like this:
// Around 50 fields get filled like this
txtCarArea.setText(orderObject.getCar_area());
....
The user then can change the values.
Now I could get the values of every textfield and put it into the orderObject after the user clicks on a button like "Apply changes", but this again would mean I have to write 50 setter-uses and fire all of them, even if the user only changed a value in one field:
#Override
public void actionPerformed(ActionEvent e) {
// Again: Around 50 uses of the different setters
orderObject.setCar_area(txtCarArea.getText());
orderObject.setRope_length(txtRopeLength.getText());
orderObject.setDoughID(txtDoughID.getText());
(...)
}
This feels very bloated? I have to write and maintain those 50 calls.
Therefore I've read about reflection and tried to just use the setter-methods of the textfields that are changed and not all of them.
#Override
public void actionPerformed(ActionEvent e) {
orderObject.setCar_area(txtCarArea.getText());
Method[] methods = orderObject.getClass().getDeclaredMethods();
for (int i = 0; i < methods.length; i++) {
String methodName = methods[i].getName();
if (methodName.startsWith("set")) {
methodName = "txt" + methodName.substring(3);
String newMethodName = methodName.replace("_", "");
Method method = null;
try {
// "setCarArea" is hardcoded by me
method = orderObject.getClass().getMethod("setCarArea", String.class);
} catch (NoSuchMethodException e1) {
e1.printStackTrace();
} catch (SecurityException e1) {
e1.printStackTrace();
}
try {
// How to invoke dynamically for every textfield?
method.invoke(orderObject, "1070");
} catch (IllegalAccessException e1) {
e1.printStackTrace();
} catch (IllegalArgumentException e1) {
e1.printStackTrace();
} catch (InvocationTargetException e1) {
e1.printStackTrace();
}
}
}
}
But since I dont know to find the pair of orderObject-setter + JTextField where the value is, I am stuck now.
So how can I dynamically get the correct setter-methods in the orderObject to input the values from the JTextFields?
Related
I have a program to update vehicle inventory. I call the updateVehicle()...it should loop through the arrayList of vehicles to look for a match based on what the user input. In the if statement, if a match is found, update the vehicle in the arrayList with what the user input, call the displayCurrentVehicleEntry() and display the updated details to console. The code works and will update the vehicle.
However, if there is more than one vehicle in the arrayList, it will update it correctly, but not display the details of the updated vehicle (it displays the info for the last element in the arrayList).
In the displayCurrentVehicleEntry() it will grab the last element and display the details, which works correctly for the addVehicle().
I'm not sure how to get that to work for the updateVehicle().
public void updateVehicle(String makeCurrent, String modelCurrent, String colorCurrent, int yearCurrent, int mileageCurrent,
String makeUpdated, String modelUpdated, String colorUpdated, int yearUpdated, int mileageUpdated) {
try {
boolean found = false;
for (int i = 0; i < listOfVehicles.size(); i++) {
AutoInv vehicle = listOfVehicles.get(i);
if (vehicle.getMake().equalsIgnoreCase(makeCurrent)
&& vehicle.getModel().equalsIgnoreCase(modelCurrent)
&& vehicle.getColor().equalsIgnoreCase(colorCurrent)
&& vehicle.getYear() == yearCurrent
&& vehicle.getMileage() == mileageCurrent) {
vehicle.setMake(makeUpdated);
vehicle.setModel(modelUpdated);
vehicle.setColor(colorUpdated);
vehicle.setYear(yearUpdated);
vehicle.setMileage(mileageUpdated);
System.out.println("\nVehicle updated successfully!\n");
displayCurrentVehicleEntry(); //FIXME not working rethink
found = true;
}
}
if (!found) {
System.out.println("\nVehicle not found in inventory!");
}
} catch (Exception e) {
// TODO Auto-generated catch block
System.out.println("Failure");
System.out.println(e.getMessage());
e.printStackTrace();
}
}
public void displayCurrentVehicleEntry() {
try {
AutoInv vehicle = listOfVehicles.get(listOfVehicles.size() - 1);
System.out.println("Make: " + vehicle.getMake().toUpperCase());
System.out.println("Model: " + vehicle.getModel().toUpperCase());
System.out.println("Color: " + vehicle.getColor().toUpperCase());
System.out.println("Year: " + vehicle.getYear());
System.out.println("Mileage: " + vehicle.getMileage());
System.out.println("");
} catch (Exception e) {
// TODO Auto-generated catch block
System.out.println("Failure");
System.out.println(e.getMessage());
e.printStackTrace();
}
}
public void addVehicle(AutoInv vehicle) throws Exception{
try {
if (listOfVehicles.add(vehicle)) {
System.out.println("\nFollowing vehicle added successfully:\n");
displayCurrentVehicleEntry();
}
else {
throw new Exception("\nFailed to add vehicle.");
}
} catch (Exception e) {
System.out.println(e.getMessage());
// e.printStackTrace();
}
}
Modify the displayCurrentVehicleEntry() method, add a parameter to displayCurrentVehicleEntry() like this displayCurrentVehicleEntry(int index), and change AutoInv vehicle = listOfVehicles.get(listOfVehicles.size() - 1); to AutoInv vehicle = listOfVehicles.get(index);
in addVehicle, you can use displayCurrentVehicleEntry(listOfVehicles.size() - 1); and in updateVehicle you can use displayCurrentVehicleEntry(i); to select the vehicle you want to print
So I am trying to get more insight on Java methods as I am still new to all this. And in my method type I declared as below:
public int insert_url(long nodeid,String url,String startdt,String enddt,int enable) {
try {
// UrlLink attr = em.find(UrlLink.class,n);
String sql="INSERT INTO urllink(NODEID,URL,STARTDT,ENDDT,ENABLE) VALUES("+nodeid+",'"+url+"','"+startdt+"','"+enddt+"',"+enable+")";
em.createNativeQuery(sql).executeUpdate();
return 1;
} catch (Exception e) {
e.printStackTrace();
return -1;
}
}
And in my front end, I called it simply like below:
try {
fileFacade.insert_url(nd.getNodeid(), "f0=" + nd.getNodeid() + "&ts=" + hash, currentDate, defaultDate, 1);
} catch (Exception e) {
// error should be handled
}
Initially, I was using void method rather than int. My question is if I am not using a return method,can it be handled in the front end?
In the even that the end user encounters any error, they ought to know an error occurred.
Im trying to do something that might seem a bit unorthodox, however this is due to some limitations in a framework that im using.
Basically my case is this:
1: I have an object that has several fields, all with default values.
2: I have an other object that is initialized and has all values that I want to have, in the new object.
Im trying to do this with reflection, so looping over all public setMethods, finding all getMethods that seem to be matching from the other object, invoking them and invoke the other setMethod with the value over the invoked setMethod.
This is what I came up with so far:
java.lang.reflect.Method[] publicMethods1 = newlabels.getClass().getMethods();
for(int i=0; i<publicMethods1.length; i++){
if (publicMethods1[i].getName().startsWith("set")){
String setname = publicMethods1[i].getName();
String getname = "get"+setname.substring(3, setname.length());
try {
java.lang.reflect.Method getMethod = labels.getClass().getMethod(getname, null);
publicMethods1[i].invoke(newlabels, getMethod.invoke(labels, null));
} catch (NoSuchMethodException e1) {
//System.out.println("Couldnot find a method with name: "+getname);
} catch (SecurityException e1) {
//System.out.println("Security exception occured");
} catch (IllegalAccessException e1) {
//System.out.println("IllegalAccessException");
} catch (IllegalArgumentException e1) {
//System.out.println("IllegalArgumentException");
} catch (InvocationTargetException e1) {
//System.out.println("InvocationTargetException");
}
}
}
This unfortunately isn't working, its not giving errors either (unless a getter wasnt found, but ill take that).
I looked around on the internet and found somewhat similar in this method:
/**
* Only works for methods with equally named getters and setters
*
* 1. Get all declared methods of obj1 and find all setters
* 2. Get all declared methods of obj2 and find all getters
* 3. Find which setter belongs to which getter
* 4. Set the value of obj1.setter with obj2.getter
*
* #param obj1
* #param obj2
*/
public static void runAllSettersWithGetters(Object obj1, Object obj2) {
ArrayList<Method> setters = findSetters(obj1);
ArrayList<Method> getters = findGetters(obj2);
for(int s=0; s<setters.size(); s++){
String setmethodname = setters.get(s).getName();
String whattoset = setmethodname.substring(3);
for(int g=0; g<getters.size(); g++){
boolean isboolean = false;
boolean match = false;
if(getters.get(g).getReturnType().equals(Boolean.TYPE)){
isboolean = true;
}
String getmethodname = getters.get(g).getName();
String whattoget = getmethodname.substring(3);
if(whattoset.equalsIgnoreCase(whattoget)){
match = true;
}else{
//might start with is instead of get
whattoget = getmethodname.substring(2);
if(whattoset.equalsIgnoreCase(whattoget)){
match = true;
}
}
if(match){
try {
setters.get(s).invoke(obj1, getters.get(g).invoke(obj2));
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
So I tried it, because it seems better, however in the end it gives the same not working solution.
Can anyone help me with this?
I am building a Widget which contains a ProgressBar. If the Widget is computing I set the visibility of that ProgressBar to VISIBLE, and to INVISIBILE if all computings stopped. There should be no Problem, because the setVisibility is documented as RemotableViewMethod. However some guys at HTC seem to forget it, (i.e on the Wildfire S), so a call to RemoteViews.setVisibility will result in a crash. For this reason I try to implement a check, if setVisibility is really callable. I have writen this Method for it:
private boolean canShowProgress(){
LogCat.d(TAG, "canShowProgress");
Class<ProgressBar> barclz = ProgressBar.class;
try {
Method method = barclz.getMethod("setVisibility", new Class[]{int.class});
Annotation[] anot = method.getDeclaredAnnotations();
return anot.length > 0;
} catch (SecurityException e) {
LogCat.stackTrace(TAG, e);
} catch (NoSuchMethodException e) {
LogCat.stackTrace(TAG, e);
}
return false;
}
This will work, but is REALLY ugly as it will return `True´ if ANY Annotiation is present. I looked, how RemoteView itself is doing the lookup and found this:
if (!method.isAnnotationPresent(RemotableViewMethod.class)) {
throw new ActionException("view: " + klass.getName()
+ " can't use method with RemoteViews: "
+ this.methodName + "(" + param.getName() + ")");
}
But i could't do the same, because the Class RemotableViewMethod is not accsesible through the sdk. How to know if it is accesible or not?
By Writing my question I had the Idea to lookup for the class by its Name, and it worked.
So I updated my Method to the following:
private boolean canShowProgress(){
LogCat.d(TAG, "canShowProgress");
Class<ProgressBar> barclz = ProgressBar.class;
try {
Method method = barclz.getMethod("setVisibility", new Class[]{int.class});
Class c = null;
try {
c = Class.forName("android.view.RemotableViewMethod");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return (this.showProgress= (c != null && method.isAnnotationPresent(c)));
} catch (SecurityException e) {
LogCat.stackTrace(TAG, e);
} catch (NoSuchMethodException e) {
LogCat.stackTrace(TAG, e);
}
return false;
}
which works flawlessly
So i have a java class, with 3 private fields
public class Parcel {
private String guid;
private List<String> files;
private String zipFileName;
public Parcel (List<String> files, String zipFilePath){
UUID uuid = UUID.randomUUID();
guid = uuid.toString();
zipFileName = zipFilePath + File.separator + guid + File.separator + ".zip";
if ((files != null) && (!files.isEmpty())){
this.files = files;
}
}
}
Now, I am writing JUnit test to test these private fields
public class ParcelTest {
#Test
public void parcelObject() {
String zipFilePath = "/path/to/folder";
List<String> files = new ArrayList<String>();
files.add("/path/to/folder/test1");
files.add("/path/to/folder/test2");
Parcel parcel = new Parcel(files, zipFilePath);
Class<? extends Parcel> parcelClass = parcel.getClass();
try {
Field guid = parcelClass.getDeclaredField("guid");
guid.setAccessible(true);
System.out.println(guid.get(parcel));
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I am getting error when trying to access private guid field. I have tried this even after creating zero argument constructor. how should i access private members here?
EDIT
I figured it out and i have updated my response if someone else needed it.
P.S:
How can i close this question>
You are much better off testing the externally visible behaviour (behaviour, not getters and setters). If your code doesn't change behaviour, you should delete it.
(Also you might want to copy your list before stashing it in a field (and before checking validity).)
Why don't you have a public getter or setter instead of dealing with reflection?