Write access for node from JComponent
Hello, I created a custom component with swing but I can't change properties of the corresponding concept (properties: isFinished : boolean)
The error message I get when clicking the checkbox is
How can I accomplish this? Thanks in advance.
component provider: (node, editorContext)->JComponent { final JCheckBox check = new JCheckBox(); check.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { node.model/.getRepository().getModelAccess().runWriteAction({ => node.isFinished = check.isSelected(); }); } }); check; }
The error message I get when clicking the checkbox is
IllegalModelChangeError: registered node can only be modified inside undoable command or in 'loading' model [items]
How can I accomplish this? Thanks in advance.
Please sign in to leave a comment.
and org.campagnelab.ui.code).
http://campagnelab.org/extending-mps-editors-with-buttons-just-got-easier/
The org.campagnelab.ui.code.Swing.Button class uses the
runWriteActionInCommand:
public void actionPerformed(ActionEvent event) {
ModelAccess.instance().runWriteActionInCommand(callback);
}
runWriteActionInCommand is marked deprecated in the MPS platform, but there
is no alternative suggested in the deprecated annotation, and it seems to
be the only one of these methods that works in this case.
You can get the UI code in the NYoSh repo at
https://github.com/CampagneLaboratory/NYoSh
Fabien
On Sat, Aug 23, 2014 at 8:01 AM, fxlex - Meta Programming System <
jetforum@jetbrains.com> wrote:
--
Fabien Campagne, PhD – http://campagnelab.org
Assistant Professor, Dept. of Physiology and Biophysics
Institute for Computational Biomedicine
Associate Director, Biomedical Informatics Core,
Clinical Translational Science Center
Weill Medical College of Cornell University
phone: (646)-962-5613 1305 York Avenue
fax: (646)-962-0383 Box 140
New York, NY 10021
Do you speak next-gen?
See how GobyWeb can help simplify your NGS projects at
http://gobyweb.campagnelab.org
The checkbox can be unchecked but checking takes 2 clicks. check.isSelected() is true after the first click but ticked only after 2 clicks which is a bit annoying. Any ideas?
Look at "read action"/"write action"/"command". The last seems to be what you need
[fxlex]
I experienced the same issue. I was not able to diagnose it, but I solved it by accident, so it's something.
The part that did the trick is the very last line. Try initializing the checkbox with a state based on your model. To clarify: SomeDef has a property called "presentation" which is of an enum type with the values "table" or "text".
This is how I use this Checkbox in my editor:
I do not know if this is the right thing in general when it comes to altering your model via a Swing component, but it's the only way I found so far.
To be honest, I haven't tried it yet. My sample above just worked out for me.
Fabien wrote:
I also wrote a short post about it.
However, when I get the project from GitHub, I tried to open it with MPS 3.2.3 and with MPS 3.3 RC1, both times, I was unsuccesful, meaning that I cannot open any concept or editor or anything. I get a bunch of IDE exceptions, and I cannot build the language :(
I know you mentioned you used MPS 3.2 EAP 4, but I start to wonder: how many installations of MPS does one need to have? Or, in other words, do I need to get exactly MPS 3.2 EAP 4 to look at this project?
Btw., in your blog post, you say it is MPS 2.3 EAP 4.
Thanks,
Robert
Anyways, with MPS 3.3 RC1, what I had to do was, after opening the project,
. postponing the migration (wizard pops up automatically)
. delete the "Test" model in the com.github.fxlex.ui.sandbox solution
. add a reference to from com.github.fxlex.ui.sandbox -> to the demolang language
That allowed me to open the Test editor.
I used your project as a tutorial and I think it helped me to learn a lot, thanks! The problem that remains for me is that the checkbox behaves as if it has three states.
When I look at your demolang, the checkbox behaves "as expected" (clicking it toggles between 'selected' and 'unselected').
When I use the checkbox cell in my editor, however, I want the following checkbox handler implementation:
With this model operation, the checkbox falls back into its weird "three-state-like" behavior you also experienced in you original question.
In my original implementation with a custom JCheckBox, I got rid of this behavior by initializing the CheckBox's selection property with the default enum value (see http://forum.jetbrains.com/message/Meta-Programming-System-1015-5).
Any idea what the reason for this behavior might be? When I remove my line node.enumProp.is(< enumMember >); and set the value of a text property instead (like in your demo language), the checkbox behaves fine again.
I also tried to not use the set-method, but rather do this:
Same result.
Next thing I tried is to enhance your checkbox cell with a "initial value" property since this did the trick for me in my original implementation.
However, as a MPS novice I couldn't make it work. Here is what I tried:
. I added a child to the CheckBox concept called initValueCondition:
. In the inspected cell layout, I added this like so:
The user would than be able to declare the checkbox's initial value like so:
However, I do not really know how to "get" the value of the query and pass it down to the CheckBox constructor call.
Any ideas or pointers where I can find something like that?
I tried to handle this query similiar than you do the CheckBoxCallBacks (due to lack of better knowledge). I declared an abstract type called CheckBoxFunction with an abstract method getValue().
In the reduction rule for the CheckBox, I added the implementation of this abstract type and pass it on to the CheckBox:
Honestly, I do not know what the "return getValue()" statement does in the COPY_SRCL macro.
Anyways, it compiles and the generated code looks okay as far as I can tell.
However, my editor where I use the checkbox falls back to the defualt editor presentation without giving me any warnings, or errors.
Any ideas how to achieve what I tr to do and where I headed in the wrong direction?
You can get the statements from a QueryFunction with the $COPY_SRCL macro:
In your case you are returning a value from your function and just "copying" the statements doesn't work. You can take a look at reduce_CellModel_JComponent on how to properly handle this case or you try something like this:
Then you can pass obj to the CheckBox constructor.
If your editor shows the default representation or throws a NullPointer you could preview the generated text of an editor that uses the checkbox and check the code for syntax errors.
Turns out I did pretty much what you propose, but I had a bad cast left in my query that caused my editor to fallback to the default representation. It didn't give me a warning, nor an error, so I wonder what goes wrong at runtime, but I do not need that cast anyways so I could savely remove it (it was a leftover from a previous attempt to make the "three state problem" go away: I tried to pass the node, the first argument of the CheckBox constructor, as a node<CheckBox> to be able to access the CheckBox children and properties; this, of course, is not needed).
Anyways, it finally works. I can initialize my CheckBox like so:
In this example, the checkbox allows the user to switch between a table or textual representation in the editor. I still don't understand why, without the initialization, the checkbox needs two clicks to show the "check", but with the initialization, it works just fine.
Let me know if you would be interested in me adding this functionality to your github project.
Thanks again,
Robert
You need this initialization because the default state of JCheckBox is unchecked. If you open the editor and the property is already set, your checkbox does not "project" the correct state of the model.
That you have to click twice is just an effect of this violation. The reason is, that MPS rebuilds the editor after a model change. On the first click, the property is set to checked, but because the checkbox is recreated, it is unchecked after the rebuild. Then you click a second time and your "on select" is invoked again, but because the same value is written to the property that it already has, there is no need to rebuild the editor and the checkbox is not recreated.