I am using a gwt cell tree and I want only one node to be selected in the whole tree but many nodes are being selected.
I am also trying this
S1= new SelectionModel();......
S1.setSelected(S1.getSelected(),false); but using this technique nothing is being selected.
I am having the following problem:
Can someone help??
Maybe SingleSelectionModel helps you;
SingleSelectionModel selectionModel = new SingleSelectionModel();
See Google Example 2
to SingleSelectionModel usage.
Code looks weird to me, because you firstly get selected object with S1.getSelected() command and then kinda re-select same object, so no wonder that nothing happens. Instead S1.getSelected() pass object that you want to select.
You need to provide a key provider to the selection model like this
selectionModel = new SingleSelectionModel<NamedObject>(new ProvidesKey<NamedObject>() {
#Override
public Object getKey(NamedObject item) {
return item.getKey();
}
});
This will uniquely identify the nodes in the tree.
Related
How to read all the row data from a multicolumn TreeViewer.
m_viewer.addSelectionChangedListener(new ISelectionChangedListener() {
#Override
public void selectionChanged(final SelectionChangedEvent event)
{
IStructuredSelection selection = (IStructuredSelection)event.getSelection();
Object [] selections = selection.toArray();
}
}
This code snippet gives only selected row value. I want to read all the data and save it in an xml file on click of a Save button. Can anyone help me to achieve that?
The objects you get from the structured selection are the objects provided by the content provider for the tree viewer. So you should be able to cast them to whatever class(es) the content provider uses and get the data from them.
This is similar to the objects that are passed to the tree viewer label provider.
If you want a serialize what is close to the visual representation of the tree, you can access the underlying Tree of the TreeViewer and traverse its TreeItems. This approach is described here: Get all TreeItems in an SWT Tree
Or you consider to just use the data model that the TreeViewer is showing and serialize its objects. Traversing the children of your data model is presumably already implemented in the content provider, usually a ITreeContentProvider, or an extension thereof and could be reused.
I have a JTable, it contains a custom AbstractTableModel that return an object when getValueAt is called. And of course I have a custom TableCellRenderer that is capable of getting/constructing the text from the object so that it can be displayed.
However now I would like to write a filter. Filter will be a simple toggle button. When it is turned on I would like the filter to be applied and when it is turned off I would like filter to be removed.
I have two problems due to that.
First one is that I have absolutely no idea how to write a filter when you have to filter by object rather than a primitive.
Second is I have no idea how to attached the said filter to the toggle button to be able to turn it on and off.
I am sorry if this is a retarded question but http://docs.oracle.com/javase/tutorial/uiswing/components/table.html#sorting was the most useless documentation I saw since explanation was not in depth.
Thanks to anyone for their help.
EDIT:
The object contains multiple fields, but I am interested in two filter toggles specifically. One returns a boolean value when I say isSuper, and the second return a string when I call getName. If first toggle is turned on it should show all entries that return true on isSuper, and the second toggle should show all entries where name is compromised of two words (space is present) when I call getName.
To be honest, the JavaDocs spell it out quite well...
With such little information to go on, the best you can hope for is an overview...
TableRowSorter<TableModel> trs = new TableRowSorter<TableModel>();
table.setRowSorter(trs);
// Create the row filder...
trs.setRowFilter(new RowFilter<TableModel, Integer>() {
#Override
public boolean include(RowFilter.Entry<? extends TableModel, ? extends Integer> entry) {
boolean include = false;
// Returns the value for the specific column...
CustomObject value = (CustomObject)entry.getValue(filterColumn);
if (filterBySuper) {
include = value.isSuper();
} else {
include = value.getName().startsWith(fistPart) && value.getName().endWith(lastPart);
}
return include;
}
});
When you want to update the filter, you simply need to call...
trs.sort();
First one is that I have absolutely no idea how to write a filter when you have to filter by object rather than a primitive.
Did you read the RowFilter API? It shows an example of how to create a custom filter based on a custom Object.
Second is I have no idea how to attached the said filter to the toggle button to be able to turn it on and off.
Did you read the tutorial and try running the demo? The tutorial uses a DocumentFilter to change the filter dynamically every time the user changes the text in the text field. So the tutorial shows you how to dynamically changes the filter based on user input. You can modify the code to change the filter every time the toggle button is pressed.
it contains a custom AbstractTableModel that return an object when getValueAt is called. And of course I have a custom TableCellRenderer that is capable of getting/constructing the text from the object so that it can be displayed.
Unrelated to my answer, but I don't really understand that statement. Are you saying every cell in the model returns a differently object, or does every cell return the same object but you just display a different property of the object for column1, column2, column3 etc? Either way it sounds like a weird design. We can probably suggest something better. Post your SSCCE that demonstrates the problem.
I am using wicket's CheckBoxMultipleChoice to let the user set a list of options. so far it works fine. but then i want to add a "check all" check box that checks all the options in the CheckBoxMultipleChoice and I am having problems with that.
here is my initial code
ArrayList<String> chosen;
List<String> choices = Arrays.asList(new String[]{"Train", "Bus", "Car"});
CheckBoxMultipleChoice myCheck = new CheckBoxMultipleChoice("transport", new Model(chosen), choices));
myCheck.setOutputMarkupId(true);
form.add(myCheck);
on submit i print out the values of chosen and its "Bus", "Car" etc. as expected.
now i am adding a checkbox to check all the choices using ajax:
Boolean checkOrNot;
final CheckBox checkAll = new CheckBox("checkAll", new Model(checkOrNot));
form.add(checkAll);
checkAll.add(new AjaxFormComponentUpdatingBehavior("onchange") {
#Override
protected void onUpdate(AjaxRequestTarget target) {
// here i am not able to set the checkboxes
// i tried doing this
chosen.clear();
chosen.add(new String("Car"));
chosen.add(new String("Train"));
myCheck.modelChanged();
// i have also tried recreating the multiple choice
myCheck = new CheckBoxMultipleChoice<T>("transport", new Model(chosen), choices);
myCheck.setOutputMarkupId(true);
target.addComponent(myCgecj);
target.addComponent(form);
}
});
I am running out of ideas and wondering if anyone has any solutions? thanks in advance for any help.
I didn't (and can't) try that right now, so this is to be taken with a grain of salt, but couldn't you use a CheckGroup for that?
From the JavaDoc:
Component used to connect instances of Check components into a group. Instances of Check have to be in the component hierarchy somewhere below the group component. The model of the CheckGroup component has to be an instance of java.util.Collection. The model collection of the group is filled with model objects of all selected Check components.
So a
new Checkgroup("group", choices)
should work for you. No need to reimplement that functionality.
P.S.: I'll check that as soon as I've got the chance to do so...
You could use javascript to mark the checkboxes.
An example, using jQuery:
mycheck.setOutputMarkupId(true);
checkAll.add(new SimpleAttributeModifier("onclick",
"$('#" + mycheck.getMarkupId() + " input:checkbox').attr('checked', $(this).is(':checked'))");
Well, another way to go is to use
checkBoxMultipleChoice.setDefaultModelObject(listOfAllElements); // Select all.
checkBoxMultipleChoice.setDefaultModelObject(Lists.newArrayList()); // Deselect all.
I know that you fount already an answer but in my case I had exactly the same issue, but the option to use the CheckGroup was not feasible because my list is built dynamically and at the beginning it can even be empty.
The situation for me was:
I was obliged to use the CheckBoxMultipleChoice because it allows me to have empty lists thus reflecting in the GUI. CheckGroups will always print one check box without label, even if the options for the component are empty.
Using AjaxFormComponentUpdatingBehavior would throw an exception saying it was only possible to use it in other components.
Using OnChangeAjaxBehavior would work with the selector CheckBox (select/deselect) but if used with the CheckBoxMultipleChoice then the event will fire but the actual values of the component will not be reflected in the model within the event.
Thanks god I found This Forum in Nabble.
Basically here Pedro Santos propose to use the AjaxFormChoiceComponentUpdatingBehavior instead. I followed the advice and finally I was able to get the values in the model.
Sometimes I think Wicket is Wicked :P
I try to realize a link (in fact many links) that update a table in an website using an AjaxLink of Wicket. But I fail, the table is never updated (I have "setOutputMarkupId(true)" and call "setDefaultModelObject" and "addComponent", but there must be something other thats wrong).
How can I realize a panel with a number of links and a table that displays dynamic data, dependent on the link clicked? Can someone give an example (Maybe two links, when the first one is clicked the table displays two random numbers from 1-10, when the second is clicked the table displays random numbers from 1-100)? Without reloading the entire page, but only the html for the table?
One possible reason might be that you are not using a 'refreshable' model, but rather fetching the list items and passing them directly to the component, thus the list get's serialized in the session and doesn't get updated.
If this is the case, pass a LoadableDetachableModel (that retrieves the list in it's load method) to the component. I can't be more specific without seeing your code.
I don't think you've defined what you are doing very clearly.
Are these 2 tables different implementations? If so, then your code is correct - you have to replace the old component with the new one, then add the new one to the ajax response.
Realistically though, I'd imagine that you have 1 table component implementation.
What you therefore need to do, is something like this:
public class RandomNumberListModel extends LoadableDetachableModel {
private int upperBound;
public RandomNumberListModel(int upperBound) {...}
public void setUpperBound(int upperBound) {...}
protected Object load() {
// generate random number list using upper bound
// return list
}
}
...
final MyTableComponent table = new MyTableComponent(new RandomNumberListModel(30));
add(table);
AjaxLink link = new AjaxLink("myButton") {
public void onClick(final AjaxRequestTarget target) {
table.getModel().setUpperBound(100);
target.addComponent(table);
}
};
add(link);
(Edit) I've added a dynamic, reusable model to illustrate how the model would work. There are different ways of implementing this, depending on what you want to be reusable. The key point is that the model generates the list dynamically, i.e. per request, and the upperBound of the number range can be manipulated in the onClick callback.
Like jboyd was asking do you have code that knows to send the table contents back in the Ajax response?:
final Component tableComponent = ....;
AjaxLink link = new AjaxLink("myButton"){
public void onClick(final AjaxRequestTarget target) {
target.addComponent(tableComponent);
}
};
add(link);
The addComponent piece is the part jboyd is referring to.
There is one such example among the wicketstuff.org examples, the tree/tree table one. The three links at the top change the table.
i think this not a specific problem to me; everybody might have encountered this issue before.
To properly illustrate it, here's a simple UI:
As you can see, those two spinners are controlling a single variable -- "A". The only difference is that they control it using different views.
Since these two spinners' displaying values are synchronized, cyclic event shows up.
If i change the top spinner, "A" will be changed and the bottom spinner's value will also be updated accordingly. However, updating the bottom spinner's call (such as setValue) will also trigger another event instructing the top spinner to update based on the bottom spinner's value. Thus creates a bad cycle which can eventually cause a StackOverFlow exception.
My previously solution is kinda cumbersome: i placed a guarding boolean to indicate whether the 2nd updating call should be performed.
Now i'd like to ask "how can i handle such situation elegantly? ( in general, not specific to spinners )"
thx
Update:
Since i've got 2 answers suggesting me to utilize the observer structure, i have to say something about it.
Like what i've said, it's great but far from being perfect. Not only because of its inherent complexity, but also Its inability to solve the problem.
Why? To see the reason, you must realize the tight coupling of the View and Model-Controller in Java Swing. Lets take my spinner UI for an example. Suppose the variable A is actually an Observer object. Then, after firing the first state change event from the top spinner, the Observer "A" will update its value and fire a PropertyChange event to notify the bottom spinner. Then comes the 2nd updating which updates the bottom spinner's View. However, changing bottom spinner's view inevitably triggers a redundant event that will try to set "A"'s value again. Afterwards, the deadly loop is fully constructed and the stack overflow will be thrown.
In theory, the Observer model tries to solve the direct cycle by introducing 2 independent feedback paths. The chained updating odds(in event-response codes) implicitly form a bridge connecting both paths, making a cycle again.
Going back to Model-View-Controller, think about what your Model is, and what your View is.
In your current implementation, you have two models (one for each Spinner control), and they're being synced through the View layer.
What you should be doing though is share the same backing model. For the spinner with a subtracted value, create a proxy to the original model. ie:
class ProxySpinnerModel implements SpinnerModel {
getValue() { return originalSpinner.getValue() - 10 }
setValue(v) { originalSpinner.setValue(v+10) }
}
spinnerA = new JSpinner()
spinnerB = new JSpinner( new ProxySpinnerModel( spinnerA.getModel() ) )
Now, you don't need to add listeners, since they're both working off the same model and the default implementation (the originalModel) already has change listeners which it fires to the view.
Problem Solved
I've got many different suggestions. Particularly,
i want to thank Marc W & Reverend Gonzo. I'm here to make a summary for these ideas; this can save your time navigating thru big chunk of texts.
This problem can be easily bypassed if you carefully decouple the View and Model-Controller.
The dead cycle is caused by dependent writes: write_1 -> write_2 -> write_1 ->.... Intuitively, breaking the dependency can solve the problem elegantly.
If we look into the problem in depth, we can find updating the corresponding views doesn't necessarily involves an external write call. Actually, a view only depends on the data it's representing. Known this, we can then re-write the logic as follow: write_1 -> read_2 & write_2 -> read_1.
To illustrate this idea, lets compare the 3 methods mentioned by different posters:
alt text http://www.freeimagehosting.net/uploads/2707f1b483.png
As you can see, only the proxied view can solve all the dependency thus it's the generic solution for this knid of problem.
In practice, it can be implemented as something like this (in your event-response codes):
setValue(newValue);
anotherSyncUI.parse(); // not anotherSyncUI.setValue() any more
anotherSyncUI.repaint();
No more loops. Solved.
It's a bit complicated, but you could make A actually be an object that's observable. Both spinners (or whatever needs to update itself based on A's value) would then observe A. Whenever A changes, the spinners (or again, whatever object) update themselves to reflect the new value of A. This decouples the spinners' logic from one another. In your example here, the spinners should not be coupled to one another because they really have nothing to do with each other. Instead, they should both simply be bound to A and take care of their own view updating individually.
Whenever the value in the first spinner is changed, you would simply update A's value to match it. Whenever the value in the second spinner is changed, you would of course add 10 to its value before assigning it to A.
Update
In response to the update to your original question, my answer is that the spinners do not listen to one another's change events. Have a separate event handling method for each spinner. A user clicking the up or down arrows in the spinner generates a different event than calling setValue on the spinner programmatically, correct? If the spinners are completely independent of one another, there will be no infinite loop.
E.g. for the second spinner, calculate A-10 and then compare it to the current value of the spinner. If it's the same, do nothing, ending the infinite loop. Similarly for the first spinner.
I think there are also ways to update the spinner's model in a way that doesn't fire an event, but I don't know them off the top of my head.
Use a single SpinnerModel for both JSpinners. See the following code:
Note that the call to setValue() is only made once each time a new value is defined by one of the JSpinners.
import java.awt.BorderLayout;
import javax.swing.*;
public class Test {
public static void main(String[] args) {
JFrame jf = new JFrame();
SpinnerModel spinModel = new MySpinnerModel();
JSpinner jspin1 = new JSpinner(spinModel);
JSpinner jspin2 = new JSpinner(spinModel);
jf.setLayout(new BorderLayout());
jf.add(jspin1, BorderLayout.NORTH);
jf.add(jspin2, BorderLayout.SOUTH);
jf.pack();
jf.setVisible(true);
jf.setDefaultCloseOperation(3);
}
}
class MySpinnerModel extends AbstractSpinnerModel {
private int _value = 0;
private int _min = 0;
private int _max = 10;
#Override
public Object getNextValue() {
if (_value == _max) {
return null;
}
return _value + 1;
}
#Override
public Object getPreviousValue() {
if (_value == _min) {
return null;
}
return _value - 1;
}
#Override
public Object getValue() {
return _value;
}
#Override
public void setValue(Object value) {
System.out.println("setValue(" + value + ")");
if (value instanceof Integer) {
_value = (Integer) value;
fireStateChanged();
}
}
}
It seems you're really observing the wrong thing. From the example given I presume what you want to detect is the user's actions on the controls, not the changes in the values themselves. As you've outlined, changes in your model are reflected in the values of the spinners, and it is this which forms the infinite loop of events.
However, diving further into the UI implementation may not be the answer you want. In that case I'd say the best you can do is either your current guard solution, or to better extract the logic into your model (similar to what Marc and William have said). How that can be done will depend on the 'real world' model behind a particular implementation of the provided puzzle.
As a rule, your model should not be defined by your GUI. Ie, the SpinnerModel that backs each JSpinner should not be your value A. (That would be a horribly inelegant tightly coupled dependency on a particular view.)
Instead, your value A should either be a POJO or a property of an object. In which case, you can add PropertyChangeSupport to it. (And presumably have already done so in any case, as you want your spinners to update automatically if A is changed by other parts of your program).
I realise this is similar to Marc W's answer, and you were concerned that it's "complicated", but PropertyChangeSupport does almost all of it for you.
In fact, for trivially simple cases, you can just use a single class that wires a "setProperty" method through to a "firePropertyChange" call (as well as storing the value in a HashMap for any "getProperty" calls).
I don't really want to solve your problem but I find it interesting. I have already been confront to it and solved it each time a different way. But when I think about the 'why ?' and not about the 'how ?' am staying perplexed.
This problem only exists because I am using an automatism (MVC) which had to help me, and exactly in that way. The art how the components are used make this automatism a barrier to a beautiful code.
Why do set #setEvent() has to produce the same event as a GUI action?
Though, my opinion is also pretty close to Observer pattern but it is a bit lighter than that!!!
Have A as a variable with a setter
private Integer A;
setA(int A)
{
this.A = A;
refreshSpinners();
}
refreshSpinners()
{
setSpinnerA();
setSpinnerAMinus10();
}
setSpinnerA()
{
// show value of A
}
setSpinnerAMinus10()
{
// show value of A-10
}