I'd prefer to hold off until 2.0.1 - Todd just created the 2.0 tag, and we 
really need to get it out the door (we have a press release tentatively 
scheduled to go out the week of Jan 10).

On Dec 21, 2010, at 1:15 AM, Chris Bartlett wrote:

> Greg,
> 
> Is there time before the 2.0 vote to put in the constructor work-around I
> suggested?  I see there have been a few commits recently and see it as very
> low risk.
> 
> Either way I will add it to JIRA for 2.0.1.  As a pure fix, or the fix and
> removal of the workaround.
> 
> Chris
> 
> On 12 December 2010 21:08, Greg Brown <gk_br...@verizon.net> wrote:
> 
>> Yes, that would definitely explain it.
>> 
>> On Dec 12, 2010, at 9:01 AM, Chris Bartlett wrote:
>> 
>>> I didn't think to look that closely at installSkin(), but it sounds like
>> the
>>> behaviour you describe would give the same problem due to there not being
>> a
>>> skin installed when the setText() call occurs, so no there is no listener
>> to
>>> catch the TextAreaContentListener#paragraphInserted(TextArea, int) event.
>>> 
>>> On 12 December 2010 20:03, Greg Brown <gk_br...@verizon.net> wrote:
>>> 
>>>> I don't think the problem is that the skin is getting installed twice -
>>>> installSkin() was written specifically to handle that case. When a more
>>>> specific component/skin mapping exists, installSkin() is supposed to
>> ignore
>>>> the first call because it knows a more specific skin will be installed
>>>> later. So something else is probably going on, most likely related to
>> the
>>>> call to setText().
>>>> 
>>>> On Dec 11, 2010, at 1:48 PM, Chris Bartlett wrote:
>>>> 
>>>>> I created a custom skin extended from TerraTextAreaSkin in order to
>>>> handle these keypresses.
>>>>> However I had problems after associating my subclass of TextArea with a
>>>> custom skin.
>>>>> 
>>>>> 
>>>>> TextArea only has one constructor, a public no args one which will
>> always
>>>> be called when instantiating a subclass.
>>>>> public TextArea() {
>>>>>   installSkin(TextArea.class);
>>>>>   setText("");
>>>>> }
>>>>> 
>>>>> The problem is that org.apache.pivot.wtk.skin.TextAreaSkin is installed
>>>> immediately, and this skin holds some state.
>>>>> The setText() call ultimately adds a empty paragraph via
>>>> TerraTextAreaSkin(TextAreaSkin).paragraphInserted(TextArea, int), and
>> this
>>>> is tracked within TextAreaSkin.
>>>>> 
>>>>> 
>>>>> Normally I would extends a skin & component as follows
>>>>> public class MyTextAreaSkin extends TerraTextAreaSkin {
>>>>>   public MyTextAreaSkin() {
>>>>>       super();
>>>>>   }
>>>>>   // My styles, overrides & supporting code
>>>>> }
>>>>> 
>>>>> public class MyTextArea extends TextArea {
>>>>>   public MyTextArea() {
>>>>>       super();
>>>>>       installSkin(MyTextArea.class);
>>>>>   }
>>>>>   // My properties, overrides & supporting code
>>>>> }
>>>>> 
>>>>> And make them known to the Theme
>>>>> Theme.getTheme().set(MyTextArea.class, MyTextAreaSkin.class);
>>>>> 
>>>>> 
>>>>> This will fail because by the time I get to install my custom skin in
>> the
>>>> MyTextArea constructor, it superclass has already installed a skin,
>> *and*
>>>> altered its state.
>>>>> The installSkin() in MyTextArea runs again, and essentially resets the
>>>> state by installing a new skin over the old one.
>>>>> The next call to TextArea.setText(Reader) will fail with the following
>>>> error
>>>>> 
>>>>> Exception in thread "main" java.lang.IndexOutOfBoundsException: index 0
>>>> out of bounds.
>>>>> at
>>>> 
>> org.apache.pivot.collections.ArrayList.verifyIndexBounds(ArrayList.java:577)
>>>>> at org.apache.pivot.collections.ArrayList.get(ArrayList.java:346)
>>>>> at
>>>> 
>> org.apache.pivot.wtk.skin.TextAreaSkin.paragraphsRemoved(TextAreaSkin.java:1216)
>>>>> at
>>>> 
>> org.apache.pivot.wtk.TextArea$TextAreaContentListenerList.paragraphsRemoved(TextArea.java:511)
>>>>> at
>>>> 
>> org.apache.pivot.wtk.TextArea$ParagraphSequence.remove(TextArea.java:420)
>>>>> at org.apache.pivot.wtk.TextArea.setText(TextArea.java:722)
>>>>> at org.apache.pivot.wtk.TextArea.setText(TextArea.java:667)
>>>>> at mytextarea.SimpleTest.test(SimpleTest.java:23)
>>>>> at mytextarea.SimpleTest.main(SimpleTest.java:27)
>>>>> 
>>>>> 
>>>>> This occurs because the state held in the TextArea component is now out
>>>> of sync with the state held in the TextAreaSkin.  (The component
>> remembers
>>>> the first paragraph that was added, but the newly installed skin knows
>>>> nothing about it, so fails when it tries to remove the paragraph)
>>>>> 
>>>>> Hopefully that all makes sense!
>>>>> 
>>>>> 
>>>>> A simple fix would be something like changing the TextArea constructors
>>>> as follows
>>>>> // Single constructor to be replaced with 2 new constructors
>>>>> public TextArea() {
>>>>>   installSkin(TextArea.class);
>>>>>   setText("");
>>>>> }
>>>>> 
>>>>> ...becomes...
>>>>> 
>>>>> // Default
>>>>> public TextArea() {
>>>>>   this(TextArea.class);
>>>>> }
>>>>> 
>>>>> // To be called by any class extending this which wishes to use a
>> custom
>>>> skin
>>>>> public TextArea(Class<? extends TextArea> componentClass) {
>>>>>   installSkin(componentClass);
>>>>>   setText("");
>>>>> }
>>>>> 
>>>>> 
>>>>> Then in the constructor for MyTextArea() I can call the 2nd constructor
>>>> and only install a single skin instance
>>>>> public MyTextArea() {
>>>>>   super(MyTextArea.class);
>>>>> }
>>>>> 
>>>>> Zip file (hopefully) attached with some simple test code to demonstrate
>>>> the issue.
>>>>> 
>>>>> Chris
>>>>> 
>>>>> On 11 December 2010 17:25, Chris Bartlett <cbartlet...@gmail.com>
>> wrote:
>>>>> I forgot to add that it would be nice to be able to place the caret at
>>>> the start and end of the file with keystrokes such as CTRL+HOME and
>>>> CTRL+END.
>>>>> Holding SHIFT in addition to the other keys would bound the selection
>>>> from the caret to the start/end point respectively.
>>>>> 
>>>>> As I will be following up on the whole component keystroke handling
>> area
>>>> in PIVOT-638, I will just make a note to include it then.
>>>>> 
>>>>> Chris
>>>>> 
>>>>> On 11 December 2010 17:12, Chris Bartlett <cbartlet...@gmail.com>
>> wrote:
>>>>> Greg,
>>>>> 
>>>>> I finally found a little time to play around with TextArea today, and
>> it
>>>> looks good.   The only points of note I could find are the following.
>>>>> 
>>>>> 
>>>>> TextAreaSkin fails as follows if when the END key is pressed on the
>> final
>>>> line of a TextArea (ie, a line without a linebreak)
>>>>> java.lang.IndexOutOfBoundsException
>>>>> at org.apache.pivot.wtk.TextArea.getCharacterAt(TextArea.java:870)
>>>>> at
>>>> org.apache.pivot.wtk.skin.TextAreaSkin.keyPressed(TextAreaSkin.java:934)
>>>>> at
>>>> 
>> org.apache.pivot.wtk.Component$ComponentKeyListenerList.keyPressed(Component.java:524)
>>>>> at org.apache.pivot.wtk.Component.keyPressed(Component.java:2813)
>>>>> at
>>>> 
>> org.apache.pivot.wtk.ApplicationContext$DisplayHost.processKeyEvent(ApplicationContext.java:1257)
>>>>> at java.awt.Component.processEvent(Unknown Source)
>>>>> at
>>>> 
>> org.apache.pivot.wtk.ApplicationContext$DisplayHost.processEvent(ApplicationContext.java:709)
>>>>> ...
>>>>> You can see this by simply pressing END with a freshly created TextArea
>>>> with no content.
>>>>> If you add a second line, END will work on the first line, but throw on
>>>> the last one.
>>>>> 
>>>>> 
>>>>> TextAreaSkin.getInsertionPoint(int, int) did not behave as I
>> anticipated
>>>> in one scenario.
>>>>> I was expecting it to place the caret at the end of the text (the same
>>>> placement that would occur if I press the END key) if I left click
>> anywhere
>>>> within the 'space' following the final character in TextArea.
>>>>> Clicking in that space currently seems to have no effect.
>>>>> 
>>>>> Chris
>>>>> 
>>>>> 
>>>>> <mytextarea.zip>
>>>> 
>>>> 
>> 
>> 

Reply via email to