I´m new with JLabel, i wonder if it's possible to set the text in a coordenate specific (x,y) over an image.
Like this:
So the text is "HI"
label.setText("HI");
label.setIcon(icon);
I'm trying to say that label contains an image and a text but i want to locate it in a specific position like the image above.
I don't want to use label.setHorizontalTextPosition(i);
or setVerticalTextPosition(i);
Sorry for my bad english
Thanks in advance ^ ^
By overriding the paintComponent method, text can be drawn in any position.
JLabel label = new JLabel(icon) {
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawString("Hi", 10, 10); //these are x and y positions
}
};
There are any number of, reasonable, ways to do it.
However, you should avoid using null layouts, pixel perfect layouts are an illusion within modern ui design. There are too many factors which affect the individual size of components, none of which you can control. Swing was designed to work with layout managers at the core, discarding these will lead to no end of issues and problems that you will spend more and more time trying to rectify
GridBagLayout and GridBagConstraints#insets
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (IOException ex) {
ex.printStackTrace();
}
}
});
}
public class TestPane extends JPanel {
public TestPane() throws IOException {
setLayout(new GridBagLayout());
BufferedImage img = ImageIO.read(...);
JLabel background = new JLabel(new ImageIcon(img));
background.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(1, 46, 9, 0);
gbc.anchor = GridBagConstraints.SOUTH;
gbc.weighty = 1;
JLabel message = new JLabel("Go that way!");
message.setVerticalAlignment(JLabel.BOTTOM);
background.add(message, gbc);
add(background);
}
}
}
Graphics2D
You could paint the text directly onto the image, but as you can see, it becomes considerably more complex
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (IOException ex) {
ex.printStackTrace();
}
}
});
}
public class TestPane extends JPanel {
public TestPane() throws IOException {
JLabel background = new JLabel();
BufferedImage img = ImageIO.read(...);
Graphics2D g2d = img.createGraphics();
g2d.setFont(background.getFont());
String text = "Go that way!";
FontMetrics fm = g2d.getFontMetrics();
int x = 46 + (((img.getWidth() - 46) - fm.stringWidth(text)) / 2);
int y = (((img.getHeight() - fm.getHeight())) + fm.getAscent()) - 9;
g2d.setColor(Color.BLACK);
g2d.drawString(text, x, y);
g2d.dispose();
background.setIcon(new ImageIcon(img));
add(background);
}
}
}
You can follow this Example, also take a look on setLocation() method for Components like JLabel, also try to use Layouts to manage better the position for each Component.
This guy also work with location with JLabel, you can see how he does the work and apply it in your project.
Example
JLabel label = new JLabel("Hi");
panel.add(label);
//This is to get the width and height
Dimension size = label.getPreferredSize();
//You can change 100(x) and 100(y) for your likes, so you can put that JLabel wherever you want
label.setBounds(100, 100, size.width, size.height);
You'll have to know what x and what y you want to put the JLabel right there.
If you want to do that, just do what tong1 did, but showing the x and y to know where exactly you want it.
Create a Container
Container container= getContentPane();
Add the JLabel on it
container.add(label);
Add an MouseListener() to get the x and y
container.addMouseListener(new MouseAdapter(){
public void mouseClicked(MouseEvent e){
//x and y are ints.
x = e.getX();
y = e.getY();
label.setBounds(x,y,150,50);
}
});
Related
With all the different 'containers' I'm using, it's hard to set my window size in the code. I guess I need them but at the same time need to find a way to change settings around it.
I've tried doing frame.setSize(int x, int y), did not work.
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TweetProgram1{
public static void main(String[] args) {
new TweetProgram1();
}
public TweetProgram1() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Tweet Program");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TweetProgram1Pane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TweetProgram1Pane extends JPanel {
public TweetProgram1Pane() {
setLayout(new GridBagLayout());
JLabel lbl = new JLabel("Random tweet");
JButton btn = new JButton("Send it");
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = 300;
gbc.gridheight = 300;
add(lbl, gbc);
add(btn, gbc);
}
}
}
I expect to be able to re-scale the window size (in the code) to whatever I need it to be.
Thanks
I want to create brightness functionality in Swing. JPanel and its component's brightness level will be adjust in this functionality.
To achieve this I used JLayeredPane and added JPanel as BrightNessPanel on the top of my JPanel called MainPanel. I am giving brightness effect by changing the opacity of BrightNessPanel. This will simulate Brightness effect for my MainPanel.
Now problem is that, I am not able to click the buttons present on MainPanel because of layer of BrightNessPanel.
How do I pass through clicks from BrightNessPanel to the buttons present on MainPanel??
You might be able to make use the JLayer API which allows you to perform painting operations ontop of other components.
import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLayer;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.plaf.LayerUI;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
TestPane testPane = new TestPane();
BrightnessLayerUI layerUI = new BrightnessLayerUI();
JLayer<JComponent> layer = new JLayer<>(testPane, layerUI);
JSlider slider = new JSlider(0, 100);
slider.addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent e) {
int value = slider.getValue();
float brightness = (100 - value) / 100f;
layerUI.setBrightness(brightness);
testPane.repaint();
}
});
slider.setValue(100);
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(layer);
frame.add(slider, BorderLayout.SOUTH);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(new JTextField(10), gbc);
add(new JButton("Hello"), gbc);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.dispose();
}
}
public class BrightnessLayerUI extends LayerUI<JComponent> {
private float brightness = 0f;
public void setBrightness(float brightness) {
this.brightness = brightness;
}
public float getBrightness() {
return brightness;
}
#Override
public void paint(Graphics g, JComponent c) {
super.paint(g, c);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(c.getBackground());
g2d.setComposite(AlphaComposite.SrcOver.derive(getBrightness()));
g2d.fillRect(0, 0, c.getWidth(), c.getHeight());
g2d.dispose();
}
}
}
One of the advantages of this is you could actually introduce a "brightness" algorithm, rather than faking it, by using a backing buffer, which is demonstrated the link above (this use to to blur the UI)
Hi I have following classes, I want display content
(paintComponentor that panel with this rectangle from paint class)
inside my JFrame. I try already find out how to achieve this by
looking at different examples posted on this forum however this
doesn't help me I need simple example like panel inside frame with
paint component or something similar to understand how should work!
ps. don't hang me on tree because I am newbie jut ask question!!!
[I want something like this][1]
package scp;
import java.awt.*;
import javax.swing.*;
public class Panel extends JPanel {
public Panel() {
//this.setPreferredSize(new Dimension(200,200));
//panel = new Panel();
setVisible(true);
setLayout(new FlowLayout());
setSize(200, 300);
getRootPane();
}
#Override
public void paintComponent(Graphics g){
g.drawString("HEY",20,20);
g.drawRect(200, 200, 200, 200);
}
}
and
package scp;
import javax.swing.JFrame;
import javax.swing.JButton;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.beans.EventHandler;
public class Frame extends JFrame {
JButton redButton;
JButton blueButton;
public Frame()
{
super("EventHandling");
setLayout(new FlowLayout());
redButton = new JButton("Red");
add(redButton);
blueButton = new JButton("Blue");
add(blueButton);
EventHandler h = new EventHandler();
redButton.addActionListener(h);
blueButton.addActionListener(h);
}
private class EventHandler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
if (e.getSource()==redButton)
getContentPane().setBackground(Color.RED);
else if(e.getSource()==blueButton)
getContentPane().setBackground(Color.BLUE);
}
}
}
and
package scp;
import javax.swing.JFrame;
public class EventHandling {
public static void main(String[] args) {
Frame f = new Frame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(800,600);
f.setVisible(true);
f.getContentPane().add(new Panel());
}
}
[1]: http://i.stack.imgur.com/OJTrq.png
Start by taking a look at:
Painting in AWT and Swing
Performing Custom Painting
2D Graphics
This is probably the simplest I can make it...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int width = getWidth() - 100;
int height = getHeight() - 100;
int x = (getWidth() - width) / 2;
int y = (getHeight() - height) / 2;
g2d.setColor(Color.RED);
g2d.drawRect(x, y, width, height);
g2d.dispose();
}
}
}
Compound Example
This example uses an outer panel, which has an empty border applied to it, this pushes the content of the edges of the outer panel.
The inner panel (which is unchanged from the last example), as a light gray border applied to it so you can see it, the red rectangle is still been painted by the panels paintComponent method.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JPanel outer = new JPanel(new BorderLayout()) {
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
};
outer.setBorder(new EmptyBorder(50, 50, 50, 50));
TestPane tp = new TestPane();
tp.setBorder(new LineBorder(Color.LIGHT_GRAY));
outter.add(tp);
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(outer);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int width = getWidth() - 100;
int height = getHeight() - 100;
int x = (getWidth() - width) / 2;
int y = (getHeight() - height) / 2;
g2d.setColor(Color.RED);
g2d.drawRect(x, y, width, height);
g2d.dispose();
}
}
}
I wanted to know how to set an image to a JTextField if this is transparent, or how to make my JTextField look like this:
Here's how I make my field transparent, but I can't set its background image:
//Step 1: Remove the border line to make it look like a flat surface.
field.setBorder(BorderFactory.createLineBorder(Color.white, 0));
//Step 2: Set the background color to null to remove the background.
field.setBackground(null);
All Swing components have a concept of transparency, which is controlled via the use of opaque property. Setting the background to null tents to rest the background color of the field to it's UI default.
Having said that, some components can ignore this (partially or completely). In these case we can cheat...
In the following example, set the field transparent via the opaque property, this is important, as the RepaintManager will not paint areas behind components unless they are transparent, and use a fully transparent background color.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestTextField {
public static void main(String[] args) {
new TestTextField();
}
public TestTextField() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JTextField field = new JTextField(20);
field.setBackground(new Color(0, 0, 0, 0));
field.setOpaque(false);
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setBackground(Color.RED);
frame.setLayout(new GridBagLayout());
frame.add(field);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
Updated based on comments...
This is a very specific example designed to provide a direct answer to the presented problem. Basically, what this does is creates a custom border and uses an Image to render the "border"
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.AbstractBorder;
import javax.swing.border.Border;
import javax.swing.border.MatteBorder;
public class TestTextField {
public static void main(String[] args) {
new TestTextField();
}
public TestTextField() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JTextField field = new JTextField(20);
try {
BufferedImage img = ImageIO.read(getClass().getResource("/FieldBorder.png"));
field.setBorder(new ImageBorder(img, 8, 6));
} catch (IOException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridBagLayout());
frame.add(field);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class ImageBorder implements Border {
private BufferedImage img;
private int bottomMargin;
private int leftMargin;
public ImageBorder(BufferedImage img, int leftMargin, int bottomMargin) {
this.img = img;
this.bottomMargin = bottomMargin;
this.leftMargin = leftMargin;
}
#Override
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
g.drawImage(img, x, y + height - img.getHeight(), c);
}
#Override
public Insets getBorderInsets(Component c) {
return new Insets(0, leftMargin, bottomMargin, 0);
}
#Override
public boolean isBorderOpaque() {
return false;
}
}
}
Now, this could also be done using custom painting within the custom Border instead, but was quicker this way ;)
Another option...
Is to simply use a JPanel and add the field and a JLabel holding the border outline together, for example...
import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.Border;
public class TestTextField {
public static void main(String[] args) {
new TestTextField();
}
public TestTextField() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JTextField field = new JTextField(20);
field.setBorder(null);
JPanel fieldPane = new JPanel(new GridBagLayout());
fieldPane.setBackground(Color.WHITE);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.anchor = GridBagConstraints.WEST;
gbc.insets = new Insets(0, 8, 0, 0);
fieldPane.add(field, gbc);
try {
BufferedImage img = ImageIO.read(getClass().getResource("/FieldBorder.png"));
gbc.insets = new Insets(0, 0, 0, 0);
fieldPane.add(new JLabel(new ImageIcon(img)), gbc);
} catch (IOException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridBagLayout());
frame.add(fieldPane);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
But this will come down to needs and requirements...
Text field with a background
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.text.Document;
public class TextFieldBackground {
public static void main(String[] args) {
new TextFieldBackground();
}
public TextFieldBackground() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
TextFieldWithBackground field = new TextFieldWithBackground(40);
try {
field.setBackgroundImage(ImageIO.read(getClass().getResource("/clouds.jpg")));
} catch (IOException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridBagLayout());
frame.add(field);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TextFieldWithBackground extends JTextField {
private BufferedImage bg;
public TextFieldWithBackground() {
}
public TextFieldWithBackground(String text) {
super(text);
}
public TextFieldWithBackground(int columns) {
super(columns);
}
public TextFieldWithBackground(String text, int columns) {
super(text, columns);
}
public TextFieldWithBackground(Document doc, String text, int columns) {
super(doc, text, columns);
}
public void setBackgroundImage(BufferedImage bg) {
this.bg = bg;
setOpaque(bg == null);
repaint();
}
#Override
protected void paintComponent(Graphics g) {
if (bg != null) {
int x = 0;
int y = (getHeight() - bg.getHeight()) / 2;
while (x < getWidth()) {
g.drawImage(bg, x, y, this);
x += bg.getWidth();
}
}
super.paintComponent(g);
}
}
}
So I've been trying to export an image that I've drawn on a JPanel into an image. I've been using this method:
BufferedImage image = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics2D g = image.createGraphics();
paint(g);
try { ImageIO.write(image, "png", new File([location goes here]); } catch (IOException e) {}
I get an image in my intended location but I get a compressed version of what my JPanel shows. The same happens if I try to export a BMP as well. Is there a way to get a pixel-perfect image exported from the JPanel? Thanks in advance.
The panel needs to be laid out based on it's requirements. If the panel hasn't being realized on the screen yet, it may not render the way you expect it do
The following example assumes that the panel has not being displayed on the screen...
setSize(getPreferredSize());
BufferedImage image = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics2D g = image.createGraphics();
printAll(g);
g.dispose();
try {
ImageIO.write(image, "png", new File([location goes here]);
} catch (IOException e) {
e.printStackTrace();
}
You should avoid calling paint yourself, it can throw an exception if the component has not being realized on the screen, instead, use printAll
Also, if your create a resource, you should dispose of it ;)
Updated
I did this quick example. Screen shoot on top, jpeg on left, png on right.
jpeg is 30kb and png is 320kb
I used this to create it...
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class PaintComponent {
public static void main(String[] args) {
new PaintComponent();
}
public PaintComponent() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JPanel paintPane;
public TestPane() {
paintPane = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
paintPane.add(new JLabel("I'm a label"), gbc);
paintPane.add(new JTextField("I'm a text field", 20), gbc);
paintPane.add(new JLabel(new ImageIcon("some\pretty\picture")), gbc);
setLayout(new BorderLayout());
add(paintPane);
JButton paint = new JButton("Capture");
paint.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
BufferedImage image = new BufferedImage(paintPane.getWidth(), paintPane.getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics2D g = image.createGraphics();
paintPane.printAll(g);
g.dispose();
try {
ImageIO.write(image, "jpg", new File("Paint.jpg"));
ImageIO.write(image, "png", new File("Paint.png"));
} catch (IOException exp) {
exp.printStackTrace();
}
}
});
add(paint, BorderLayout.SOUTH);
}
}
}
I would make sure that you are actually looking at the correct files ;)
If you are trying to make an image of a panel that is not visible on a window then check out Screen Image. It will invoke doLayout() on the panel to make sure the components are displayed properly.