I am creating an ArrayList of JTextFields using the following code.
ArrayList<JTextField> cmp = new ArrayList<>();
cmp.add(txtAmount);
cmp.add(txtBillTo);
cmp.add(txtBranch);
After passing this ArrayList into a method, I need to print the "variable name" of the textfield. I can use the SetName and GetName to print some names. But I need the output as txtAmount, txtBillTo, txtBranch.
Is there anyway to find the variable name of textfield?
No, you can't do this. The information you are asking for is just not recorded. The only way to do it would be to store it yourself:
Map<String, JTextField> cmp = new HashMap<>();
cmp.put("txtAmount",txtAmount);
cmp.put("txtBillTo", txtBillTo);
cmp.put("txtBranch", txtBranch);
If you need to keep things in the same order you put them into the collection then use a LinkedHashMap instead of a HashMap as the HashMap may change the order.
What you are looking for would require reflection of method code, something supported by languages such as Scala via macros/compile time reflection. However Java itself does not support runtime or compile time reflection of method code, only runtime reflection of classes/fields/functions, although some people have pulled together their own Java parsers to grab the information from source files and others have pulled the information from the Class files debug information. Neither of which has an officially supported API.
Your best bet is to place the name that you want along with the field, which is obviously duplication and thus could diverge by accident but your options are limited.
Related
Java program takes a long list of inputs(parameters), churns a bit and spits some output.
I need a way to organize these parameters in a sane way so in the input txt file I want to write them like this:
parameter1 = 12
parameter2 = 10
strategy1.parameter1 = "goofy"
strategy2.parameter4 = 100.0
Then read this txt file, turn it into a Java object I can pass around to objects when I instantiate them.
I now pyqtgraph has ParameterTree which is handy to use; is there something similar in Java? I am sure others must have had the same need so I don't want to reinvent the wheel.
(other tree structures would also be fine, of course, I just wanted something easy to read)
One way is to turn input.txt into input.json:
{
"parameter1": 12,
"parameter2": 10,
"strategy1": {
"parameter1": "goofy"
},
"strategy2": {
"parameter4": 100.0
}
}
Then use Jackson to deserialize input.json into one of these:
A Map<String, Object> instance, which you could navigate in depth to get all your parameters
An instance of some class of your own that mimics input.json's structure, where your parameters would reside
A JsonNode instance that would be the root of the tree
(1) has the advantage that it's easy and you don't have to create any class to read the parameters, however you'd need to traverse the map, downcast the values you get from it, and you'd need to know the keys in advance (keys match json object's attribute names).
(2) has the advantage that everything would be correctly typed upon deserialization; no need to downcast anything, since every type would be a field of your own classes which represent the structure of the parameters. However, if the structure of your input.json file changed, you would need to change the structure of your classes as well.
(3) is the most flexible of all, and I believe it's the option that is closest to what you have in mind, nonetheless is the most tedious to work with, since it's too low-level. Please refer to this article for further details.
I have a block of static data that I need to organize into an array containing hash maps. Specifically, I want to have a static object in my app that contains the time zone information like this: https://gist.github.com/pamelafox/986163
Seeing how clean the definition looks like in Python, and knowing how a similarly clean definition can be created with some of the other languages I know, I was hoping there is a cleaner approach to it in Java then just running map.put(...) repeatedly. I have seen this question: How to give the static value to HashMap? but what wondering if there is a better way to do it?
One solution would be to store the data as a normal string in whatever format you can think of and then convert the string representation into the map (static, non-static or as a one-time initialized instance).
An improvement of this method would be to store the data in a file and load it (can be included in .jar package, when you use jar). This solution would have the advantage that data can be easily updated.
I am not able to create the name of the object at runtime. My statement is:
Map<String,String> objectName+""+lineNumber = new HashMap<String,String>();
It's giving me compiletime error. I want to create the HashMap object at runtime depending upon the line number.
Java is not a interpreted but rather a compiled language. So the compiler does not knows how to handle this. Such a thing might make sense in a scripting language.
If you need a custom Name for a "variable" maybe a construct like the following might make sense:
Map<String,Map<String,String>> varMap = new HashMap<String,Map<String,String>>();
varMap.put(objectName+" "+lineNumber, new HashMap<String, String>());
You can't do this directly in Java (without major tricks)
What you can (and probably should) do:
Put your Map in another map which has the 'variable' name as a key.
If you really want to do that you have to do code generation. For this again you have multiple options:
Generate Java Source Code and compile it
Generate Java Byte Code on the fly. You might wanna look at this list: http://java-source.net/open-source/bytecode-libraries for libraries available.
Having a dynamic object name is of No Use.
At first, it's not possible to give reference a dynamic name. The bigger question is Why do you want to do it?
If, just for learning and doing experiments, I'll suggest you should follow proper exercises.
But, if you are trying to achieve some project requirement, Pls. explain the requirement. There will be some other way to achieve that.
I need to store values specific to a username into memory, I was thinking about something like dynamically naming vars, so that I could do something like
["bubby4j_falling"] = true;
and index it by
["bubby4j_falling"]
But, this is just a example, I know that won't work, I just want a way to quickly and simply get and store things dynamically.
You want to use a Map with string keys, for example a HashMap<String, something>.
Your example would look like this:
Map<String, Boolean> map = new HashMap<String, Boolean>();
map.put("bubby4j_falling", true);
if(map.get("bubby4j_falling")) {
...
}
Actually, in your case a Set<String> would be more useful:
Set<String> fallingUsers = new HashSet<String>();
fallingUsers.add("bubby4j");
if(fallingUsers.contains("bubby4j")) { ... }
But uf you already have User objects (and you should), you should better use a Set<User>, or even let this falling simply be a property of the user object. Then you could have a Map<String, User> to get the user objects by name.
#PaĆlo Ebermann's answer is spot on.
I just want to point out that the Java language has nothing that resembles a dynamic variable. All Java variable names and their types are declared in the Java source code. Not even reflection will allow you to create new variables on the fly in an existing class.
Java is designed as a static programming language, and it works best if you use it that way.
(In theory, if you mess around with source code or byte code generation technologies, you can dynamically create a new class with new variables. However, this involves a HUGE amount of work, and not something that a sensible programmer contemplate doing to solve a simple problem. Besides, I doubt that this approach would actually help in your particular case.)
I'm looking for clever ways to build dynamic Java classes, that is classes where you can add/remove fields at runtime. Usage scenario: I have an editor where users should be able to add fields to the model at runtime or maybe even create the whole model at runtime.
Some design goals:
Type safe without casts if possible for custom code that works on the dynamic fields (that code would come from plugins which extend the model in unforeseen ways).
Good performance (can you beat HashMap? Maybe use an array and assign indexes to the fields during setup?)
Field "reuse" (i.e. if you use the same type of field in several places, it should be possible to define it once and then reuse it).
Calculated fields which depend on the value of other fields
Signals should be sent when fields change value (no necessarily via the Beans API)
"Automatic" parent child relations (when you add a child to a parent, then the parent pointer in the child should be set for "free").
Easy to understand
Easy to use
Note that this is a "think outside the circle" question. I'll post an example below to get you in the mood :-)
Type safe without casts if possible for custom code that works on the dynamic fields (that code would come from plugins which extend the model in unforeseen ways)
AFAIK, this is not possible. You can only get type-safety without type casts if you use static typing. Static typing means method signatures (in classes or interfaces) that are known at compile time.
The best you can do is have an interface with a bunch of methods like String getStringValue(String field), int getIntValue(String field) and so on. And of course you can only do that for a predetermined set of types. Any field whose type is not in that set will require a typecast.
The obvious answer is to use a HashMap (or a LinkedHashMap if you care for the order of fields). Then, you can add dynamic fields via a get(String name) and a set(String name, Object value) method.
This code can be implemented in a common base class. Since there are only a few methods, it's also simple to use delegation if you need to extend something else.
To avoid the casting issue, you can use a type-safe object map:
TypedMap map = new TypedMap();
String expected = "Hallo";
map.set( KEY1, expected );
String value = map.get( KEY1 ); // Look Ma, no cast!
assertEquals( expected, value );
List<String> list = new ArrayList<String> ();
map.set( KEY2, list );
List<String> valueList = map.get( KEY2 ); // Even with generics
assertEquals( list, valueList );
The trick here is the key which contains the type information:
TypedMapKey<String> KEY1 = new TypedMapKey<String>( "key1" );
TypedMapKey<List<String>> KEY2 = new TypedMapKey<List<String>>( "key2" );
The performance will be OK.
Field reuse is by using the same value type or by extending the key class of the type-safe object map with additional functionality.
Calculated fields could be implemented with a second map that stores Future instances which do the calculation.
Since all the manipulation happens in just two (or at least a few) methods, sending signals is simple and can be done any way you like.
To implement automatic parent/child handling, install a signal listener on the "set parent" signal of the child and then add the child to the new parent (and remove it from the old one if necessary).
Since no framework is used and no tricks are necessary, the resulting code should be pretty clean and easy to understand. Not using String as keys has the additional benefit that people won't litter the code with string literals.
So basically you're trying to create a new kind of object model with more dynamic properties, a bit like a dynamic language?
Might be worth looking at the source code for Rhino (i.e. Javascript implemented in Java), which faces a similar challenge of implementing a dynamic type system in Java.
Off the top of my head, I suspect you will find that internal HashMaps ultimately work best for your purposes.
I wrote a little game (Tyrant - GPL source available) using a similar sort of dynamic object model featuring HashMaps, it worked great and performance was not an issue. I used a few tricks in the get and set methods to allow dynamic property modifiers, I'm sure you could do the same kind of thing to implement your signals and parent/child relations etc.
[EDIT] See the source of BaseObject how it is implemented.
You can use the bytecode manipulation libraries for it. Shortcoming of this approach is that you need to do create own classloader to load changes in classes dynamically.
I do almost the same, it's pure Java solution:
Users generate their own models, which are stored as JAXB schema.
Schema is compiled in Java classes on the fly and stored in
user jars
All classes are forced to extend one "root" class, where you could put every extra functionality you want.
Appropriate classloaders are implemented with "model change"
listeners.
Speaking of performance (which is important in my case), you can hardly beat this solution. Reusability is the same of XML document.