I have a DropDownChoice component on my Form and when the form is submitted and nothing is selected from the DropDownChoice, the default value that's returned is "-1". Is there are a way to change this behavior?
This behavior is controlled by a constant field
protected static final String NO_SELECTION_VALUE = "-1";
in AbstractSingleSelectChoice, which is a superclass of DropDownChoice.
You can't change this value in a subclass, so in order to change the value used, you would have to locate uses of this constant and override the methods that use it to use some other default.
Doing that would be risky, though it's likely possible. I know you'd have to override at least getDefaultChoice(final Object selected) and getModelValue().
Why do you wish to do this? It's a sensible value for its purpose.
Perhaps there's a better approach to accomplishing your underlying need.
Hook to the beforeSubmit, and change what you want.
I think it is good to have such a value, Since first element is 0, notting means -1.
Related
I have implemented my own ComboBoxModel:
public class MyComboBoxModel extends AbstractListModel<MyType>
implements ComboBoxModel<MyType> {}
Now I obviously need to override public void setSelectedItem(Object item), but the documentation says the following:
The implementation of this method should notify all registered ListDataListeners that the contents have changed.
To do so, I guess I need to use the method AbstractListModel.fireContentsChanged(Object, int, int). The Problem with JComboBox is, that one can set the selected item without it having to be in the list, so when setSelectedItem(Object) is called, I cannot necessarily determine the index of the item in question, since it need not be in the underlying model.
I found an answer to another question (https://stackoverflow.com/a/7077192) which uses fireContentsChanged(item, -1, -1) in this case, but the person did not provide any details to that part of code. Now I am wondering, whether this was the correct way to deal with a changed selected item?
Should I ALWAYS use -1 as both indexes? Should I try and get the real index of an item, if it is actually in the model? Or should I do something entirely different?
I need to set the null value string for a dropDownChoice component. The default value for null choice is "Choose One", which is hardcoded in the Wicket AbstractSingleChoice class.
The usual way of overriding this is to define a property resource.
However my DropdownChoice component is dynamically generated at runtime, and added to a panel (which is within a datatable). The DropDownChoice is not specifically referenced in the markup.
I'm looking for suggestions on how to programmatically override the default null value string in this situation. It would be nice if the DropDownChoice constructor had an additional parameter for this.
Do I need to programmatically create a new property resource?
Hope this makes sense.
You can override AbstractSingleSelectChoice.getNullKey() and AbstractSingleSelectChoice.getNullValidKey() in order to make Wicket retrieve a localized resource from a .properties or .xml file that does not have the component id as part of the key. This is documented in this JIRA issue: Open DropDownChoice null value internationalization key
For instance:
DropDownChoice ddc = new DropDownChoice(id, model, choices){
#Override
protected String getNullKey(){ return "customDdcNullValue"; }
#Override
protected String getNullValidKey(){ return "customDdcNullValue"; }
}
Will retrieve the <option>'s text from the customDdcNullValue property.
These methods seem to have been added in version 1.4.4, if you're on 1.3, you could always use an IChoiceRenderer with the DropDownChoice that returns the proper String in the case of null value. Note that you could retrieve it from resources (with getString(), or StringResourceModel), or grab the value from database/cache if necessary. This may depend on how are you already localizing the choices for non-null values.
Also, you could use the source code of AbstractSingleSelectChoice.getDefaultChoice() to roll your own DropDownChoice with this behavior.
UPDATE: Another way of handling this is to provide your own custom value that represents null, or no-choice. Just remember to use setNullValid(false) on the DropDownChoice to prevent null from appearing when there is a selected value, and initialize the ddc's model with your no-selection value when you still don't know its value in order to avoid Wicket provide null in the getDefaultChoice() call.
When defining the value for your no-selection option, pay special attention to this part of AbstractSingleSelectChoice.getDefaultChoice():
// Null is not valid. Is it selected anyway?
if ((selected == null) || getNoSelectionValue().equals(selected) ||
selected.equals(EMPTY_STRING))
{
Take into account that getNoSelectionValue() returns -1, so please do not use -1, or an empty string, as your custom null value. I learnt this the hard way, believe me, it's not pleasing.
You should use localisation feature to achieve it. There is a method org.apache.wicket.resource.loader.IStringResourceLoader.loadStringResource(org.apache.wicket.Component,java.lang.String) which returns a string value to display for a given component. The string will be a resource key, for your case it is the "nullValid" string, IIRC.
So, you can implement your custom resource manager which will pick data from a database instead of .properties files.
I need a value of Someclass based on the key. And the key can be a string, boolean, or another Object, that's why I used Object as key. But I have a problem, when the object is a string. and I have two Object of string, which is equals, but it should return different value, because it is a different object.
The code that I have:
Object k = new String("action");
Object l = new String("action");
Hashtable<Object,SomeClass> map = new Hashtable<Object, SomeClass>();
map.put(k,anObject1);
map.put(l,anObject2);
map.remove(k); // it is removing both with k and l.
when I check the hashCode() of both object, it returns the same value, which is ultimately what not I want.
Is there any solution of this? Is I need to make a new class that override Equals() of object? but, still, the hashCode. :( The problem is I need a hashCode that return different value for different Object.
Edited:
I am doing this because I need to do different action based on what the string is, but the action will differ by the value returned by map with the key.
Updated:
Okay, here is all the story why I need this weird thing.
I have a player instance, and 3 land instances. So I wanted the player to plow land1, land2, land3. If the player wanted to plow a land, that land make a running thread, that tell the player to move to position X, and do the job action, and wait() by object action, and when the other thread notify this thread by object action, the land then modify itself. The player then make an animation based on the object action. I am having ArrayList<Position> destination and 'ArrayList action` to have it. Maybe you can read my other question about this here.
So I wanted to make the action cancelable. I implements it by also passing the action object. I have a button that show for every action, and every button will cancel that action. I passing the action here too. So when I click the button, the land will get the notify. The problem is I can't make the ArrayList<Position> remove the destination by the Action, because it's don't know where the index. I'm new to Java but have been using C++ a lot, so I thinking of using Hashtables, because it's O(1) differs with C++ O(log n), and kind of convenience because not many changes to my current code.
Is it understandable?
You could use an IdentityHashMap instead, though it might help if you could explain what exactly you're trying to do here. This is not a terribly common requirement and unless you have some very good reasons you want to do this, there's probably something else you're better off doing.
By the way, a Map can only hold one value for a single key. So after your second call to map.put, the first value you put in there is already gone.
Edit:
Ok, I've read your explanation and... well, I'm still not completely clear on what you're doing. Here's my best guess from what you've said:
You have an action called "plow", represented as a String.
You are telling the player to "plow" 3 different lands.
You want to be able to cancel that action for one land without cancelling it for the others.
To do this, you're trying to map 3 different instances of the String "plow" to the Positions of the 3 different lands.
If this (or something like it) is what you're trying to do, here are my thoughts:
The action String should not be unique... "plow" is "plow", whatever land it is done on. What is unique is the combination of an action like "plow" and the land that action is to be done on.
Given that, "plow" should be considered something like an "action type". It might be good to use an enum or some such to represent action types.
An Action class should contain an "action type" and a Position. When you click to cancel that Action, you have the data you need right there.
The String class overrides equals() and hashCode() such that two Strings with the same characters have the same hashCode() and are equal. But the Object class itself has an equals() method that never returns true for two different objects. It's actually not necessary (nor possible!) for hashcodes to be unique; they just have to be nicely distributed across the range of possible values.
So in any case: String is ill-suited for your requirements, I agree; but an object of any other class that doesn't override equals() and hashCode() should be just fine.
This is the very semantics for a Hashmap: keys are uniqe and each value from the key domain maps to at most one value in the Hashmap.
Think of it like an array, only that the array is not indexed by numbers but by arbitrary objects. You can't have more than one different value at the same index in an array.
You might consider creating your own class to represent a Key and define your own hashcode by some unique identifier .. perhaps using a AtomicLong
I have a function which returns an int value for a given key (from a HashMap<String, Integer>). If the key doesn't exist, I want to return something the caller can check for. It seems that, most commonly, this would be a "returns -1 if key doesn't exist" kind of thing. However, I can't reserve -1 for that purpose in my case, because negative numbers are feasible values for keys which do exist.
The only other options I have been able to come up with are the following:
Change return type to Integer wrapper class and check for null
Return something very unlikely, such as Integer.MIN_VALUE
Make an additional boolean keyExists(String key) function which should always be called first
Switch to float and use NaN instead
I am writing this in Java, but people from similar language backgrounds are welcome to post. Thanks!
The first option is, in my opinion, the cleanest. Magic numbers like -1 and Integer.MIN_VALUE are kind of messy, especially when the values aren't intuitive. That is an idiomatic C solution, which Java developers will hate you for. Depending on what you're actually using this for you could also throw a "KeyNotFoundException" if this only happens in "exceptional" circumstances.
I vote for throwing a checked exception here. Generally I dislike checked exceptions but it seems like a reasonable thing to do in this case. The case where the value is not present will need to be handled separately from the case where the value is present, using an exception would make that clear.
Actually your idea to add a keyExists method is the best of the ideas you list, because it doesn't rely on the user knowing to look for a special value. If you go that way then you could throw an exception as a backup plan in case the map contents change between the call to keyExists and the retrieval.
Although it depends heavily on the application and know constraints, I would prefer #1 above. The reason is because then it is explicit - it is always better to have an explicit situation than an implicit - such as MIN_VALUE - in my experience.
Another option is to have a wrapper object that contains the result value as a primitive int, but also has a status value or something similar. So it could be something like:
public class Wrapper {
private int value = Integer.MIN_VALUE;
private boolean isValid;
// appropriate getters and setters etc.
}
You could also include an enum instead of a boolean to have a state instead, depending on the complexity of the problem. If you see this element holding composite information - sets of information keyed of single keys, or something similar - a container object or status object can be very valuable in those cases.
float is unsafe as not all int values can be accurate represented as int values. long is a better options as all int values can be safely stored as long and you will have plenty more values for not-found.
If you are using a Map you have an Integer object anyway so why not return that (or null)
If you really want to use primitives (for efficiency ??) I suggest you look at TObjectIntHashMap instead. This uses primitive int values. To check for absense, you have to check containsKey() seperately.
Two situations are typical:
You have a high expectation of
finding a value for a particular
key.
You are not sure if a particular key
has a value stored.
If assumption 1 is wrong, then it's likely to indicate a bug, so protect your assumption in the access method with an assertion.
If 2 applies, how would you be sure about what's returned? so provide a test method such as "keyExists" and know absolutely before accessing the map.
In case 1, no checking is required, which is much cleaner, but the access will fail if you are wrong.
With special cases such as -1 or Integer.MIN_VALUE it is very hard to be sure that they won't be used.
Languages like Haskell, Scala and C# have special types to convey presence / absence of a value which is far better than use of null (if you forget to test you will likely get a NullPointerException)
Option 5: Throw an Exception
Although, in this case, I'd vote for using the Integer class.
I think you should combine options #1 and #3, since that's consistent with the behavior of the underlying HashMap. From HashMap's get method documentation:
Returns the value to which the specified key is mapped in this identity hash map, or null if the map contains no mapping for this key. A return value of null does not necessarily indicate that the map contains no mapping for the key; it is also possible that the map explicitly maps the key to null. The containsKey method may be used to distinguish these two cases.
Change return type to Integer wrapper class and check for null.
This is the more common option.
Note that I'm not actually doing anything with a database here, so ORM tools are probably not what I'm looking for.
I want to have some containers that each hold a number of objects, with all objects in one container being of the same class. The container should show some of the behaviour of a database table, namely:
allow one of the object's fields to be used as a unique key, i. e. other objects that have the same value in that field are not added to the container.
upon accepting a new object, the container should issue a numeric id that is returned to the caller of the insertion method.
Instead of throwing an error when a "duplicate entry" is being requested, the container should just skip insertion and return the key of the already existing object.
Now, I would write a generic container class that accepts objects which implement an interface to get the value of the key field and use a HashMap keyed with those values as the actual storage class. Is there a better approach using existing built-in classes? I was looking through HashSet and the like, but they didn't seem to fit.
None of the Collections classes will do what you need. You'll have to write your own!
P.S. You'll also need to decide whether your class will be thread-safe or not.
P.P.S. ConcurrentHashMap is close, but not exactly the same. If you can subclass or wrap it or wrap the objects that enter your map such that you're relying only on that class for thread-safety, you'll have an efficient and thread-safe implementation.
You can simulate this behavior with a HashSet. If the objects you're adding to the collection have a field that you can use as a unique ID, just have that field returned by the object's hashCode() method (or use a calculated hash code value, either way should work).
HashSet won't throw an error when you add a duplicate entry, it just returns false. You could wrap (or extend) HashSet so that your add method returns the unique ID that you want as a return value.
I was thinking you could do it with ArrayList, using the current location in the array as the "id", but that doesn't prevent you from making an insert at an existing location, plus when you insert at that location, it will move everything up. But you might base your own class on ArrayList, returning the current value of .size() after a .add.
Is there a reason why the object's hash code couldn't be used as a "numeric id"?
If not, then all you'd need to do is wrap the call into a ConcurrentHashMap, return the object's hashCode and use the putIfAbsent(K key, V value) method to ensure you don't add duplicates.
putIfAbsent also returns the existing value, so you could get its hashCode to return to your user.
See ConcurrentHashMap