aspose file tools*
The moose likes Swing / AWT / SWT and the fly likes setEditable and blinking cursor Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Swing / AWT / SWT
Bookmark "setEditable and blinking cursor" Watch "setEditable and blinking cursor" New topic
Author

setEditable and blinking cursor

Fred Hamilton
Ranch Hand

Joined: May 13, 2009
Posts: 679
Greetings. I have a JTextPane and I wish to prevent the user from doing any editing. so setEditable(false) was easy enough to find, but the problem is that seems to disable the blinking cursor that represents the caretPosition.

I'd like to be able to disable user editing but keep the blinking cursor, is their a way to do this? I suppose I could use some kind of styled text to display the last character before the caretPosition, but I'd rather not go that way if I can help it.

thanks.
Michael Dunn
Ranch Hand

Joined: Jun 09, 2003
Posts: 4632
don't know if there's a built in way, but this might work (but will also disable/consume e.g. F keys)

Fred Hamilton
Ranch Hand

Joined: May 13, 2009
Posts: 679
OK thanks Michael, I hadn't thought about consuming key events, but that seems plausible enough. And as I was mulling this over, another idea occurred to me.

In my chess program, the JTextPane displays chess notation as pieces are dragged about on the board. The CaretListener on the JTextPane will react to mouseclicks on a particular notation, and adjust the position on the board accordingly. If anyone edits the JTextPane, the relationship between the board and the pane goes out of wack. And I wish to display the cursor as a visual aid.

So I suppose what I could also do is add a key listener to the pane, and whenever a key stroke is detected, the event handler for the key listener would disable the caretlistener, delete the character that was just typed, and then re-enable the caretlistener. Not the cleanest of solutions, but it does have the advantage that it would allow me to move pieces on the board by typing in the correct notation of I so desired.
Rob Camick
Ranch Hand

Joined: Jun 13, 2009
Posts: 2227
    
    8
I believe the DefaultCaret has methods like focusLost and focusGained, that disable/enable the painting of the caret. So there appears to be a check for non-editable in there as well.

You should be able to extend the DefaultCaret and customize those methods to make sure the caret is enabled on focusGained.
Maneesh Godbole
Saloon Keeper

Joined: Jul 26, 2007
Posts: 10535
    
    9

On a side note, having a cursor visible in a non editable field is bad usability. A cursor is supposed to indicate that the value can be changed. On this background you might want to drop your cursor .
PS> Needless to say, your requirement might be such that the cursor is absolutely required.


[How to ask questions] [Donate a pint, save a life!] [Onff-turn it on!]
Fred Hamilton
Ranch Hand

Joined: May 13, 2009
Posts: 679
Maneesh Godbole wrote:On a side note, having a cursor visible in a non editable field is bad usability. A cursor is supposed to indicate that the value can be changed. On this background you might want to drop your cursor .
PS> Needless to say, your requirement might be such that the cursor is absolutely required.


Duly noted Maneesh, I understand what you mean about the general purpose of a cursor in. No, It's not an absolute necessity, just a wish. In this particular application (see a brief description above) it is a useful and convenient visual aid, due to the nature of the information in the TextPane and it's relation to what is happening in other parts of the GUI. And popular commercial applications of similar purpose do make use of a blinking cursor in a non-editable field.

p.s. to Rob. Thanks for the tips, I didn't know about the DefaultCaret class. I couldn't see how that would help display a cursor in a non-editable pane, but I'll put in on my list for further investigation later. In any event, I do have at least one workaround which has the desired effect, so that'll buy me time to look for other solutions, all of which are useful from a learning perspective.
Fred Hamilton
Ranch Hand

Joined: May 13, 2009
Posts: 679
Anyways just to close the book on this (I think) , this is what I came up with.

1. Given that displaying a cursor in a (pseudo) non-editable TextArea is part of the requirement, and it is not so easy to do this.
2. Given that I want the app to respond to caret changes due to mouse clicks but effectively disable keystroke changes.
3. Given that in the future I may wish have the app respond to some keystroke changes.

I decided it would be simpler and more logical to get rid of the CaretListener altogether, and go with a mouseListener and a KeyListener. The MouseListener event handler duplicates the activities of a Caret change event handler for mouseclicks only.

The KeyListener event handler reverses all changes to the TextArea due to KeyEvents. This way I get to keep my blinking cursor and also leave the door open for some useful KeyEvents on the TextArea in the future.

