I'm using a self-made DesktopPaneUI for a JDesktopPane, I've written the proper methods for the class, and I'm running into trouble. When I resize the JDesktopPane, the background image doesn't resize with the frame. The image appears to be clipped at the size it was when the window initially opened. I'm giving it an image larger than the window, and I'm still having this problem.
Here's my method call inside the constructor of my desktopUI class.
super();
this.background = javax.imageio.ImageIO.read(new File(fileName));
Is there a way I can change my main class where I set the UI, or the myDesktopPaneUI class such that the background still fills the window when the JDesktopPane changes size?
setUI(new myDesktopPaneUI("media/bg.jpg"));
Override paint() to invoke drawImage() in a way that scales the image to the pane's size:
#Override
public void paint(Graphics g, JComponent c) {
g.drawImage(image, 0, 0, c.getWidth(), c.getHeight(), null);
}
If you are only creating the custom UI to add the background image, the easier approach is to do custom painting of the JDesktopPane so that it works for all LAF's:
JDesktopPane desktop = new JDesktopPane()
{
protected void paintComponent(Graphics g)
{
g.drawImage(image, 0, 0, getWidth(), getHeight(), null);
}
};
Normally you would invoke super.paintComponent(g) first, but since the image will cover the entire background there is no need to do this.
Use a component Listener to know when the windows has been resized and then rescale the image using
image.getScaledInstance(getWidth(), getHeight(), 0);
Related
I am new to making GUIs so I decided to try the the windows builder for eclipse, and while great I do have some doubts. I have been searching but I cannot seen to find a good way to add a background image to my "menu". For example I tried this:
public Menu() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(50, 50, 300, 250); //Dimensiones
contentPane = new JPanel() { //Imagen de Fondo
public void paintComponent(Graphics g) {
Image img = Toolkit.getDefaultToolkit().getImage(
Menu.class.getResource("/imgs/rotom.jpg"));
g.drawImage(img, 0, 0, this.getWidth(), this.getHeight(), this);
}
};
And adding the following classes:
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
But to no avail the window remains with its dull grey color, so far my code is just the standard one WindowsBuilder cooks for you plus 4 buttons but I doubt they're of importance here. Shouldn't the code I added override the paintComponent() method of the jPanel and draw the image in it?
The class for the menu is in a package within my project and the image is within a imgs package is within the same project as well.
Thanks a lot in advance.
A simple method, if you're not interested in resizing the background image or applying any effects is to use a JLabel...
BufferedImage bg = ImageIO.read(Menu.class.getResource("/imgs/rotom.jpg"));
JLabel label = new JLabel(new ImageIcon(bg));
setContentPane(label);
setLayout(...);
There are limitations to this approach (beyond scaling), in that the preferred size of the label will always be that of the image and never take into account it's content. This is both good and bad.
The other approach, which you seem to be using, is to use a specialised component
public class BackgroundPane extends JPanel {
private BufferedImage img;
public BackgroundPane(BufferedImage img) {
this.img = img;
}
#Override
public Dimension getPreferredSize() {
return img == null ? super.getPreferredSize() : new Dimension(img.getWidth(), img.getHeight());
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(img, 0, 0, this);
}
}
You should avoid trying to perform any task in the paintComponent method which may take time to complete as paintComponent may be called often and usually in quick succession....
Getting the image to scale when the component is resized is an entire question into of it self, for some ideas, you could take a look at...
Java: maintaining aspect ratio of JPanel background image
Java: JPanel background not scaling
Quality of Image after resize very low -- Java
Reading/Loading images
Oh, and, you should avoid extending directly from top level containers, like JFrame, they reduce the reusability for your components and lock you into a single container
I try to draw a .PNG Image using graphic2D.drawImage() method.
And I make it right, but I've one JPanel on my Frame, and when I draw my image, it appears in background. I want it to appear on the foreground, and obviously in front of my JPanel.
Use JLayer. (http://docs.oracle.com/javase/tutorial/uiswing/misc/jlayer.html)
Override the paint method on the LayerUI set to the JLayer and draw your .PNG image there. Add your JPanel to the JLayer.
You should add one more JPanel and draw image in its paintComponent method like that.
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (yourImage != null)
g.drawImage(yourImage, 0, 0, this);
}
and than you can hide other JPanel and show this JPanel with setVisible() function.
this has been driving me crazy all day so I figured I'd post it here and see if someone else can work it out. First off I tried to add a background image, the default ImageIcon was not working so I went with overriding the paint method instead. #
public class ImageJPanel extends JPanel {
private static final long serialVersionUID = -1846386687175836809L;
Image image = null;
public ImageJPanel(){
addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent e) {
ImageJPanel.this.repaint();
}
});
}
//Set the image.
public ImageJPanel(Image i) {
image=i;
setOpaque(false);
}
//Overide the paint component.
public void paint(Graphics g) {
if (image!=null) g.drawImage(image, 0, 0, null);
super.paint(g);
}
}
Once I used that it worked fine, however now I want to add images to my buttons but it is not working. Here is how my buttons work:
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Images images = new Images();
JPanel j = new ImageJPanel(images.menuBackground);
j.setLayout(null);
JButton Button_1= new JButton("Button_1",new ImageIcon("images/gui/Button.png"));
Insets insets = j.getInsets();
Dimension size = Button_1.getPreferredSize();
Button_1.setBounds(300 + insets.left, 150+ insets.top, size.width, size.height);
Singleplayer.setSize(200, 50);
j.add(Button_1);
frame.add(j);
frame.setSize(800,600);
frame.setResizable(false);
Button_1.addMouseListener(singleplayerPressed);
frame.setVisible(true);
All my images are .png, could that affect it?
Let's start with this:
public void paint(Graphics g) {
if (image!=null) g.drawImage(image, 0, 0, null);
super.paint(g);
}
This is the wrong approach. Firstly, you really don't want to override the paint method UNLESS you absolutely know that this is the correct approach to your problem (and without knowing more, I'd suggest it isn't).
Secondly, you paint your image on the component, then promptly paint over the top of it...(super.paint(g); can have the ability to paint over your work, I know the panel is opaque, but this is still a very bad approach).
Use paintComponent instead
protected void paintComponent(Graphics g) {
super.paint(g);
if (image!=null) g.drawImage(image, 0, 0, null);
}
PNG images are fine, they are supported by Swing out of the box.
Make sure that your program can see the image. Is it been loaded from the file source or is it a resource within you JAR?
Try this:
System.out.println(new File("images/gui/Button.png").exits());
If your program can see the file, it will return true other wise the program can not see the file and that is your problem.
Try this:
ImageIcon image = new ImageIcon(this.getClass()
.getResource("images/gui/Button.png"));
Side note, you should override paintComponent() not paint(). Also make sure to call super implementation before doing all your painting. For more details see Lesson: Performing Custom Painting tutorial.
So im making a gui, and i have a background image for it. i dont know how to make it set as the background, so any help with that would be good. an explination would also be good. also, after we get that image as a background, how do we get the image resize to the size of the window. such as
image.setSize(frame.getHeight(), frame.getWidth());
but i dont know if that would work. the image name is ABC0001.jpg and the frame name is frame. thanks!
To get the image to resize, you can either use
public void paintComponent(Graphics g) {
g.drawImage(img, 0, 0, getWidth(), getHeight(), this); // draw the image
}
or you can use a componentlistener, implemented like:
final Image img = ...;
ComponentListener cl = new ComponentAdapter() {
public void componentResized(ComponentEvent ce) {
Component c = ce.getComponent();
img = im1.getScaledInstance(c.getWidth(), c.getHeight(), Image.SCALE_SMOOTH);
}
};
Image quality will degrade over time with the second solution, so it is recommended that you keep the original and the copy separate.
Create a class the extends JPanel. Have that class load the image by overriding paintComponent
class BackgroundPanel extends JPanel
{
Image img;
public BackgroundPanel()
{
// Read the image and place it in the variable img so it can be used in paintComponent
img = Toolkit.getDefaultToolkit().createImage("ABC0001.jpg");
}
public void paintComponent(Graphics g)
{
g.drawImage(img, 0, 0, null); // draw the image
}
}
Now that you have this class, simply add this to your JFrame (or whereever you want the background).
//create refrence if you want to add stuff ontop of the panel
private BackgroundPanel backGroundPanel;
//constructor
add(backGroundPanel, BorderLayout.CENTER);
The size of the background will fill the entire frame so no need to scale it unless you want it smaller
I have extended jEditorPane as shown below (minus the instantiation code). However, when I set the image and call update on the object, it only draws a small portion of the image (equivalent to where one line of text would go). Can somene tell me what I am doing wrong here?
public class JEditorPaneImg extends JEditorPane {
private BufferedImage bi = null;
public JEditorPaneImg() {
initComponents();
}
#Override
public void paint(Graphics g) {
super.paint(g);
if (bi != null) {
Graphics2D g2 = (Graphics2D) g;
g2.drawImage(bi, 0, 0, this);
}
}
public void setImage(BufferedImage image){
bi = image;
}
}
I don't understand what you are attempting to do. It looks like you are trying to paint an image on top fo the the text in the editor pane.
First of all you should never invoke update(). Swing will determine when painting needs to be done.
If you want to paint an image on top of the editor pane, then there is no need to add custom painting to the editor pane. All you do is is create a JLabel and add an ImageIcon to the label. Then add the label to the editor pane. Make sure you use:
label.setSize( label.getPreferredSize() );
and the label will simply be painted as a child component of the editor pane.
If you need more help post your SSCCE showing the problem.