I'm working on a program that includes a scrollbar.
In the program I got a scrollable field of 500px and I want the scrollbar to scroll per 50px.
So I get 10 pages.
I dont want to be able to show 50% of a page I only want to be able to show 1 page at a time.
So how do I change the scroll dimensions?
Or is there a better way to accomplish this?
Greets,
And thanks in advance
Bram
You can make the scrollable field implement the Scrollable interface, which declares two methods the scroll field will use to decide how far it scrolls, getScrollableUnitIncrement (scroll-wheel, clicking the scroll arrow) and getScrollableBlockIncrement (clicking the scrollbar's track).
If you're really only ever going to want it to be 50, you can use
jScrollPane.getVerticalScrollBar().setUnitIncrement(50);
jScrollPane.getVerticalScrollBar().setBlockIncrement(50);
However, if the user then drags the scrollbar until half a page is shown (I don't think this behavior can be easily changed), scrolling will still jump 50 pixels and show half of the next page... If you implement Scrollable, you can base the amount scrolled on what is currently visible.
Try this with you JScrollPane
scrollPane.getVerticalScrollBar().setUnitIncrement(50);
This helps when you scroll with JScrollPane buttons up/down but you be able show a half of page by moving knob with mouse.
As alternative I can propose to watch knob position with AdjustmentListener and shift scrollPane value manually.
scrollPane.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener()
{
public void adjustmentValueChanged(AdjustmentEvent e)
{
scrollPane.getVerticalScrollBar().setValue(e.getValue() / 50 * 50);
}
});
But I think it isn't good idea. May be somebody will propose better way.
Related
I have a series of column labels that scrolls independently from the data that is displayed in a matrix below. I can make the whole scrollbar transparent except on hover. The labels are right up against the data, which I like, however, upon hover, unless I shift the vertical scroll (which I'd rather not do), the scrollbar obscures the beginning of all the labels.
I would like to set the background of the scrollbar as transparent so that only the "grabber" (or whatever it's called) is the only thing that is drawn. (It will obscure the beginning of the labels it is over, but would be a lot less so.)
Is there any way to do that? Here is what I tried:
Color bg = new Color(255,255,255,0);
colLabelScroll.setBackground(bg);
This does not seem to make the background of the scrollbar transparent.
What I'm shooting for is like how the iPhone's scrollbar grabber hovers over info in some apps. Is that even possible with JScrollBars?
Transparent JScrollBar can do it, but consider this: if column labels are related to the data and you can scroll them independently, beginner users may not understand what is going on and associate column labels with whatever is visually aligned beneath it. Either you will need some sort of visual indicator that makes it clear that the labels are disconnected from the data, or you should change the way labels are scrolled that never leaves them statically in 1 place.
Here's how I ended up making the relationship between the labels and the data clearer:
Instead of allowing the user to independently and intentionally scroll the labels, I decided to control the label scroll position via mouse hover. This eliminates the need for the obtrusive scrollbar.
I created a scroll-bar-like indicator that shows the portion of the data the labels represent.
I highlighted the currently hovered label that corresponds to the data below it, i.e. the only label that is ever correctly aligned with the data is the one that is under (or directly above) the cursor.
When the mouse is not hovered over (or dragging from) the column labels, do not display any labels. This helps prevent invalid label/data associations by the user.
A few nuanced notes: Implementing your own scrollbar-like indicator is somewhat involved, especially if your labels are painted and then rotated, because the paint position of 0 is at the bottom of the pane, yet the vertical scroll position of the pane is at the top. You will have to track the vertical scroll position to be able to recover it again when the cursor returns since you are blanking the labels on mouse out.
When developing a plugin for IntelliJ, I accomplished it with:
scrollPane.getVerticalScrollBar().setUI(ButtonlessScrollBarUI.createTransparent());
It takes advantage of the the:
ButtonlessScrollBarUI.createTransparent()
method, which is an IntelliJ specific method. However, if you can find a ScrollBarUI which has a transparent background, you can use the same trick.
Since I got a bit lost myself at first after reading #hepcat72's answer I'm posting a little explanation about the BasicScrollBarUI class:
JScrollBar scrollbar = scrollPaneConversation.getVerticalScrollBar();
scrollbar.setUI(new BasicScrollBarUI(){
// This function returns a JButton to be used as the increase button
// You could create your own customized button or return an empty(invisible) button
#Override
protected JButton createIncreaseButton(int orientation){
}
// Same as above for decrease button
#Override
protected JButton createDecreaseButton(int orientation){
}
// This function paints the "track" a.k.a the background of the scrollbar
// If you want no background just return from this function without doing anything
// If you want a custom background you can paint the 'Graphics g' object as you like
#Override
protected void paintTrack(Graphics g, JComponent c, Rectangle trackBounds)
{
}
// This function paints the "thumb" a.k.a the thingy that you drag up and down
// You can override this function to paint it as you like
#Override
protected void paintThumb(Graphics g, JComponent c, Rectangle thumbBounds)
{
}
});
Refer to the Transparent JScrollBar link posted by #hepcat72 for hints about what to do exactly in these functions.
The album view in iTunes has a slick effect where the album title and cover art stay in view at all times. If you slide down the screen they stay pinned to the top of the screen until they bump into the next album, then they slide away.
Notice how the top album is still fully visible even though the user has scrolled down a ways.
What is this control or effect called? I'm coming up with blanks trying to Google for it.
How can I do this in JavaFX? I want to mimic this in my Java-based GUI. Can TableView do this, or maybe some third-party control?
The easiest way to do this is with a ScrollPane. Inside your ScrollPane you define your rows and their layouts (probably each row is an HBox containing an ImageView and a TableView which is set to the height of the ImageView). Then, the TableViews inside your ScrollPane need to let the ScrollPane override their scrolling - that is, their onScroll bubbles up to the ScrollPane.
Then you override the onScroll behavior for your ScrollPane. The algorithm for the scrolling could go like this:
There are two modes.
1) Scrolling IN an album scrolls the TableView in that row. If the scrolling goes beyond the boundaries of the TableView's scrollHeight (the range between 0 and scrollHeight), then the mode switches to scrolling TO an album.
2) Scrolling TO an album scrolls the ScrollPane an amount up to the height of the current row. Scrolling an amount greater than the current row's height moves to the next album and switches the mode back to Scrolling IN that album.
3) Edge Cases: Scrolling within the ScrollPane beyond the boundaries of the ScrollPane's scrollHeight (the range between 0 and scrollHeight) immediately moves to the next album and switches the mode back to Scrolling IN that album.
I'd give a code example, but I've never actually seen anybody try to do this. I just know you CAN do it.
I would recommend you to take a look to the SpreadsheetView in ControlsFX
The SpreadsheetView allow you to fix at the top of the screen any number of line. So you would have the first part of your behavior.
Regarding the fact of bumping into another, it would be more difficult but not impossible with the SpreadsheetView.
Anyway, if you want to implement that behavior in the TableView, you will find very useful tricks in the SpreadsheetView code.
This is how a section title acts as default in a UITableView.
https://developer.apple.com/Library/ios/documentation/UIKit/Reference/UITableView_Class/index.html
This should help you on how to create and use UITableView
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.
I am Working with Swing in java and I'm making a little tool to compare 2 Files.
The Comparing works, the differences are marked in Red.
So I tough that I could make a kind of Bar next to the ScrollBar to show where I have to Scroll to find de differences in my text. Something like in Eclipse to show where are Errors, Warnings and TODOs
Another possibility coulb be to put the marks into the ScrollBar.
Is that Possible and if Yes, how can I code this? Thank you for your help
Place your scroll pane in a JPanel with BorderLayout. Add one more JPanel's extension to show all the marks and place it to the east (or west). Place the marks on the panel and add a MouseListener to process clicks and scroll to desired positions.
Or you can use custom row/column header. Like this
http://docs.oracle.com/javase/tutorial/uiswing/components/scrollpane.html
Been developing a game for a while, and currently re working the GUI, or at least trying to. Had the massive problem of not being able to resize the frame (without issues), as I didn't understand layout managers very well. A few projects later, and time to come back and do some more on the game, and I hit a problem...
The basic layout of the main frame is, mainPane, containing one gameScrollPane and one controlPanel. The scroll pane is a scroll pane, and the control panel a normal panel. The scroll pane contains the main game panel.
As I wanted the scroll pane to take up most of the screen, with the control panel taking up a small lower area, much the same as many Sim like games, so chose the Border layout for the mainPane. I added the scroll pane and set the constraints CENTER and the control panel added and constriants SOUTH. This didn't show the scroll pane, so I played around trying different constraints, and it seems that only when I set the scroll pane constraint to North, does it display at all.
To demonstrate this, I have created a quick video...
http://screenjel.ly/q5RjczwZjH8
As you can see, when I change the value of NORTH to CENTER and re run, it's like its not there!
Bonus points for anyone who can see a clear second problem which I may start another question for after this issue is solved!
I thank you for your time to read this.
Thanks in advance for any ideas or thoughts :)
Rel
If you'd posted some code to start with then you might have gotten a really quick answer. Luckily, you posted a link in the comments to the other response.
The setContentPane() stuff is weird, especially after doing some things to it that will then get wiped out. However, that's not your problem.
The issue is that you are adding levelMaker and personMover right to mainPane without any constraints. These will then be blowing away anything you set for CENTER... in this case the previously set gameScrollPane.
That's why you see it for NORTH and not for CENTER.
I can't get the video to show. It's been buffering for ages.
My guess would be that the scrollpane is in fact filling the center; it's just your game panel that's not being shown.
Your game panel needs to return reasonable values for getPreferredSize().
Update
Another thing you may want to do is have your game panel implement the Scrollable interface. You can then override getScrollableTracksViewportWidth and ...height to return true so your panel will be forced to the scrollpane's dimensions.