Thanks to all for the suggestions, they're all useful from a learning perspective, which is what this exercise is re3ally about anyways.
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19787
    
  20

Fred Hamilton wrote:The KeyListener event handler reverses all changes to the TextArea due to KeyEvents.

You may want to check out a DocumentFilter then:
Installing it:
This way, you don't have to revert anything - because nothing even gets inserted / removed / replaced.

Note how I suggested to create a setter for readonly. This is because when readonly is true, you cannot change the text at all. That is including calling setText and similar methods. So if you want to change the text from code, turn readonly off for the filter, change the text, and turn it on again. Because this will all be done on the EDT the user can't try to update while readonly is off.


SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6
How To Ask Questions How To Answer Questions
Fred Hamilton
Ranch Hand

Joined: May 13, 2009
Posts: 679
Thanks Rob, that sounds promising. and esthetically more pleasing than deleting stuff I never really wanted in the first place. Anyways, I've pretty much got the program where I want it in terms of functionality, so I'll going back and reviewing several aspects for improvements and learning. Document Filters will go on the list, along with REGEX for parsing notation, alternate piece designs using images rather than draw commands. a proper tree structure for exploring alternate variations, a hashtable and some recursive algorithms for improved efficiency of analysis, some php and mySQL for the web version, etc..... I get a feeling that ten years from now I'll still be tweaking this program.


Rob Camick
Ranch Hand

Joined: Jun 13, 2009
Posts: 2227
    
    8
Given that displaying a cursor in a (pseudo) non-editable TextArea is part of the requirement, and it is not so easy to do this.


This is what I meant by my earlier suggestion. Maybe I don't understand what you are asking for?



The MouseListener event handler duplicates the activities of a Caret change event handler for mouseclicks only.


Again, I don't understand your requirement, but the user should be able to use the Keyboard or the Mouse, whichever they prefer. Using the arrow keys to position the caret on a character should be valid just like clicking the mouse.
Fred Hamilton
Ranch Hand

Joined: May 13, 2009
Posts: 679
Thanks Rob (Camick) , No, I think you understood my requirement of displaying a cursor in a non-editable TextArea, I just didn't see how your comment about extending DefaultCaret would meet that requirement, and besides, it's a solution that would take time for me to research and implement, and I could not free up that time right now. But I see you have provided some additional info, so I'll try to find time later this week to test it out, and I'll let you know. My problem is, my to-do list is too long. Anyways, the method I did use works, although it is not the most elegant I concede.

My comment about MouseEvent Handler vs CaretEvent Handler was for the following reason...

Given the solution that I did implement, A key Event handler, A Caret Listener only complicated the situation, while it was easy for my KeyEvent handler to get rid of unneeded content in the TextArea, it was not so easy to deal with unwanted caret events. See what I mean? So I got rid of my CaretListener altogether, and the work my CaretEvent handler was doing was divided up between a MouseEvent Handler and a KeyEvent Handler. ergo, no unwanted caret events, only unwanted content, which is much easier ( for me given my current knowledge ) to deal with. My solution would also allow me to implement use of arrow keys for text selection.

Anyways, like I said, I will be looking into your method in the not to distant future, i'll let you know how it goes.

anyways, if you still don't understand my requirements, but you want to, then we can deal with that, just let me know.
Maneesh Godbole
Saloon Keeper

Joined: Jul 26, 2007
Posts: 10535
    
    9

Fred Hamilton wrote:...it is a useful and convenient visual aid, due to the nature of the information in the TextPane and it's relation to what is happening in other parts of the GUI. And popular commercial applications of similar purpose do make use of a blinking cursor in a non-editable field.


In that case I would personally prefer a Highlighter. But then that's my personal preference
Fred Hamilton
Ranch Hand

Joined: May 13, 2009
Posts: 679
Maneesh Godbole wrote:
Fred Hamilton wrote:...it is a useful and convenient visual aid, due to the nature of the information in the TextPane and it's relation to what is happening in other parts of the GUI. And popular commercial applications of similar purpose do make use of a blinking cursor in a non-editable field.


In that case I would personally prefer a Highlighter. But then that's my personal preference


I thought about doing that. There's two main commercial chess database programs out there. One uses a highlighter, one uses a blinking cursor. Guess which one I've been using for the last six or seven years

anyways, when I get around to programming an Options Menu in the desktop version of this program, I'll probably make it an option to choose either blinking cursor or a highlighter.

