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.
Related
I want my JPanel to be semi transparent. This panel is animated and has the motion of a dropdown list. I have used the Color(r,g,b,a) constructor to achieve the transparency, however the transparency only takes effect as the panel returns to its original position. For example, as it is moving downwards it is not transparent at all, however when moves up, it spontaneously becomes transparent.
How do I fix this problem?
detailPanel.setBackground(new Color(50,50,50,220));
detailPanel.setLayout(null);
detailPanel.setBounds(0,posY,1200,750);
Check out Backgrounds With Transparency for the cause of the problem (you can't use a transparent Color on an opaque background) and a couple of solutions to fix the problem:
make the component non-opaque and paint the background yourself
use the AlphaContainer class so it can do the painting of the background for you
I have a window which contains upper JPanel where figures are painted and the lower JPanel where figures are listed in the JList the list looks like:
[minature][figure.toString()]
The minature is JPanel of a size 10x10. I would like it to contain minature of drawn figure in the upper Panel. By it I mean.
class minaturePanel{
Figure f;....
public void paint(Graphics g){
g.drawFullSizeFigure(f);
g.rescaleWholeInsidesOfThePanel();
}
}
This example paints into a BufferedImage and uses AffineTransformOp to do the scaling.
You may also want to look at JScrollNavigator, examined here. It lets you navigate on a thumbnail image of your entire component, seen at full size in an adjacent scroll pane.
It seems you want to draw your full figure to an image, return the image, and then rescale the image then draw the image on the panel which will be the right size as the panel now. Actually you can rescale the image while drawing it.
If the Figure has no capacity to scale it self. You can use a AffineTransformation to scale the Graphics context your self. Just don't forget to restore the previous transformation...
Check out Transforming Shapes, Text, and Images for more details.
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 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 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.