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
Related
I am designing a online marketing page on GUI(user interface). I have added a scroll pane in my main JFrame. The scroll pane starts from 'vertical position = 20' and so does the scroll bar during run time. I want the scroll bar to start from 'vertical position = 0' instead of 20, with the scroll pane still remaining at 'verticle position = 20'
I've tried changing the maximum and minimum size in the properties, but it doesn't work.
A simple example would help in understanding your issue. In the meantime, try to use the following method in JComponent. This works with the component's viewport ancestor, if it has one, and moves the viewport so the given rectangle area is visible or at least its origin. In your case, you could add the component to view to the scrollPane and then call component.scrollRectToVisible(startRect) to ensure the starting position is correct.
public void scrollRectToVisible(Rectangle rect)
I just recently started using Swing to create GUIs for programs, and it's been pretty fun to mess around with so far. However, I'm having an issue with a JPanel with the layout set to gridLayout. Right now it looks like this:
The grid on the right is a JPanel set to a GridLayout, with each cell being a bordered JLabel. The options on the left are also inside a JPanel, and the left JPanel and right JPanel are nested in a GridBagLayout set on a JFrame.
Essentially, my problem is that I want to "scale" the grid on the right so that each cell is a certain height and width. The grid itself will have a variable number of rows and columns, which are set when the program first starts up. Eventually, I plan to have the right JPanel in a JScrollPane (if that's how that works...), so I'm not really concerned about whether or not all of the grid shows up onScreen.
I tried setting the fill value for the gridLayout to "BOTH" and it gave me the following result:
This is closer to my intention, but I wanted the actual ImageIcon in the JLabels to fill the entire JLabel. Additionally, I would want the JLabels to be the same height and width. However, I don't know exactly how to do that. I've been messing around with it for a while now, and I'm not sure if I'm just too much of a noob with Swing, or if I'm missing something in the documentation.
In the end, I'd like the grid cells to be a fixed height and width, no matter the number of cells, and no matter whether it goes offscreen or doesn't fill it.
(Also, I just thought, maybe it's not the best idea to code this and then shove it in a JScrollPane later and expect it to perform the same.... I guess I'll just see what happens.)
but I wanted the actual ImageIcon in the JLabels to fill the entire JLabel.
Check out Darryl's Stretch Icon which will allow the icon to resize to file the space available for the JLabel.
I have a column of JPanel instances that has content in it, that when it is clicked, the selected Panel is set to have a border (in order to distinguish it), and only 1 at a time has the border.
The problem is that when it sets the border, it sets the outer section of the panel to the border, and shrinks the content inside. Although it seems minor it is not very professional, and I would much rather have it add more like an overlay, where the content will not shrink.
I am thinking maybe there is some method of graphics that will let me do this? I haven't been able to find any way of doing this.
Start by setting all the components to have a EmptyBorder set to a single pixel inset.
When you select a panel, simply set the newly selected panel's border as you are (presumably using a LineBorder) and the set the previously selected panel's border to the single pixel EmptyBorder.
If you're clever, you could get away with a single instance of EmptyBorder ;)
I am building a small java application that deals with taking screenshots.
I have a custom class that inherits from JPanel called ScreenshotPanel that holds the image, and it is inside a JScrollPane. The ScrollPane moves and resizes when the frame is resized.
All works well except the zoom part, I want to be able to control the size of the screenshotPanel inside the ScrollPane, however the screenshotPanel doesn't resize, it flickers at the right size for a moment but then it's being resized back to the ScrollPane size.
If I use the screenshotPanel without the ScrollPane it works exactly right, but I want it to automatically add scrollers so you can see move the image around while zoomed-in.
Here is the part of the code I use to resize:
double AR=((double)screenshotPanel.getImage().getHeight())/screenshotPanel.getImage().getWidth();
screenshotPanel.setSize((int)((getWidth()-180)*zoomFactor), (int)((AR*(getWidth()-180)-100)*zoomFactor));
scrollPane.setSize(getWidth()-180, (int)(AR*(getWidth()-180))-100);
the -180 and -100 are used to keep a space for buttons and zoom control componenets (which all move and resize perfectly), zoomFactor is a double that hold the amount to zoom.
How do I resize the screenshotPanel inside the ScrollPane without the ScrollPane forcing it's size back?
Changing the size of the component won't scale the image, unless you have code in your paint method to compensate for the change in size.
JViewPort is respecting your components preferred size, thus you get this flicker, as you change the size and the viewport resets it.
Add a scale method to your panel and override the getPreferredSize method.
When you call setScale, calculate the new scaled size. Make sure that the getPreferredSize method returns these values.
You will need to call invalidate and possibly repaint to make sure the change is updated through the container hierarchy.
Remember, the pane will not resize the image on it's own, you are responsible for taking this ;)
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.