This is has been a great learning project for me, and there's a few years worth of learning left in it still.

anyways, the latest version has been uploaded to the link in my signature. So you can see the results of the current MouseListener/KeyListener solution.

Rob Camick
Ranch Hand

Joined: Jun 13, 2009
Posts: 2227
    
    8
anyways, the latest version has been uploaded


Cool. I won my first game, do I get a prize?
Maneesh Godbole
Saloon Keeper

Joined: Jul 26, 2007
Posts: 10535
    
    9

Man,
All you chess aficionados always scare me.
I am so dumb even my daughter defeats me at chess
Maneesh Godbole
Saloon Keeper

Joined: Jul 26, 2007
Posts: 10535
    
    9

Fred Hamilton wrote:
anyways, the latest version has been uploaded to the link in my signature.


Are you pulling our legs here Fred?
I tried out your link, made my move and like a schmuck waited for the server to counter move!!!

Are you aware you can have hyperlinks in your signature? (Will save lazy dogs like me the trouble of CtrlC/CtrlV )
Fred Hamilton
Ranch Hand

Joined: May 13, 2009
Posts: 679
Maneesh Godbole wrote:
Fred Hamilton wrote:
anyways, the latest version has been uploaded to the link in my signature.


Are you pulling our legs here Fred?
I tried out your link, made my move and like a schmuck waited for the server to counter move!!!

Are you aware you can have hyperlinks in your signature? (Will save lazy dogs like me the trouble of CtrlC/CtrlV )


Not sure what you mean. In this program, the program will act as a basic chessboard by default, if you want the computer to play you have to tell it to play. If you want to play a complete game as white, make a move as white and click play. If you want the computer to play white, click play right away. There are also tool tips on most of the controls. Select the think checkbox for the strongst level. Anyways, advanced recursive algorithms are not my strong suit, so the program is not particularly strong.

No I didn't know about hyperlinks in the sig, I just typed in the URL. I'll check it out.


p.s. oops. not Play, Start is the button. I should change it.
Fred Hamilton
Ranch Hand

Joined: May 13, 2009
Posts: 679
Maneesh Godbole wrote:
Fred Hamilton wrote:...it is a useful and convenient visual aid, due to the nature of the information in the TextPane and it's relation to what is happening in other parts of the GUI. And popular commercial applications of similar purpose do make use of a blinking cursor in a non-editable field.


In that case I would personally prefer a Highlighter. But then that's my personal preference


hmm, Maneesh I may have to go with your suggestion in the short term after all. I haven't given up yet, but weird things are happening as I try to expand keystroke functionality that as far as I can see are caused by two factors.

1. a keystroke cause a change in content or cursor/caret position and also fires a keyevent and the event handler itself affects content/cursor position.

2. key events are fired before the text area gets updated. It would probably be simpler if the events happened after the TextArea was updated.

I may have to take a second look at CaretEvents. I'm also looking into some solutions that onvolve buffering. Anyways, I'm not really looking for help at this point, just wanted to correct an earlier erroneous impression that my idea solved the problem.

Other solutions in this thread will have to wait till I've has time to research the background material. I promised myself I wouldn't implement anything in my program without at least a basic understanding of the underlying theory. And I don't like to give up on even bad ideas without at least figuring out the problem.
Rob Camick
Ranch Hand

Joined: Jun 13, 2009
Posts: 2227
    
    8
I may have to take a second look at CaretEvents.


Well, I still don't know how your entire code is structured, but from what I understand you want the ability to "undo" and "redo", based on the move the user selects.

