开发者

pass class name via context and use it to store static value in different class

The dialogue and the array displays just fine, I just want to be able to set the static variable from the originating class within the onClick that is in a method that is in a different class. All of the try, catch and <?> were things that I put in at the insistence of the compiler:

public class Setter
    {
    public void myList(Context context, Class<?> thisclass, int arrayid, String choice)
        {
        return new AlertDialog.Builder(context)
        .setItems(arrayid, new OnClickListener()
            {
            @Override
            public void onClick(DialogInterface dialog, int which)
                {
                setChoice(thisclass, context, arrayid, which, choice);
                }
            })
        .create();
        }           
    public void setChoice(Class<?> thisclass, Context context, int arrayid, int which, String choice)
        {
        String[] array = context.getResources().getStringArray(arrayid);
        try
            {
            Field f = thisclass.getDeclaredField(choice);
            f.set(null, array[which]);
            }
        catch (SecurityException e)
            {
            e.printStackTrace();
            }
        catch (NoSuchFieldException e)
            {
            e.printStackTrace();
            }
        catch (IllegalArgumentException e)
            {
            e.printStackTrace();
            }
        catch (IllegalAccessException e)
            {
            e.printStackTrace();
            }
        }
    }

public class ClassA extends Activity
    {
    static String stringa;
    Setter setted = new Setter();
    ...
    public void onCreate()
        {
        super.onCreate();
        ...
        AlertDialog thinga = setted.myList(this, getclass(), R.array.thinga, stringa).show();
        ...
        }
    }

When I select开发者_开发百科 an item from the list, I get this from debugger:

ClassCache.findFieldByName(Field[], String) line: 438   
Class.getDeclaredField(String) line: 666    
Setter.setChoice(Class, Context, int, int, String) line: 45 // the line with the Field

I think I'm passing it the class wrong but this is a bit out of my current depth.

I have a number of different classes each with their own static Strings. I am passing the method below the name of the String (in choice) and the context of what I had hoped was the original class that called a method that called a method that led to the code below. I was hoping I could call context.choice = something and the machine would read that as ClassA.stringa = something; how do I do that?

Briefly, I want to have a list of items that the user can choose from be the content of a dialogue, and have their selection be saved and accessible to the class that called for the creation of the dialogue. Perhaps I'm going about this all wrong but I got tired of dealing with other 'kludges' involving using spinners to do the same thing.

Because onClick can't have non-final objects declared elsewhere (at least that is my understanding) I thought maybe I could get around that by calling to another method, setChoice that would store the value of whatever was chosen. I would definitively say this is a kludge and would love to be shown the light as to how you are supposed to deal with these things.


Java does not have closures, but you can get close with anonymous inner classes.

String output;
public void onCreate() {
    Setter.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            output  = "selected";
        }
    });
}

See also this swing tutorial: http://download.oracle.com/javase/tutorial/uiswing/events/actionlistener.html

Edit: In spirit of your example, this should look like this:

public class Setter
{
public void setChoice(IsetString setter, String something)
    {
    setter.setString(something);
    }
}


class ClassA extends Activity implements setString
{
static String stringa;
string polka = "dots";
Setter setted = new Setter();
...
public void onCreate()
    {
    super.onCreate();
    ...
    setted.setChoice(new IsetString() {

        @Override
        public void setString(String s) {
            stringa = s;
        }
    }, polka);
    ...
    }
}

interface IsetString {
    void setString(String s);
}


The short answer - use the Reflection API.

The long answer - you'll need to obtain access to the Fields of the desired Context Class. Once you gain access to the Field instances, you can set their values using the set() method; the API call is a bit tricky in that you'll need to pass in the object reference (the context object and not the context class) whose field you wish to modify.

It is necessary that your Context, choice and something parameters to the method, contain the necessary information to make this operation as simple as possible. In other words, the Context class might have to contain the actual Class object (or provides a way to get one) that contains the field.


You can use reflection for that. Suppose you context is class itself

public void setChoice(Class<?> context, String choice, String something)
{
   try {
     Field f = context.getDeclaredField(choice);
     f.set(null, something);
   } catch (....) {
   }
}

Add proper exception handling


Note that first argument to set is null. That is only valid for static methods. So you may want to check that method is static using f.getModifiers().

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