• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Jittery Pan/Scrolling

 
Greenhorn
Posts: 29
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Below is a bit of code that loads an image, and is supposed to allow the user to pan the image (which is in a JScrollPane) by clicking and dragging the mouse. It sort of works, but there are (at least) two problems. First, the image is jittery. It moves around, but it's jumpy. The cause of that problem is a total mystery to me. The second problem is that the distance moved by the mouse is not equal to the amount by which the image is moved. My guess is that the second problem is due to a mismatch between the logical coordinate system and the pixel coordinate system, but the two should be the same in this default case. I've been tinkering with this for a while and can't find any similar examples on the net. Any ideas?


 
Bartender
Posts: 5167
11
Netbeans IDE Opera Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Comments:
-- You don't need an extended JPanel to just draw one image. Use a JLabel with the ImageIcon instead. Unless of course you are also adding components to the panel and have omitted that part for brevity.
-- If you do have a need for custom painting, it is pointless to construct an ImageIcon just to retrieve its Image. Read the Image by ImageIO instead. Unless you have to deal with an animated GIF, in which case you would use Toolkit and MediaTracker/ImageObserver.
-- Explicitly assigning null to fields is redundant. The default value is null for all reference types.
-- Why the empty statements in the empty methods? They just add clutter.

The solution I posted at JLabel pan image doesn't show any jitter. It's a SSCCE and loads an image available on the web, so you can run it without changes and see for yourself.

the distance moved by the mouse is not equal to the amount by which the image is moved. My guess is that the second problem is due to a mismatch between the logical coordinate system and the pixel coordinate system


Nope.
 
Randall Fairman
Greenhorn
Posts: 29
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

I should have been more clear. I don't care about loading images; that was just something simple to exercise what I do care about: the way that scroll bars work and how they interact with the origin of the drawing. I should have said g.drawRect() for some arbitrary rectangle instead of messing with images. Let me play around with your suggestion and see if I can bring the intent over as a solution to my problem.

Thanks
 
Randall Fairman
Greenhorn
Posts: 29
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Darryl, I took your basic idea and reimplemented my original test class, without involving images at all. Instead, the program just draws a rectangle. I also got rid of the invokeLater() since I don't see why it's necessary here. Am I missing something?

 
Randall Fairman
Greenhorn
Posts: 29
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I should have made it clear: the program that I just posted works perfectly, but I wonder why you bother with the invokeLater().
 
Sheriff
Posts: 22783
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Randall Fairman wrote:I also got rid of the invokeLater() since I don't see why it's necessary here. Am I missing something?


All user interface interaction, including the creation, should be done on the Event Dispatcher Thread (EDT). EventQueue.invokeLater / SwingUtilities.invokeLater (they do the same) will take the Runnable and execute its run() method on this EDT.
 
Randall Fairman
Greenhorn
Posts: 29
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Yes, I understand that about invokeLater(). Below is the mouseDragged() from your original example. The code that's inside invokeLater() doesn't do anything to the UI. Indeed, it doesn't seem to do anything at all. Your original program runs just fine if you remove the entire invokeLater() block. The values of pressed and visiRect, which are the only two things that are modified are the same before and after that code is executed. You must have had some reason to put it there?

 
Darryl Burke
Bartender
Posts: 5167
11
Netbeans IDE Opera Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You're correct. That code was left over from a more advanced DragScrollHandler that included a Timer to create "inertia" of scrolling after the mouse button was released. I've made corrections n the thread linked.

@Rob: The code is already on the EDT, being in an event listener method.

edit Scratch that first. Try continuing to drag when the scrolled component has already reached its limit, then without releasing the mouse button drag back slowly. Try it with and without the code in the invokeLater.

Calling scrollRectToVisible doesn't always change the visibleRect.
 
Randall Fairman
Greenhorn
Posts: 29
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
OK, and thanks for the example.
 
Darryl Burke
Bartender
Posts: 5167
11
Netbeans IDE Opera Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Please see edit.
 
Randall Fairman
Greenhorn
Posts: 29
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You're right. Using invokeLater() is one way to fix the problem, or my version of mouseDragged(), in DrawPanel3, could be modified slightly to read.



This does act slightly differently than your version since the point of the original mouse click remains the "reference point" for the pan, even after you attempt to pan beyond the edge of the image. If that behavior is undesired, then the value of pressed could be modified too when visiRect goes beyond it's natural bounds.
 
Rob Spoor
Sheriff
Posts: 22783
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Randall Fairman wrote:The code that's inside invokeLater() doesn't do anything to the UI.


It does interact with the UI - it queries the component. But since the invokeLater is called from the EDT the only reason to do this is to run this code later. Sometimes it's required, for instance when calling requestFocus on a component.
reply
    Bookmark Topic Watch Topic
  • New Topic