• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

can't enable or disable events

 
Gary Frick
Greenhorn
Posts: 28
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I need to enable and disable events from firing in a JList where I am dynamically changing the contents. I want to disable events when changing list contents, but enable them to get user selection. If I don't disable them, then the action of dynamically changing contents fires a 'value changed' event and so the 'getSelectedIndex' is set inappropriately.
OpsTool.java [451:1] enableEvents(long) has protected access in java.awt.Component
HostList.enableEvents(AWTEvent.ITEM_EVENT_MASK);
^
OpsTool.java [467:1] disableEvents(long) has protected access in java.awt.Component
HostList.disableEvents(AWTEvent.ITEM_EVENT_MASK);
 
Cindy Glass
"The Hood"
Sheriff
Posts: 8521
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Remove the Listener.
Change the value.
Put the Listener back.
 
Malcolm Storey
Ranch Hand
Posts: 40
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't think temporarily removing the Listener works.

You remove the Listener, then make the change. The change causes an Event to be put in the Event Queue. You complete your change, reinstall the Listener, and return. Now the Event Multicaster takes over and sends the Event to your Listener - At least this seemed to be what happened when I tried it with a ComponentListener that I was using to monitor the size of a JFrame.


My (not very nice) solution is to save the start time:



and then ignore events until isCascading() returns false




Sorry to take 10 years to add this comment!!!
 
Darryl Burke
Bartender
Posts: 5132
11
Java Netbeans IDE Opera
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Your code may not be correctly respecting Swing's single threaded rule. Even if it does, it's sometimes necessary to wrap user customizations in a SwingUtilities#invokeLater(...) to achieve the desired event notification sequence.

I much prefer the idiom of maintaining a boolean flag the value of which is tested in event handling code. That approach is immune to concurrency issues.
 
Malcolm Storey
Ranch Hand
Posts: 40
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for your comments.

Sorry, I wasn't clear. I'm not removing/adding the Listener, just making the Listener ignore callbacks. The set/isCascading calls are all from the componentResized call, so are only called during callbacks which are on the Swing thread. I don't think that violates the single threaded rule, but I've now inserted to check.

This solution doesn't rely on event timing - just a sledge-hammer 100 millisecond dead time.

(I'm not particularly defending it, just trying to learn)

Two things I don't like about the above solution: firstly the frequent calls to the real time clock, and secondly the arbitrary 100 milliseconds.

It would be cleaner if I could remove the listener, and then put a SwingWorker on the end of the Event Queue and use that to re-add the Listener - is InvokeLater guaranteed to be invoked after all pre-existing Events? Have just looked it up. I see that this is the case.

Many thanks

 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic