I have a pane that contains image content which changes during scrolling. The content is properly updated via a scrollwheel event because I implemented a wheel listener which repaints the image before setting the new scroll value.
However, when the user drags the scrollbar handle with the mouse, the image content was not being updated during the manual drag-scroll. So I implemented a timer which grabs the current scroll value and repaints the content given the new scroll position.
This solution however (despite 10 millisecond adjustments) results in a jumpy scroll experience. The image moves (without the necessary image adjustments) and then gets corrected after-the-fact every 10 milliseconds.
I had originally tried an adjustmentlistener, but it only gets the event after the handle is released. How can I live-update the pane content during a jscrollbar handle drag BEFORE the scrollbar machinery starts to simply move my content as if it was a static image? Can I somehow give the scrollbar machinery a clue that content has changed or something every time it tries to redraw the content? Or can I disable the scrollbar's ability to move the image and just rely on my timer to do it?
I would recommend that you add a ChangeListener to the JScrollBar's model, a BounderedRangeModel, and then based on the value of the model as well as its maximum and minimum, change your image. If you're swapping images, the easiest way to do this is by swapping a JLabel's ImageIcon.
Related
I have a JScrollPane with JPanel on it. I have also many different components on JPanel (for example Labels, JTextFields, JTextAreas). These components are added programmatically (at runtime, on the user request).
JPanel uses SpringLayout. The program calculates preferred size of JPanel after adding components, because scrolling doesn't function properly without calculating. Adding components and calculating preferred size are part of my prepareGui() method.
The data displayed on components are periodically refreshed (in my refreshData() method, which is invoked by listener).
My problem: after refreshing, scroll bar always sets to fixed position (I don't know why). I want the scroll bar to stay in old position after refreshing.
I tried to find a place, where the scroll bar moves. I checked some values at the start and at the end of refreshData() method, but they was the same (they didn't change inside of refreshData()):
scrollPane.getVisibleRect().getX()
scrollPane.getVisibleRect().getY()
scrollPane.getVisibleRect().getWidth()
scrollPane.getVisibleRect().getHeight()
panel.getVisibleRect().getX()
panel.getVisibleRect().getY()
panel.getVisibleRect().getWidth()
panel.getVisibleRect().getHeight()
scrollPane.getHorizontalScrollBar().getX()
scrollPane.getHorizontalScrollBar().getY()
scrollPane.getHorizontalScrollBar().getWidth()
scrollPane.getHorizontalScrollBar().getHeight()
scrollPane.getHorizontalScrollBar().getValue()
scrollPane.getVerticalScrollBar().getX()
scrollPane.getVerticalScrollBar().getY()
scrollPane.getVerticalScrollBar().getWidth()
scrollPane.getVerticalScrollBar().getHeight()
scrollPane.getVerticalScrollBar().getValue()
Changing of layout manager didn't take effect.
I noticed one thing (I don't know if it has any meaning). When I set only preferred size (in prepareGui()), the scrollbar moves to the end. When I set also size, the scrollbar moves to strange, fixed position.
How can I prevent this?
The scroll bar should keep it's current position.
I finally found the answer here: https://stackoverflow.com/a/5230477/5694159 (thanks to Johan M) in the topic about JTextArea instead of JPanel.
When the refreshData() is calling in separate thread it works good.
I hope this question and answer will help someone.
In my code, the UI has the following components:
JSplitPane:
pane1: JTable
pane2: JPanel with some texutal information.
I am listening to the row selection events on the table and then setting the divider location of the splitpane appropriately so that the textual information is visible for some row and is hidden for some other rows.
However, one problem with this approach is the switching to the divider location is very abrupt which gives very less time to the user to understand what happened.
Could you please let me know how to add in some animation so that the divider location switching happens slowly and gives user an idea that textual information is shown for a particular row selection and hidden for some other row selection.
I tried changing the divider location slowly from one value to the next on the AWT thread, but then the UI seemed to not respond properly.
Use a javax.swing.Timer to control the animation, as shown in this example. Note that the animation remains smooth as the frame is resized.
i'm looking for this effect, but PulpCore doen't works with swing. Do you know what library use, or how to make a TileMap? Also, I'd like to move forever in it.
Thanks.
I'm guessing you don't want to use an actual world-map implementation like JXMapViewer...
The basic functionality appears to be: click on some coordinates, and that point becomes centered in the viewport. One fairly simple way to do this is to have the component(s) that you want to view all contained within a JPanel and have that panel inside a JScrollPane with its scrollbars turned off (setHorizontalScrollbarPolicy(HORIZONTAL_SCROLLBAR_NEVER) and so on). Then, set up a click or action listener for your elements that calculates the new center point, what the new viewport rectangle coordinates will be, and use scrollRectToVisible on the panel to shift the view. For animation, you can use a Swing Timer to set up a series of incremental scrolls in the required direction until you reach the target.
I've created an applet which has one large panel to display data surrounded by several controls (buttons, textfields, etc.). The large panel contains several layers of labels which I render myself.
The controls all have tooltips associated with them, and some of these tooltips overlap the main panel. When they disappear, they leave a hole in the main panel image until the main panel is repainted.
Now mind you, this does not always happen. It only occurs when the cursor is in a certain range. If you get far enough to either the left or right (no difference noted for changes along the Y axis), the holes are painted over when the tooltip disappears.
I'm not well-versed on how tooltips and repainting are supposed to work, and if this is a sign that there's something dreadfully wrong with my program, but if I can just call repaint on the main panel whenever the tooltip disappears, I should be fine. Is there something I can override in tooltip to make this happen?
I'm using Swing
Thanks.
To answer your question (after you found a solution by the comments): Swing has some quite elaborate repaint management built in. When a tooltip disappears, the rectangle below it is repainted.
Now, which components have to be repainted? All those who overlap with the given rectangle, and are not themselves hidden (in the region in question) by other components - but only opaque components count here. (This is the whole reason we need the opaque property on JComponent - to optimize repainting.)
Your label declared itself being opaque, but did not really paint its whole area on a paintComponent, and such the region of the tooltip which should have been covered by the label stayed unpainted.
Declaring your label to be partly transparent caused also the concerning region of the component behind it to be repainted.
In windows, Java, etc, the scroll pane scrolls the widgets inside. What I'm wondering is, how exactly does it do its scrolling? Does it change the location of each nested widget, or does it have a content widget that it moves around? Or is it something else? Also, when both scrollbars are present, how does it mask that little square at the bottom right? That square is sometimes used to resize. Is it a separate nested widget?
Thanks
I think it just changes the location of the widget, button, or thing-a-ma-bober.
But my second guess would be it just draws the components "outside" of the scroll pane without being seen and when you scroll it just redraws dynamically.