Is it possible to set a property on an object using a string as the property name? I am quite new to Java but in JavaScript I would just do something like this:
Object[propertyNameAsString] = value
After searching around I found how to get a property using a string, but not how to set one. I also came across something called a Properties object, is that what I need to be using?
Basically I just want to loop through an array filled with image names and then set their respective properties onto an object which I will use to store the actual images. Is this possible in Java or should I do it another way?
Edit:
This is what my array looks like:
static String pngs[] = {"staminaBox", "staminaBoxR", "healthBox", "healthBoxR", "moveBox", "goButton"};
Ideally I want to loop through them and add properties to an assets class like so:
for (int i = 0; i < pngs.length; i++) {
Assets.pngs[i] = createImageFromUrl(pngs[i] + ".png");
}
But now I'm realizing this wouldn't work because in my assets class I have to previously define the properties like:
public static Image staminaBox;
And the whole point of me wanting to do this in the first place was so that I didn't have to write out declarations for every single image I wanted to add. I'm used to the loose nature of JavaScript, but does this mean there is no way of getting around these explicit declarations of properties? Will a HashMap let me accomplish this?
You might be talking about a couple different things. Are you talking about setting the value of variables defined inside a class? If so, you might be able to hack something together using reflection, but it's not a "gimme" in Java like it is in javascript.
You might also look into using a HashMap of properties to their values, or like you said, the Properties object (which is pretty much just a Map itself).
You can use the Reflection API. Keep in mind that it will get messy very quickly.
Because Java uses the Getter and Setter pattern, you likely won't be assigning a value to a member variable but calling a method which itself assigns the value.
How do I invoke a Java method when given the method name as a string?
Related
I have an arraylist of classes. I need to randomly pick 2 classes from the arraylist, then call an attribute from them. How would I do this?
I can't just do
(array_list_name.get(random_number)).attribute_name();
as i'm not calling the attribute of the class, i'm attempting to call the attribute from get, and that obviously won't work.
P.S. I have already initialized all the classes.
I think something may be missing from the question. Are you trying to access the attribute's value? If you know the name of the attribute in all objects you have in the list, the following should work:
SomeType obj = list_of_objects[0]
String val = obj.attribute_name
Or are you perhaps trying to dynamically call a method name that is contained in an attribute's value? If so, then (along with the code above) you'll want to look at how to call a method dynamically. The answer to that can be found here: https://stackoverflow.com/a/161005/4700298
What would you use if you wanted to pass a list of options into a function?
For example, if you have an interface to a server:
public interface Server {
public void authUser(String username, String password, <xyz> options);
}
What structure would use use for to pass a set of options? Something like a HashMap?
The reason I'm saying that it comes from tunnel vision is because I feel that this goes against Java standards. Java has method overloading. So if I get flames for raising the question I understand. But overall, maybe in different cases, would you ever pass bulk data in some collection and, if yes, which one?
Option1 : If you are choosing any collections like List or Set these are specific to an object . I mean,
Lets Assume, Set sets = new HashSet();
If I want 5 Object of different different class having no relationship to be send, then It would be very difficult to recognize that which Object is belong to which class while Iteration. So, I wont recommend Collections.
Option2 : If you are choosing Map, the same above problem may occurs while getting the Object Dynamically. So, This Options is also not recommended.
Option3 :
Why cann't you create your own DTO and in that DTO place your reqyired datastructure and pass it over.
If you want 5 different Object to be pass then, you can pass. If all are of same type then you may use Collection or array or Variable Arguement based on your scenerio.
I think anything Serializable is exactly the thing. If you can serialize the object, then you can pass (store, transmit...) it, passing it's properties in bulk. What format of serialized data to choose, is another question.
It depends on the data you want to pass.
You can use a map(hashmap) if you are passing key-value pairs.
If it is just a list of diffrent object, you can use List(ArrayList)
Other option is to create DTO(data transfer object) with getter and setter methods.
You may want to take a look at VARARGS feature that was introduced in JAVA5.
I'd suggest a Map [HashMap] as you can then access the argument values via their Keys.
I am building a DAQ in a Java based Platform called KMax. This platform, has a design interface to use objects like histograms. Each histogram has a name, which is declared on the design interface.
To call the histogram in the code you have to use
hist = tlsh.getKmaxHist("DATA");
The string DATA is the name that the user gives in the design interface and hist is the variable that refers to the object. Every histogram object has certain classes it can use. For instance hist.getSum() gives the total sum of the histogram.
In my DAQ I have many histograms. My plan is to create a slider box that will pick the histogram, that the user wants to apply some functions(such as getSum()). The slider box has a class(string getProperty("VALUE")) that returns the value that the user has selected.
The plan is to use something like sliderBox.getProperty("VALUE").getSum(). Of course something like that is not valid, therefore I was wondering if there is a way to "convert" the string that the getProperty() returns, into a variable already defined in the code.
Sounds like a Map will do what you need. You can put the histograms in a Map keyed by whatever the property value is.
Map<String,Histogram> histograms = new HashMap<String,Histogram>();
histograms.put("PropertyValue1", histogram1);
histograms.put("PropertyValue2", histogram2);
String desiredHistogram = silderBox.getProperty("VALUE");
Histogram histogramToUse = histograms.get(desiredHistogram);
histogramToUse.getSum(); // do whatever you need to with this
You'll want to check for nulls and all that stuff too.
It looks to me like you need a Map<String, Histogram>. Variable names are lost when java code gets compiled.
You can use the *BeanInfo class mechanism. For instance. Having a class Hist, one can write a HistBeanInfo with a "sum" property. Though these classes were intended for GUI builders with components on palettes listing heterogene properties, one can use them indepedantly.
The BeanInfo classes might be generated.
This still is a far way to actually instrument that information, maybe using reflection.
An alternative to BeanInfo would be using home-brew annotations, but with BeanInfo you have an API supported by some IDEs.
Store it in a map:
yourHistogramsMap.get(sliderBox.getProperty("VALUE")).getSum();
Of course, you have to store your histograms there first.
These are some preliminary sorts for something that is going to be a conversion tool for NBT-Files. This is a file format providing nested objects, those of you knowing Minecraft might know it.
So lets consider we have an object like this:
object.name = String
object.id = int
object.randomInformation = Object
object.storedObjects = Object[]
What I'm trying to achieve is this:
The user should be able to give config files for different versions of the object.
This may look like this:
Version1.dat:
someCoolObjectName.id = 1
Version2.dat:
someCoolObjectName.id = 2
So on conversion from Version1 to Version 2 the program reads the NBT-File, search for any object with an id of 1, change it to 2 and write it into another file.
So far not a big deal.
The Problem starts, when it comes to real changes in the version. This includes:
renamed properties
moved properties
added/deleted properties
properties that contains objects which have to be treated as if they where a "normal" object itself (if you are into Minecraft, you may think of items in a chest)
I thought about something like this:
Version1.dat:
foo:object.id=1
bar:object.randomInformation
*:object.storedObjects
Version2.dat:
foo:object.id=2
bar:object.usefulInformation
blubb:object.(int)addedInformation
*:object.storedObjects
This would mean on conversion from 1 to 2:
change id from 1 to 2
rename randomInformation to usefulInformation
add a property addedInformation, which is an integer
convert every Object in object.storedObjects just like a normal object
just copy every other property
This would mean i have to implement a whole "language" for the config file and convert that into a list of "commands" that have to be done to each object. Isn't there an easier way to do this? Or is this already a good idea?
Remember, I'll have a whole lot of different objects in each version, where mostly only the id has to be changed. But on some objects, identified by their id, various changes has to be made. And I don't want to change the program code for every new version.
It's not so hard! But you need to write the conversion methods from the two object or if the second object extends the first object, then you can simple copy the fields of the first object. If the fields aren't visible, then you can use reflection for copying them.
For Minecraft NBT management you can use the JNBT library.
I'm trying to access elements in a HashMap.
The keys of this HashMap are defined by an Enum.
After going through the documentation, I figured that in order to be able to access the Enum, I have to send it to Freemarker like so:
BeansWrapper wrapper = BeansWrapper.getDefaultInstance();
TemplateHashModel enumModels = wrapper.getEnumModels();
TemplateHashModel fieldTypeModel = (TemplateHashModel)enumModels.get("com.example.MinisiteFieldType");
root.put("fieldtypes", fieldTypeModel);
In my .ftl I tried the following:
${myelement.mymap[fieldtypes.SEOTEXT]}
However I get:
Expression myelement.mymap[fieldtypes.SEOTEXT] is undefined on line X...
I wanted to make sure I mapped the enum correctly, so I tried:
${fieldtypes.SEOTEXT}
This didn't print anything, leaving me wondering wether it got through, or simply couldn't be printed.
In Java debug, just before inserting the TemplateHashModel in my root Map, 'fieldTypeModel' is filled with the correct data...
Any help would be appreciated!
Bart
I suspect your problem is that by using the [] syntax to access your map, you're implicitly telling Freemarker to treat it as a hash. That may not work as you'd expect -- the hash will probably represent the Map object, mapping 'size' and 'containsKey' and so forth to Java methods. Instead, try:
${myelement.mymap.get(fieldtypes.SEOTEXT)}
As a side note, I've never tried accessing enums by the method you describe, but there's another way to access Java constants from a template that doesn't require Java code, so the following should also work:
${myelement.mymap.get(stack.findValue("#com.example.MinisiteFieldType#SEOTEXT"))}