0

I use a simple JScrollbar for my app for controlling the visible part of a drawing in a JPanel. Every time I move the view port I use the setValue method of the scroll-bar, and every time I drag the scroll-bar I move the view port.

This is the basic code:

public void adjustmentValueChanged(AdjustmentEvent event) {
    JScrollBar scrollbar = ((JScrollBar) event.getSource());
       if (scrollbar.getValueIsAdjusting()) {
            _panel.moveViewport(scrollbar.getValue(), 0);
       }
}

And when I programmatically change the view port I use the method moveViewport

 public void moveViewport(int x, int y) {
       /* change the viewport */
       _scrollbar.setValue(x)
 }

All works fine. I use getValueIsAdjusting to differentiate when the value was changed from the setValue and the drag of the knob.

My problem is when I try to use the unitIncrement buttons. When I press a button, the event is the same as when I call scrollbar.setValue. So if I change the if (event.getValueIsAdjusting) to accept the click, it will accept the setValue and it starts a recursion.

What is the design pattern in this case? Is the only answer to extend scroll-bars as in MouseListener for JScrollBar arrow buttons?

Please, do not tell me to use JScrollPane. I can not use it for other reasons. But I think that everything a scroll pane can do I could do with a JScrollBar.

EDIT: I think I fixed it... but I do not understand how!!! I used removed the getIsValueIsAdjusting and used the SwingUtilities.invokeLater (thanks to this question) and now I can press the buttons without recursion. So my new question is "why it works?"

Community
  • 1
  • 1
Alejandro Vera
  • 377
  • 2
  • 12
  • *"..`JScrollPane`. I can not use it for other reasons."* What other reasons? – Andrew Thompson Jul 05 '14 at 04:52
  • Becouse If i understand well, to use the jscrollpane you must use the setPreferredSize. But my drawing can be infinite in every dimension and very intensive in operations. I manage my viewport to only draw the necesary parts of the drawing. – Alejandro Vera Jul 05 '14 at 05:00
  • 1
    Have you implemented the `Scrollable` interface, as suggested [here](http://stackoverflow.com/a/14575081/230513)? – trashgod Jul 05 '14 at 10:51
  • `to use the jscrollpane you must use the setPreferredSize.` no you should never use setPreferredSize(). It is the job of the component to override the getPreferredSize() method to return the size of the component. In order for the scrollbar to work you also need to use some arbitrary large value so it is no different then returning are large value in the getPreferredSize() method. `and very intensive in operations` that has nothing to do with a scrollpane. The scrollpane will also only paint what is in the viewport. – camickr Jul 05 '14 at 14:12
  • Yes. I understand it now... But i every component in my drawing requires ablosof work. I do not want to calculate it if it is not in the view port. Can i know what is going to be drawn to only calculate that? – Alejandro Vera Jul 05 '14 at 16:45
  • also, my world has negative coordinates as well as positive. You can change the jpanel to be arbitarialy big, but I would need to translate all coordinates in the panel to coordinates in my world. It is less complicated to use jscrollbars. I experimented with Scrolleable (as @trashgod said) and discarted it. – Alejandro Vera Jul 07 '14 at 04:29
  • 1
    Also consider the flyweight pattern, mentioned [here](http://stackoverflow.com/a/24488837/230513). – trashgod Jul 07 '14 at 12:45
  • Thanks @trashgod very useful!!! I use it already.. but i didn't know!!! :D it is great to view that my idea is a design patter.... But so far, nobody has answered my question about understanding better the jscrollbar behavior.. – Alejandro Vera Jul 07 '14 at 14:32

0 Answers0