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 ;)
Related
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 currently have an image that I load into program as a BufferedImage. This BufferedImage is put inside a JPanel class which has a fixed size.
Now the problem I am facing is that how can I pan this large BufferedImage inside this fixed size JPanel.
The JPanel dimension is definitely smaller than the image.
Thanks!
First, attach some scroll bars to the JPanel (south and east, using a BorderLayout) that will be visible only if the image is too large and/or high. Attach another JPanel in the remaining space (center). In that inner JPanel, you would override the paintComponent method and would draw the portion of your BufferedImage into the JPanel. Use the scroll bars' offset to offset your image, and the inner JPanel for the width and height to draw (the viewport).
Note: your scroll bars will invoke the repaint method of your inner JPanel whenever their value change.
The paintComponent will be called by the system automatically (or manually) whenever the image needs to be redrawn. Doing this, you will be able to customize the view you give your image (if such feature is needed); rotation, scaling, pixel manipulation, custom overlays etc.
You can also attach some MouseMotionListener to the inner JPanel and modify the scroll bars' offset according the mouse movements (modifying the scroll bars will automatically trigger the repaint on the image) for mouse interaction with your component. Just a thought.
I'm making Minesweeper as a school project. It's close to completion, but the only problem now is setting JFrame's size. I just can't figure out a way to set frames to the size I want.
The program looks almost like a Swing version of the original Minesweeper on Windows XP.
The main frame's layout is flow layout. There's a top panel for the time, mines, and reset button. The top panel's using flow layout, and the bottom panel's using grid layout for the buttons.
I set the preferred size of the frame's content pane. Getting the width is easy (The numbers of fields in a row * my button size), but the problem is getting the height right. The frame always go down to the 2nd last row of the minefield.
I also tried pack() but it resizes it to the preferred size of the content pane, which isn't the right size to begin with. What can I do?
Don't have the JFrame (or better its contentPane) use FlowLayout since this won't give the JFrame the best size for its components. Instead why not have it use the default BorderLayout? Your mine cell's will probably have their getPreferredSize() method overridden and thus will direct the size of the enclosing containers. As always, call pack() on the JFrame after filling it with components and before calling setVisible(true) on it.
Set a preferred size for the buttons in the GridLayout and pack() the frame after adding them.
Don't try to manually set the size. You should let each component display at its preferred size and use the pack() method.
The main frame's layout is flow layout. There's a top panel for the time, mines, and reset button
I would use a BorderLayout. Create a top panel and add it to the NORTH.
Then create a panel for the grid and add it to the CENTER. If you have problems with the buttons in the grid resizing then try creating a JPanel as a wrapper panel. Add the buttons to this panel and then add this panel to the CENTER of the frame. The panel will retain its preferred size.
I'm working on rotating a loaded image. I set the graphics on a JPanel and then use standard AffineTransform in order to rotate it, say, 45 degrees.
Unfortunately, the image is being cut, if it exceeds the panel area.
How may I force JPanel to add scrolls to itself (while loading an image file, I would like to adjust the size of JPanel by adding the scrolls, without adjusting the size of JFrame).
Or, in other words, how to correctly rotate the whole image?
Thank you in advance for the reply!
Use a JScrollPane instead.
You need to put the panel in a jscrollPane and then make sure you have the preferredsize set correctly so that the scroll will be available.
Well, I would suggest that you should not be rotating the image in the paintComponent() method of your panel since this will result in the preferred size of the panel changing and you should not be setting the preferred size in the paintComponent() method.
Instead you should probably have a rotate(...) method. This method will create a BufferedImage of the desired rotation. Then your paintComponent() method simply paints the buffered image. Then you would set the preferred size based on the rotation.
Now regarding the preferred size of the rotated image check out this example.
I need to find a component's exact screen size in pixels when the main JFrame is resized.
I've tried several things and couldn't find an easy way to do it: it probably have missed something obvious.
BBBBB JFRAME BORDER BBB
BZZZZZZZZZZZZZZZZZZZZZB
BAAAAAAAAAAAAAAAAAAAAAB
BCC1................DDB
BCCC................DDB
BCCC................DDB
BCCC................DDB
BCCC................2DB
BEEEEEEEEEEEEEEEEEEEEEB
BBBBBBBBBBBBBBBBBBBBBBB
Resized, it could become this if, say, the user made the main JFrame shorter (vertically) and wider (horizontally):
BBBBBB JFRAME BORDER BBBBBB
BZZZZZZZZZZZZZZZZZZZZZZZZZB
BAAAAAAAAAAAAAAAAAAAAAAAAAB
BCC1....................DDB
BCCC....................2DB
BEEEEEEEEEEEEEEEEEEEEEEEEEB
BBBBBBBBBBBBBBBBBBBBBBBBBBB
What I want is to find the exact size in pixels, on screen, of the rectangle area indicated by dots.
I'm adding a ComponentListener to get the resizing events, which works fine.
The issue I'm having is that calling getWidth()/getHeight() on a Component does apparently not return the component's screen size but the component's actual size (and you can have, for example, a JPanel wider than the component it is into).
Any hint most welcome.
You're looking for JComponent.getVisibleRect().
getWidth() and getHeight() returns the width and height of the component. I've never heard of any difference between "actual" width/height and "screen" width/height.
Some layout managers however, does not fill the panel with a component it contains, and some space between the component and the panels edge may not be occupied by the component. In that case I usually setBackground(Color.BLUE) on the underlying panel to see what's going on.
This is a very rubbish way but you can use a wrapper Panel, where you put your main panel into. Than you can call getWidth() and getHeight() from the wrapper panel.