I'm capturing a screenshot image of a JFrame via a "double buffering" approach, per below:
public BufferedImage getScreenshot() {
java.awt.Dimension dim = this.getPreferredSize();
BufferedImage image = new BufferedImage(dim.width, dim.height, BufferedImage.TYPE_INT_RGB);
this.paint(image.getGraphics());
return image;
}
where this extends JFrame. The image that I get has a blank strip along the top where the title bar was. What's the most straightforward way to capture an image of the contents of the JFrame without the extra space allocated for the title bar?
You should be able to use the Screen Image class. Just specify the content pane of the frame (or the root pane if you have a menu) as the component you want the image of.
Or your basic code should work, again just specify the content pane (or root pane) as the component you want to paint, not the frame itelf.
Related
Just like we can resize a JFrame I'd like to show an image on a frame. I'd like to be it resizeable so when I resize the image should be resized.
How could I do this?
try {
myPicture = ImageIO.read(f);
picLabel.setIcon(new ImageIcon(myPicture));
panel.add(picLabel);
} catch (IOException e) {
e.printStackTrace();
}
I added the label (with the image) to a JPanel and the panel is added to the frame.
ImageIcons are always resizeable. Try converting it to an image, resizing it, convert it back to an ImageIcon, and then reapplying it (of course do this when you want to resize it).
Image myScaledPicture = myPicture.getImage().getScaledInstance(newWidth, newHeight, Image.SCALE_SMOOTH);
picLabel.setIcon(new ImageIcon(myScaledPicture);
More info here: How to resize JLabel ImageIcon?
You can use the Stretch Icon.
It can be used in any component that can paint an Icon and the image will scale as the component is resized.
It is reusable code so you don't have to do custom painting all the time.
I want to generate an icon with an svg icon content. For example a yellow circle with a face (svg file) in it. At the moment I have this code.
The circle is in the right position but the svg is drawn all over the JPanel and if i resize the frame the svg is added all the time.
The svg is loaded with white background and in the wrong size.
Is there a way to make the background of the svg transparent and transform the svg to the circle size?
As information: The svg file has got a transparent background (seen in adobe illustrator) but in Java its loaded white...
import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
import org.apache.batik.swing.JSVGCanvas;
public class IconTest extends JPanel{
public IconTest(){
}
#Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D)g;
super.paintComponent(g2d);
this.setBackground(new Color(255,255,255));
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// create icon body
Ellipse2D iconBody = new Ellipse2D.Double(0, 0, 100, 100);
g2d.setPaint(Color.YELLOW);
g2d.draw(iconBody);
g2d.fill(iconBody);
// icon content
JSVGCanvas svg = new JSVGCanvas();
svg.setURI("file:/C:/Users/Linda/Desktop/smile.svg");
add(svg);
}
public static void main(String[] args) throws Exception{
JFrame frame = new JFrame("IconTest");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600,600);
frame.setVisible(true);
IconTest i = new IconTest();
frame.add(i);
}
}
edit:
bevor transforming the window size
after transforming the window size. The SVG is added all the time with white background and it's size depends on how fast i transform the window...
Edit: You can download the svg file here
The svg is loaded with white background and in the wrong size.
I'm not 100% sure 'cause I can't test atm, but you're adding a white background with:
this.setBackground(new Color(255,255,255)); //Remove this line
So, the background is white and that's why you're seeing the svg with white background. Or change it to another color and see what happens.
What do you mean with in the wrong size?
The circle is in the right position but the svg is drawn all over the JPanel and if i resize the frame the svg is added all the time.
Well, JFrame by default has a BorderLayout and the default position when you add something without specifying where in the BorderLayout you want it is BorderLayout.CENTER and you're not adding anything else to it anywhere, so it's using the 100% size of your JPanel. Maybe you'd want to try with a different Layout Manager for example a BoxLayout or FlowLayout or maybe a GridLayout.
Another thing I saw in your code is you're adding your IconTest panel AFTER you're showing your JFrame, instead you should change it like this, once you've chosen another Layout for your JFrame.
JFrame frame = new JFrame("IconTest");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
IconTest i = new IconTest();
frame.add(i);
frame.setSize(600,600);
frame.setVisible(true);
I have no idea what the heck is going on while I'm trying to render an image on a JPanel in a JFrame. In fact I just want an image displayed in a fixed position on my JFrame.To achieve this I have a JPanel of a fixed size (min, max, pref size set) on my JFrame. On press of a button, I add another panel to mentioned panel, having the same size. The "child" panel has an overriden paint method to draw an image. So far so good, once I press the button and add that child panel, nothing happens at all. If I then click on the empty panel, the image is drawn as it should be, not overflowing the bounds of the child panel. However, all other components width increases drastically, stretching them out of the JFrames bounds. One would think that at least a scrollbar would appear, but no, the components are then out of reach. I'm attaching two screenshots displaying that very logic behavior.
The code is as follows:
void setPoster(BufferedImage poster) {
ImagePanel ip = new ImagePanel(poster);
ip.setSize(new Dimension(222, 327));
panelPoster.add(ip);
ip.setSize(new Dimension(222, 327));
}
Inside ImagePanel:
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, this);
System.out.println("Paiting imagepanel with size " + getSize());
}
Before screenshot:
After screenshot:
Could anyone enlighten me on what could possibly occur here?
I fixed the strange resizing by setting the layout to null on both the JFrame and the JPanel inside my tabbed pane.
setLayout(null);
jPanel4.setLayout(null);
Anyway, that's not needed when using the JLabel instead of the JPanel to hold the image.
However, my ImagePanel would not draw the image anymore, so I replaced it by a JLabel which draws the image just fine:
void setPoster(BufferedImage poster) {
JLabel imageLabel = new JLabel(new ImageIcon(poster));
panelPoster.add(imageLabel);
imageLabel.setSize(new Dimension(222, 327));
}
Note that without setting the size of the JLabel, it won't display anything.
I want this ImagePanel class to display an image that is quite high, so I put it in a JScrollPane. Funny thing is, when I add the ImagePanel to a JFrame it does show the image, but the scroll bar is not there, and there is no way to scroll (not with the mouse either)
When I wrote it, it extended JFrame for easier excess because the part in my programm where I need it takes some time to reach and this class has many methods to draw on the picture. As a JFrame it worked as intended.
Another problem is, that I tried some things to ensure that the width is large enough to display the image, but neither setSize(image.getWidth(), something) , nor setPreferedSize did that. I case it is relevant I add the ImagePanel like this:
all.add(imagePanel, BorderLayout.CENTER);
all.add(contentbox, BorderLayout.EAST);
to a JFrame, so it should stretch, but for some reason that does not work. Contentbox contains ContentPanes, I did not deactivate the LineWarp so it should leave space to the imagePanel (this is not the reason why I can't see the scroll bar, I tried it on an empty JFrame as well with space at both sides^^)
public class ImagePanel extends JPanel {
JLabel imageContainer;
ImageIcon icon;
BufferedImage image;
JScrollPane scroll;
Graphics g;
public ImagePanel (String cName) {
super();
File cFile = new File(cName);
try {
this.image = ImageIO.read(cFile);
} catch (IOException ex) {
ex.printStackTrace();
}
g = image.getGraphics();
g.setColor(Color.black);
icon = new ImageIcon(image);
imageContainer = new JLabel(icon);
scroll = new JScrollPane(imageContainer);
add(scroll);
}
}
Your ImagePanel uses JPanel's default FlowLayout, and this may be the source of your problem, since FlowLayouts can allow components larger than they are without showing the entire component. To test this out, have your ImagePanel use a BorderLayout, and add your JLabel to it BorderLayout.CENTER so that it fills the ImagePanel. Alternatively, you could get rid of the ImagePanel altogether and just return the JScrollPane that holds your JLabel.
How do i display some custom Controls or widgets next to cursor when dragging in SWT?
Like Button or Tree or Table not Image.
If it is not possible - how do i render such a Button into Image?
I've found the way of rendering arbitrary Control (widget) into Image using GC (canvas) class. Here is how:
dragSource.addDragListener(new DragSourceListener() {
#Override
public void dragStart(DragSourceEvent dragSourceEvent) {
// getting control widget - Composite in this case
Composite composite = (Composite) ((DragSource) dragSourceEvent.getSource()).getControl();
// Getting dimensions of this widget
Point compositeSize = composite.getSize();
// creating new GC
GC gc = new GC(composite);
// Creating new Image
Image image = new Image(Display.getCurrent(),compositeSize.x,compositeSize.y);
// Rendering widget to image
gc.copyArea(image,0,0);
// Setting widget to DnD image
dragSourceEvent.image = image;
}
... other overriden methods ...
}
You could use an undecorated Shell that follows the mouse position, and in that Shell have the widget(s) you want to display.