I have a horizontal scrollbar that controls a large panel (with a very large width, and a very small height, thus an horizontal panel).
I want the start of the scrollbar (when the knob is at max left) NOT to start at the beggining of the panel it is scrolling, but rather in a specific place that I dictate. The same for the end of the scrollbar (when the knob is at max right).
I find that the scrollbar is always bound to the panel it is scrolling, and I can't figure out how to change its behaviour.
EDIT:
As an example, picture a normal web-page: when at the top of the page, the scrollbar knob is also at the top. When at the bottom, the scrollbar knob is at the bottom. I want to define new limits for the content, such that when the scrollbar knob reaches the top or bottom, the page is showing the limit I defined, instead of the real top and bottom.
As shown in How to Use Scroll Panes, you can use the component's scrollRectToVisible() method to scroll to an arbitrary Rectangle. There's an example here.
Addendum: As a Container, a JPanel is fairly fungible even if it has considerable nested content. One reliable way to swap content at a given level is via CardLayout, shown here, here and here.
I solved the problem by using the JScrollbar method setValues(), which allows me to set at the same time the maximum, minimum, value and extent of the scrollbar. By setting the maximum and minimum to the values I want, the scrollbar behaves as I wanted/expected.
The problem was that I was only setting maximum and minimum values (setMaximum, setMinimum), and since there is a strict policy at the model that minimum <= value <= value+extent <= maximum, that estrategy did not work.
Would it be possible to keep the large panel as a backing store and copy the region of interest into a panel which is actually realized in the scrollpane. This way you don't have to fight the behavior of the scrollpane.
Related
My goal is to show a view and display beyond the end of the scrollbar track, without increasing the height of said scrollbar track.
My current scrollbar implementation (the default scrollbar implementation) is set up such that the height of the view is kept within the bounds of the scrollbar track, which leaves this nasty cutoff and wasted space (basically anything beyond the top of the track gets cut off):
The goal is to have nothing look cut off like this at all and still scroll fully to the top and bottom, regardless of the height of the scrollbar's track. Here's an example I've seen:
Notice how there's nothing cut off when the contents of the view go beyond the top of the scrollbar track? That's what I'm aiming for; I want it so that regardless of the height of the scrollbar track, it will still display the view to the maximum upper and lower bounds of the screen I'm on, with the scrollbar still functioning normally. I have looked into the various views and how they implement their scrollbars, and I don't know if it's my lack of experience (Jr. Dev) or if I'm not looking in the right place, but I can't figure out a custom implementation for the scrollbar that would work the way I want it to. Any and all help would be vastly appreciated.
In the TextArea widget of Java FX 2.2, the method getScrollLeft is described in the documentation as returning
The number of pixels by which the content is horizontally scrolled.
More precisely, it accesses the value of the property ScrollLeft which has the above description.
When I slide either the horizontal or vertical scrollbar, this variable is adjusted, as expected. However when I press "backspace" on a line that is longer than the screen width such that the scroll amount decreases, or at the first character of a row, the property is not adjusted even though the scroll position changes.
A hacky way to fix this is to access the scrollbar directly, get how much of it is being scrolled, and calculate the appropriate value based on that information. I'd prefer not to do this.
Is there an accepted way to solve this problem, or am I misusing the scrollbar information?
I have a JScrollPane scroller that I would like to make move a specified amount of pixels either vertically or horizontally.
Specifically, I'm making a tile-based game in which the tile panel is wrapped in a JScrollPane that has its scrollbars hidden from the user. I need the code to adjust the scrolling such that every time I call my movePlayer() method in the tile panel, the scrollbar(s) automatically move over by the length of one tile.
Most of my searches so far have only yielded results for scrollBy in javascript.
Is there a way to programmatically force the bar to scroll in Java?
Take a look at JViewport#getViewRect, JViewport#getViewPosition, and JViewport#setViewPosition
These will allow to adjust the JScrollPane's viewport position.
You can also take a look JComponent#scrollRectToVisible which allows to ask that a given area of a component be made visible if it is within a scrollpane/viewport
You can take a look at Moving a view port over a larger image; JLablel+JScrollPane for example
I'm using JXMultiSplitPane (from SwingX 1.6.2) to implement a three-pane horizontal interface. In the center pane is a JTabbedPane with two tabs: one with a JTextArea (in a JScrollPane, of course) used for entering Markdown code and the other a JEditorPane (again, in a scroll pane) for displaying a rendered HTML preview. When the user switches to the preview pane, the text in the editor is processed and displayed in the preview pane.
My problem is that if I enter text in the editor with long lines, and then switch to the preview, the center pane will expand. Sometimes it's just by a little bit, other times it'll take up more room than is actually on the screen. But if I move one of the resize handles manually, everything will snap back in place.
I've found only two ways to deal with this before it happens:
Manually resize one of the panes before entering any text.
Give the center pane a weight of 1 in the MultiSplitLayout model.
I can't use the second one since it will expand the center pane to take up almost the whole window by default.
Is there a way to fix this?
Update
After a little more testing, even technique (2) doesn't keep the size constant; switching between the two tabs changes the size of the center pane slightly.
I now believe that the problem is partly with the tabbed pane. The JTextArea and the JEditorPane do not have the same size and that JTabbedPane is resizing when I switch between them (since I'm resetting the JEditorPane text every time. This wouldn't be a problem except that JXMultiSplitPane will keep automatically resizing the center pane until the user forces a specific size by resizing manually.
So I should be able to fix the issue by making the size of the JTabbedPane fixed, but still able to be resized by the handle bars. Any tips on doing that?
The MultiSplitLayout is .. a LayoutManager, so you have to understand how it works (me too, not overly familiar with it myself :-)
The basic layout happens according to the component's prefSize, the weights are for distributing excess/missing space relative to the pref. By default, the dividers are "floating", that is they are positioned between the components as layouted by the basic mechanism. The moment a user touches a divider, dividers are "not-floating", comp sized to fit in-between the dividers. That's the reason for you not seeing the size-greed after moving the divider once. So one ways out is to
setup the JXMultiSplitPane as usual, add the components and realize the frame
fix the dividers after the manager has done its initial layout
String layout = "(ROW " +
"(LEAF name=selector weight=0.15)" +
"(LEAF name=center weight=0.7)" +
"(LEAF name=list weight=0.15)" +
")";
JXMultiSpitPane pane = new JXMulitSplitPane((MultiSplitLayout.parseModel(layout))
// add components and realize the frame
...
pane.getMultiSplitLayout().setFloatingDividers(false);
Alternatively, give more weight to the weights - force the layoutManager to use them for the layout itself (instead of only for the distribution of excess/missing space). A side-effect is that the prefSize of the comps might be set (by the layout, which is a no-no-never, but who's perfect ;-)
pane.getMulitSplitLayout().setLayoutByWeights(true);
Not sure which way I would prefer or if/how that could be made easier in the multisplit ..
I created a JFrame initialized with a BorderLayout and a JScrollPane as its CENTER element.
The scroll pane is set with VERTICAL_SCROLLBAR_ALWAYS and HORIZONTAL_SCROLLBAR_NEVER policies. The intent of my frame is to have a controlled width, while the height should grow/shrink as data is added/removed.
Inside my scroll pane, I added a simple JPanel (lets call it the content panel) which is initialized with a FlowLayout (and LEADING policy).
In order to test this, I simply populate my content panel with 20 JLabel("Item " + n) components where n is the loop counter.
I would expect to see my labels shown on a single row if the frame is large enough and the labels wrap to other lines when I shrink the width. But instead, there is only a single line displayed with no wrapping... ever.
Does anyone know why the flow layout does not wrap when a scroll pane is involved?
If I remove the scroll pane all together and put the content panel directly in the frame, the desired wrapping effect occurs, but if the frame height is shrunk smaller than the content panel height it just disappears.
The idea is that I want my labels to be wrapped when necessary but also always be visible if it means having to scroll up/down.
Any suggestions on how to fix this?
Thanks.
Wrap Layout gives an explanation and a solution.
If you work with the designer, you have to set the prefferedSize property to null (delete what is set) then set the preferred size by clicking the triple dots [...] button next to the prefferedsize property name and put your preferred value.
I encountered the same problem and it works for me.