So following is something I threw together that may give you ideas. It use a NavigationFilter to control where the Caret can be positionsed. So basically every time the Caret is moved (either by mouse click or the the left/right arrows, the caret is positions at the beginning of the move. Therefore only a singel CaretEvent is fired as the caret position is determined by the filter.

When using the keyboard you would only be able to undo/redo a single move at a time. Using the mouse you can jump to any move you want to undo.

Fred Hamilton
Ranch Hand

Joined: May 13, 2009
Posts: 679
Rob Camick wrote:
I may have to take a second look at CaretEvents.


Well, I still don't know how your entire code is structured, but from what I understand you want the ability to "undo" and "redo", based on the move the user selects.

So following is something I threw together that may give you ideas. It use a NavigationFilter to control where the Caret can be positionsed. So basically every time the Caret is moved (either by mouse click or the the left/right arrows, the caret is positions at the beginning of the move. Therefore only a singel CaretEvent is fired as the caret position is determined by the filter.

When using the keyboard you would only be able to undo/redo a single move at a time. Using the mouse you can jump to any move you want to undo.



Thanks Rob, I think we are more or less on the same track. I actually a few hours today looking over materials on Navigation filters and Document filters, Document listeners, Editor Kits etc. and getting a lot of ideas. A lot of it is quite new to me, and absorbing new materials is not something that comes easy to me. I can see there are a number of things I haven't tried yet that should make my life easier. It's not so much undoing moves and doing real things that I have problems with, it's doing real things while at the same time making the code unbreakable that is a challenge. So it's gonna take me a few days to absorb all the ideas I've picked up, work on some prototypes, apply some brainwaves to what has been shown in this thread, etc.

My actual code is in pretty good shape, reasonably well documented and organized, just limited in terms of the actual java functionality I have employed so far. I'm big in backups, versions, doing a little bit at a time etc, so it is easy for me to backtrack to the point where things are quite solid. So I'll give some thought as to how best to present what I do have to give people a better idea of how the program is put together, and we can take it from there.

Thanks again,
Fred.
Fred Hamilton
Ranch Hand

Joined: May 13, 2009
Posts: 679
OK, I acknowledge that what I have right now doesn't make good use of the tools available to me, but I still want to know why I'm getting the result I am with this stuff, before I tackle some of the suggestions in this thread.

The requirement are:

1. I want to position the caret and redraw the board according to mouse clicks in the output area
2. I want to respond to left and right arrow key to position cursor and redraw boar, but ignore other keystrokes.
3. I want to display the blinking cursor after the last move notation

OK I have two sligtly different versions of the program available.

<links removed - problem solved>

They are identical in every respect except chess1 contains this event handler...

while chess2 contains this event handler...


chess two incorporates the arrow key functionality.

The rest of the relevant code from my GUI class is shown below.

The problem is the behaviour of the left and right arrow keys. they move the game pointers and cursor back and forth two moves, instead of one. It is as if two KeyReleased events are being fired. Notice that keyReleased calls exactly the same method as the left and right JButtions, but the buttons work fine. Other aspects of keyReleased(), such as the handling of unwanted characters, works as expected.

** Update #1: Well, this is unexpected, I just tried on a different computer that is quite a bit faster than mine, and the problem istwice as bad, instead of moving ahead or back two moves, and arrow key moves it ahead or back four moves. Interesting...

** Update#2: OK, multiple KeyReleased events are being fired, damned if I can figure out why, since I only hit the key once. hmmm, this must be a known mistake on my part. google time...

Update #3: Problem solved. Seems I managed to have more than one key listener registered on my textpane. duhhhhhh ( link in signature is updated )




p.s. edited to explain requirements near the beginning
Fred Hamilton
Ranch Hand

Joined: May 13, 2009
Posts: 679
Anyways, since I got such great support in this thread, I wanted to show what I eventually came up with.

As you may recall, the primary goal was to have the application respond to some changes in caret position but not all. It should respond to changes due to mouse clicks and arrow keys, yet disable cursor movement for all but selected keys. And also display a blinking caret (insertion point) while making the TextPane uneditable I accomplished it by using a MouseListener and a KeyListener, no Caret Listener, with the following KeyEvent handlers...



There are still one or two drawbacks from an esthetic perspective, and I don't yet have have a technique that deals with the user selcting blocks of text, which has no purpose here, but at least the user (me) can't mess things up with unwanted keystrokes.

There were some promising suggestions in this thread that probably are better than what I have, but I need to work on the underlying concepts before I try to implement these suggestions. At this point I can only make use of suggestions that involve one or more of KeyListeners, MouseListeners, or CaretListeners on the JTextPane. the other stuff in this thread involving Documents, navigation filters, modifying DefaultCaret, etc. will have to wait until I improve my knowledge of the background material. Again keep in mind that the purpose is to learn different programming techniques, not just to build the best possible mousetrap.

Anyways, for those interested the results are available at the link in my sig. You can move both sides of the board yourself to simulate a game, and you can backtrack and make different moves and you can see how the TextPane records these variations. Then you can use arrow keys, mouse clicks, and buttons to navigate teh text pane, the end purpose of recognizing the caret changes is to trigger changes in the psoition displayed on the board.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: setEditable and blinking cursor