dimanche 1 mai 2016

How to set field value of running class and not an instance with Java

I was able to loop through the fields of a class and grab private fields values using reflection. However I'm not able to set field values and the only solutions I can find is using newInstance() which seems to affect the value of a new instance of the class.

How can I set the value of a field in a running object Class?

Here is my compile and run error free code that still doesn't set the value of current running class I want to target.

Field[] allFields = c.getDeclaredFields();
  for (Field field : allFields) {

      field.setAccessible(true);

      String fieldName = field.getName();

      if (fieldName == "theNameOfFieldIneed"){

          try {
              Object objectInstance = a.newInstance();

              field.setInt( objectInstance, 1000);

          } catch (IllegalArgumentException e) {
              e.printStackTrace();
          } catch (IllegalAccessException e) {
              e.printStackTrace();
          } catch (InstantiationException e) {
              e.printStackTrace();
          }

      }





Swing GUI Designer

So I am making this project where I need to insert into a JPanel container different types of Swing components (like a JButton, JTextArea etc). My main frame looks like this: Main frame

Basically I have a text are where a user inputs what he needs inserted (a Button for example) and the component appears in the JPanel. This is achieved dynamically using reflection. I have a method that looks like this:

enter code here
JComponent createComponent(String compName)
{
    try {
        Class<?> clazz=Class.forName("javax.swing.J"+compName);
        JComponent jComponent=(JComponent) clazz.newInstance(); 
        jComponent.setBounds(lastClick.x, lastClick.y, 100, 32);
        snapPanel.add(jComponent);
        mover.register(jComponent);
        snapPanel.revalidate();
        return  jComponent;
    }catch (Exception e){
        e.printStackTrace();
    }
    return null;
}

What I need done now is the following: after I click on a component I need for its properties to be displayed in the right hand side Jpanel, where I have created a JTable. And not only do I need the properties to be displayed, I need to be able to modify some of them, like the size.

I thought of using this library http://ift.tt/1j76zfs to import the componets properties into the table, but I have not been successful. What I think the logic should be is: after this step:

Class clazz=Class.forName("javax.swing.J"+compName);

I need to take clazz and reflect it into the Jtable somehow. I am new to this reflection api and don't know how to continue. I also don't have much experience constructing a default DefaultTableModel Any help would be appreciated.





Exception in thread "main" java.lang.IllegalArgumentException: wrong number of arguments

public class DriverScript {

public static ActionKeywords actionKeywords;
public static String sActionKeyword;
public static Properties OR;
public static String sPageObject;

//Reflection Class object
public static Method method[];

public static void main(String[] args) throws Exception {

    String sPath = Constants.path_TestData;
    ExcelUtils.setExcelFile(sPath, Constants.Sheet_TestSteps);
    String Path_OR = Constants.Path_OR;
    FileInputStream fs = new FileInputStream(Path_OR);
    OR = new Properties(System.getProperties());
    OR.load(fs);
    actionKeywords = new ActionKeywords();
    method = actionKeywords.getClass().getMethods();
    for(int iRow=1;iRow<=9;iRow++){
    sActionKeyword = ExcelUtils.getCellData(iRow, Constants.Col_ActionKeyword);
    sPageObject = ExcelUtils.getCellData(iRow, Constants.Col_PageObject);
    System.out.println(sPageObject);
        execute_Actions();      
    }

}
private static void execute_Actions() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {

    for(int i=0;i<method.length;i++){
        if(method[i].getName().equals(sActionKeyword)){
            method[i].invoke(actionKeywords, (sPageObject));
            break;
        }

    }

Note: when there were no arguments in reflection methods(which are in different class) i have used "method[i].invoke(actionKeywords));" this worked absolutely fine. but now i have added an argument for each of the method and trying to call them using "method[i].invoke(actionKeywords, (sPageObject));" i am getting Exception in thread "main" java.lang.IllegalArgumentException: wrong number of arguments.

Reflection methods class would look like below:

public class ActionKeywords {

public static WebDriver driver;

public static void openBrowser(){
    System.setProperty("webdriver.chrome.driver", "D:/chromedriver.exe");
    driver = new ChromeDriver();
}
public static void navigate(String object){
    driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
    driver.get(Constants.URL);
    driver.manage().window().maximize();
}

public static void click(String object){
    driver.findElement(By.xpath(DriverScript.OR.getProperty(object)));
}

public static void input_Username(String object){
    driver.findElement(By.xpath(DriverScript.OR.getProperty(object))).sendKeys(Constants.UserName);
}
public static void input_Password(String object){
    driver.findElement(By.xpath(DriverScript.OR.getProperty(object))).sendKeys(Constants.Password);
}

public static void waitFor(String object) throws InterruptedException{
    Thread.sleep(5000);
}

public static void closeBrowser(String object) {
    driver.quit();
}

}





when using method.invoke Exception in thread "main" java.lang.IllegalArgumentException: wrong number of arguments

public class DriverScript {

public static ActionKeywords actionKeywords;
public static String sActionKeyword;
public static Properties OR;
public static String sPageObject;

//Reflection Class object
public static Method method[];

public static void main(String[] args) throws Exception {

    String sPath = Constants.path_TestData;
    ExcelUtils.setExcelFile(sPath, Constants.Sheet_TestSteps);
    String Path_OR = Constants.Path_OR;
    FileInputStream fs = new FileInputStream(Path_OR);
    OR = new Properties(System.getProperties());
    OR.load(fs);
    actionKeywords = new ActionKeywords();
    method = actionKeywords.getClass().getMethods();
    for(int iRow=1;iRow<=9;iRow++){
    sActionKeyword = ExcelUtils.getCellData(iRow, Constants.Col_ActionKeyword);
    sPageObject = ExcelUtils.getCellData(iRow, Constants.Col_PageObject);
    System.out.println(sPageObject);
        execute_Actions();      
    }

}
private static void execute_Actions() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {

    for(int i=0;i<method.length;i++){
        if(method[i].getName().equals(sActionKeyword)){
            method[i].invoke(actionKeywords, sPageObject);
            break;
        }

    }

} }





Construct array class from component class [duplicate]

This question already has an answer here:

If I have Class<?> t = T.class, how can I construct the class of T[] dynamically, i.e. without naming T in the source code?

I think it should be possible to do this as

java.lang.reflect.Array.newInstance(t, 0).getClass()

but that feels kind of round-about. Is there a shorter way to achieve this without actually constructing an array of the type in question?





Set static IP using reflection in Android 5.0 and above

I've tried the solution posted here How to configure a static IP address, netmask, gateway, DNS programmatically on Android 5.x (Lollipop) for Wi-Fi connection

But, when I run, I get following error

com.packagename W/System.err: at com.packagename.classname.getEnumValue(class-name.java:175)

Here getEnumValue() method says

private static Object getEnumValue(String enumClassName, String enumValue) throws ClassNotFoundException
{
    Class<Enum> enumClz = (Class<Enum>)Class.forName(enumClassName);
    return Enum.valueOf(enumClz, enumValue);
}

Here in my code 175th line is,

Class<Enum> enumClz = (Class<Enum>)Class.forName(enumClassName);

where

enunClassName = "android.net.IpConfiguration$IpAssignment"

getEnumValue() method is called using

Object ipAssignment = getEnumValue("android.net.IpConfiguration$IpAssignment", "STATIC");

I'm running this code for API 21 as suggested in above link too.

Thanks in advance...





Where does JVM uses reflection?

Recent question : Does JVM uses reflection internally for some process. If yes then where and why?