A few days ago I posted a question about a program that caused text on screen to change color when the mousewheel was scrolled. It was unfortunately a badly put together question with too much code posted to be particularly useful.
I had several responses, one of which was from the user trashdog who posted something that fixed the problem (which can be found at the bottom of this page here: Window going blank during MouseWheelMotion event) , however having read the class descriptions of all the things I didn't know about in the program he posted and gone through its execution I don't understand why his achieves a different effect from mine.
His seems to log every mouse wheel movement where as mine only does the initial movement. Also several people commented that they couldn't replicate the effect of my program probably because it was so big.
Below is an extremely simplified version which still elicits the same effect (I hope).
Question: What is the fundamental difference between the two programs that fixes the screen going blank when the mouse wheel events are being processed?
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.util.LinkedList;
import javax.swing.JFrame;
public class WheelPrinter implements MouseWheelListener, Runnable {
JFrame frame;
LinkedList colorList;
int colorCount;
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
WheelPrinter w = new WheelPrinter();
w.run();
}
public WheelPrinter() {
frame = new JFrame();
frame.setSize(500, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.addMouseWheelListener(this);
frame.setVisible(true);
frame.setBackground(Color.WHITE);
colorList = new LinkedList();
colorList.add(Color.BLACK);
colorList.add(Color.BLUE);
colorList.add(Color.YELLOW);
colorList.add(Color.GREEN);
colorList.add(Color.PINK);
}
#Override
public void mouseWheelMoved(MouseWheelEvent e) {
colorChange();
}
#Override
public void run() {
while(true) {
draw(frame.getGraphics());
try {
Thread.sleep(20);
} catch (Exception ex) {
}
}
}
public void draw(Graphics g) {
g.setColor(frame.getBackground());
g.fillRect(0,0,frame.getWidth(),frame.getHeight());
g.setFont(new Font("sansserif", Font.BOLD, 32));
g.setColor(frame.getForeground());
g.drawString("yes", 50, 50);
}
public void colorChange() {
colorCount++;
if (colorCount > 4) {
colorCount = 0;
}
frame.setForeground((Color) colorList.get(colorCount));
}
}
(Try spinning your mouse wheel really hard if you try running my code and it will become even more obvious)
while(true) { is endless loop, without break; f.e.
use Swing Timer instead of Runnable#Thread delayed by Thread.Sleep()
paint to the JPanel or JComponent, not directly to the JFrame
all painting to the Swing JComponent should be done in paintComponent()
more in the 2D Graphics tutorial
edit
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseWheelEvent;
import java.util.LinkedList;
import java.util.Queue;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
/**
* based on example by #trashgod
*
* #see http://stackoverflow.com/a/10970892/230513
*/
public class ColorWheel extends JPanel {
private static final int N = 32;
private static final long serialVersionUID = 1L;
private final Queue<Color> clut = new LinkedList<Color>();
private final JLabel label = new JLabel();
public ColorWheel() {
for (int i = 0; i < N; i++) {
clut.add(Color.getHSBColor((float) i / N, 1, 1));
}
//clut.add(Color.BLACK);
//clut.add(Color.BLUE);
//clut.add(Color.YELLOW);
//clut.add(Color.GREEN);
//clut.add(Color.PINK);
label.setFont(label.getFont().deriveFont(36f));
label.setForeground(clut.peek());
label.setText("#see http://stackoverflow.com/a/10970892/230513");
setBackground(Color.white);
add(label);
label.addMouseWheelListener(new MouseAdapter() {
#Override
public void mouseWheelMoved(MouseWheelEvent e) {
label.setForeground(clut.peek());
clut.add(clut.remove());
}
});
}
#Override
public Dimension getPreferredSize() {
int w = SwingUtilities.computeStringWidth(label.getFontMetrics(
label.getFont()), label.getText());
return new Dimension(w + 20, 80);
}
private void display() {
JFrame f = new JFrame("ColorWheel");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(this);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new ColorWheel().display();
}
});
}
}
The fundamental difference is that you are trying to interact with the Graphics object from the wrong thread and without knowing anything about the state the Graphics object is in at the time.
The generally correct way to interact with a Graphics object in Swing is by making a custom component which overrides the paintComponent(Graphics) method. You do your drawing while inside that method.
Your colorChange() method can tell your component to re-draw itself by calling repaint(), which will eventually lead to a call to paintComponent(Graphics) on the correct thread at the correct time.
See tutorial here
Related
Take the example from Oracle, there are some examples in your documentation.
My idea is the following:
I have achieved that my application has a transparent background, but the minimize and close application buttons do not appear
This is my code:
main
import javax.swing.JFrame;
import java.awt.*;
import javax.swing.*;
import static java.awt.GraphicsDevice.WindowTranslucency.*;
public class Textmovie extends JFrame {
/*
public Textmovie() {
//setLayout(new GridBagLayout());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
*/
public static void main(String[] args) {
JFrame jf = new JFrame("");
jf.setUndecorated(true);
jf.setBackground(new Color(0,0,0,10));
//jf.setOpacity(0.55f);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.add(new texscroll());
jf.setSize(720,480);
jf.setVisible(true);
}
}
Part 2
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JPanel;
/**
*
* #author inide
*/
public class texscroll extends JPanel {
int x =510 , y = 25;
public texscroll() {
setOpaque(false);
}
#Override
public void paint(Graphics g){
super.paint(g);
Graphics2D g2 = (Graphics2D)g;
Font font = new Font("Arial",Font.BOLD + Font.PLAIN,15);
g2.setFont(font);
g2.setColor(Color.BLACK);
String string = "stackoverflow stackoverflow stackoverflow stackoverflow";
g2.drawString(string ,x,y);
try{Thread.sleep(14);}
catch(Exception ex)
{
};
x-=1;
if(x==-10*string.length()){
x= 510;
}
repaint();
// System.out.println(string.length() );
}
}
And this is shown when running in NetBeans IDE 8.0.2
They can explain to me what I have to do to make the buttons appear (minimize and close application).
If you actually dig into the code based on the exception:
Exception in thread "AWT-EventQueue-0" java.awt.IllegalComponentStateException: The frame is decorated
at java.desktop/java.awt.Frame.setBackground(Frame.java:989)
You'll find that it's impossible to make a frame transparent AND be decorated...
#Override
public void setBackground(Color bgColor) {
synchronized (getTreeLock()) {
if ((bgColor != null) && (bgColor.getAlpha() < 255) && !isUndecorated()) {
throw new IllegalComponentStateException("The frame is decorated");
}
super.setBackground(bgColor);
}
}
The fact that the tutorials show it working is irrelevant and an error on the part of the tutorials.
It "might" have been possible in earlier "unreleased" versions of the API (using AWTUtilities), but it simply no longer possible
Now, we've got that out the way, this, inside paint...
try {
Thread.sleep(14);
} catch (Exception ex) {
};
x -= 1;
if (x == -10 * string.length()) {
x = 510;
}
repaint();
is not how you do animation in Swing
This is just going to cause you no end of issues, as nothing is committed to the native peer until AFTER the paintComponent exist (this is how double buffering works)
See Concurrency in Swing for more details.
A more appropriate solution might look something like...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Textmovie extends JFrame {
public static void main(String[] args) {
new Textmovie();
}
public Textmovie() throws HeadlessException {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame jf = new JFrame("");
jf.setUndecorated(true);
jf.setBackground(new Color(0, 0, 0, 10));
//jf.setOpacity(0.55f);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.add(new texscroll());
jf.pack();
jf.setLocationRelativeTo(null);
jf.setVisible(true);
}
});
}
public static class texscroll extends JPanel {
private int x = 510, y = 25;
private String string = "stackoverflow stackoverflow stackoverflow stackoverflow";
public texscroll() {
Font font = new Font("Arial", Font.BOLD + Font.PLAIN, 15);
setFont(font);
setForeground(Color.BLACK);
setOpaque(false);
Timer timer = new Timer(14, new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
x -= 1;
if (x == -10 * string.length()) {
x = 510;
}
repaint();
}
});
timer.start();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(720, 480);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g); //To change body of generated methods, choose Tools | Templates.
Graphics2D g2 = (Graphics2D) g;
g2.drawString(string, x, y);
}
}
}
See How to Use Swing Timers for more details
jf.setUndecorated(true);
makes the title bar invisible and that includes the minimize and close buttons so you should remove that line (because it's false by default)
It’s because you’re calling jf.setUndecorated(true). This method removes the the title bar, which contains the minimize and maximize buttons.
Unfortunately, the window have to be undecorated to have a system title bar, but the look and feel can provide a title bar. To enable it, you have to call this before your frame is made visible:
JFrame.setDefaultLookAndFeelDecorated(true);
I wanted to create a JFrame and put a sequence of images for animation in there. But the images don't appear in the frame window. I just want basic troubleshooting tips to make it appear in the window. Just edit the code for an answer if you can.
My question:
Why isn't the window displaying any pictures? It shows a window with a background color of blue, but that's it. Please tell me an efficient way to store images in variables and display it in a loop.
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.io.*;
public class Game extends JLabel implements ActionListener{
/**
*
*/
private static final long serialVersionUID = 1L;
public static Game blah;
BufferedImage nekopics[] = new BufferedImage[7];
BufferedImage currentimg;
public String nekosrcs[];
int xpos;
Timer timer;
public Game() throws IOException
{
JFrame jframe = new JFrame();
nekosrcs = new String[] { "walk1.png", "walk2.png",
"walk3.png", "walk4.png", "walk5.png",
"walk6.png"};
jframe.setTitle("Game");
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jframe.setLayout(new FlowLayout());
jframe.setSize(400, 400);
jframe.setResizable(false);
jframe.setVisible(true);
jframe.getContentPane().setBackground(Color.BLUE);
for (int i=0; i < nekopics.length; i++) {
nekopics[i] = ImageIO.read(new FileInputStream("D:/Programs
/pics"+nekosrcs[i]));
}
for (int i=0; i < nekopics.length; i++) {
timer = new Timer(1000, this);
timer.setInitialDelay(0);
timer.start();
currentimg = nekopics[i];
repaint();
}
}
public void paintComponent(Graphics g)
{
super.paint(g);
g.drawImage(currentimg,100,100,this);
}
public static void main(String[] args) throws IOException {
blah = new Game();
}
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
}
Alright, there are a lot of problems in your code, let's step into each of them:
You have a lot of spaces between lines, that makes your code a lot larger and harder to read
You haven't indented your code correctly (see the last } on your code, it's at the same level than the others; your for loops, etc), it makes the code so much harder to read and understand as well
You're creating a JFrame but extending JLabel, I'm not sure why you're doing this, if you're doing it so you can use the paintComponent() method, it's not necessary, on my code you can see how you can do it w/o extending any Component
If you haven't read the Swing Timer docs you should click that link and read what the ActionListener parameter does. In this case, we're going to use this listener to call the repaint() method and update our currentImage (or nextImage in the code below) and change the image accordingly. You failed to do this.
You were creating more than 1 Timer too, you created 6 here! All of them new but they had no action to do when the time finished
for (int i=0; i < nekopics.length; i++) {
timer = new Timer(1000, this);
timer.setInitialDelay(0);
timer.start();
currentimg = nekopics[i];
repaint();
}
You're changing unnecessarily the visibility of the paintComponent() method to public from protected
However I want to congratulate you for not using a null layout and following the recommendations I made on the comments above.
And finally the code that changes one image for another inside a Timer is the following, you can copy-paste it and change the image's names so you can see how it works.
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileInputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class ImageSequence {
private JFrame frame;
private JPanel pane;
private Timer timer;
private int nextImage = 0;
private String[] images = {"tokyo", "tokyo2", "starwars"};
private Image img = null;
public static void main (String args[]) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new ImageSequence().createAndShowGui();
}
});
}
public void createAndShowGui() {
frame = new JFrame("Image Sequence");
timer = new Timer(1000, listener);
pane = new JPanel() {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
try {
img = ImageIO.read(new FileInputStream("/home/jesus/Pictures/" + images[nextImage] + ".jpg"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
g.drawImage(img , 0, 0, 200, 200, this);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
};
timer.start();
frame.getContentPane().add(pane);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
ActionListener listener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
System.out.println(nextImage);
nextImage = nextImage < images.length - 1 ? nextImage + 1 : 0;
System.out.println(nextImage);
pane.repaint();
}
};
}
1.I am making a cookie click clone i know so mature I'm only 12 and I'm testing my abilities. I have a problem I'm trying to get a label to update but it just won't
tried everything
Also sorry in advance for weird indentation and messiness I'm not great at making good looking code
class
package learning;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.*;
import javax.swing.JPanel;
public class Learning extends JFrame implements MouseListener {
int clicks;
boolean Update;
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
new Learning().start();
}
public void start(){
ImageImplement panel = new ImageImplement(new ImageIcon("Cookie.jpg").getImage());
add(panel);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
setSize(600,600);
setResizable(false);
JLabel Click = new JLabel("Clicks: " + clicks);
Click.setFont(new Font("Arial",Font.PLAIN , 20));
panel.add(Click);
Click.setSize(100,100);
Click.setVisible(true);
addMouseListener(this);
if(Update == true){
Click.setText("Clicks: "+ clicks);
System.out.println("Reached");
}
}
#Override
public void mouseClicked(MouseEvent e) {
clicks += 1;
System.out.println(clicks);
Update = true;
if(Update = true){
Update = false;
}
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
}
Other picture class
package learning;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.JPanel;
class ImageImplement extends JPanel {
private Image img;
public ImageImplement(Image img) {
this.img = img;
Dimension size = new Dimension(img.getWidth(null), img.getHeight(null));
setPreferredSize(size);
setMinimumSize(size);
setMaximumSize(size);
setSize(size);
setLayout(null);
}
#Override
public void paintComponent(Graphics g){
g.drawImage(img, 0, 0, getWidth(), getHeight(), null);
}
}
Problem #1
Swing, like most GUI's, is event driven, that is something happens and you respond to it. This makes your program non-linear (the code doesn't progress in a straight line).
Events can happen at any time for a multitude of reasons, depending on the event. This means...
if(Update == true){
Click.setText("Clicks: "+ clicks);
System.out.println("Reached");
}
Will never be true, because the event has not occurred at the time the program interprets this command
Problem #2
To over come this issue, your mouseClicked event handler will need to know about the objects you want to update. Currently, you are declaring your variables within a local scope, within the start method...
public void start(){
//...
ImageImplement panel = new ImageImplement(new ImageIcon("Cookie.jpg").getImage());
//...
JLabel Click = new JLabel("Clicks: " + clicks);
}
You will need to change these so that they are accessible at a class instance level
public class Learning extends JFrame implements MouseListener {
int clicks;
boolean Update;
private ImageImplement panel;
private JLabel Click
public void start(){
//...
//ImageImplement panel = new ImageImplement(new ImageIcon("Cookie.jpg").getImage());
panel = new ImageImplement(new ImageIcon("Cookie.jpg").getImage());
//...
//JLabel Click = new JLabel("Clicks: " + clicks);
Click = new JLabel("Clicks: " + clicks);
}
This will allow you to access these objects from any method within any instance of the current class.
Then, within your mouseClicked handler, you can update the Click label...
#Override
public void mouseClicked(MouseEvent e) {
clicks += 1;
Click.setText("Clicks: "+ clicks);
}
Problem #3
Mouse events are contextual to the component that the MouseListener is registered. This means a few things, but in your case, it's possible that the JLabel and ImageImplement could potentially block block mouse events from reaching the component that the MouseListener is registered to.
Instead, it might be better to add the MouseListener to the ImageImplement instead...
addMouseListener(panel);
Additional
JLabel is capable of displaying images, unless you're playing on doing some kind of image manipulation or graphical effect, it might just be easier to use it instead.
You should be calling super.paintComponent in your ImageImplement's paintComponent before doing any additional painting.
You should avoid using setPreferred/Minimum/MaximumSize and instead, override these methods as you need to achieve your desired results
My program uses a Jframe, whenever I minimize the window and bring it back up, the program runs itself again. How can I cause it to not do this when minimized?
Code:
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.io.*;
import javax.imageio.*;
import javax.swing.*;
import java.util.Random;
public class AB extends Component {
public void paint(Graphics g) {
Random r = new Random();
g.setColor(Color.black);
g.fillRect(r.nextInt(100), r.nextInt(100), 100, 100);
}
public static void main(String[] args) {
JFrame f = new JFrame("Load Image Sample");
f.getContentPane().setBackground(Color.white);
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
f.setSize(dim.width, dim.height);
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
f.add(new AB());
f.setVisible(true);
}
}
My guess: you have program logic present in your paint(...) or paintComponent(...) method override. If so, get the logic out of these methods, because as you're finding out, you do not have full control over when or even if they are called. The logic belongs elsewhere, perhaps in a Swing Timer, hard to say without code or a more detailed question.
If this doesn't help, then you'll need to show us the bugs in your code by creating and posting a minimal, runnable, example program as well as tell us more of the details of your program and its misbehavior.
After looking at your code, I see that my assumption/guess was correct: you are selecting your random numbers inside of the paint method, and so they will change with each repaint. You will want to
Create a class that extends JPanel.
Create your random numbers in this class's constructor, and use the random numbers to set class instance fields.
Override this class's paintComponent method
Don't forget to call the super's paintComponent method inside this method.
Use the numbers generated in the constructor in the paintComponent method override to draw your rectangle.
Place your JPanel into a JFrame.
e.g.,
import java.awt.Color;
import java.awt.Graphics;
import java.util.Random;
import javax.swing.*;
#SuppressWarnings("serial")
public class RandomRect extends JPanel {
private static final int MAX_INT = 100;
private static final Color RECT_COLOR = Color.black;
private Random random = new Random();
private int randomX;
private int randomY;
public RandomRect() {
randomX = random.nextInt(MAX_INT);
randomY = random.nextInt(MAX_INT);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(RECT_COLOR);
g.fillRect(randomX, randomY, MAX_INT, MAX_INT);
}
private static void createAndShowGui() {
JFrame frame = new JFrame("RandomRect");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new RandomRect());
//frame.pack();
// frame.setLocationRelativeTo(null);
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
I am placing two images. One is supposed to be the background picture and the other one a picture of a stick-figure. I'd like to get the stick figure in front of the background. I can accomplish this by inserting the code to put the background picture after the code to display the stick figure. I was wondering if there was anyway to accomplish the same thing, by inserting the stick figure code after the background code, so I could keep placing new JLabels on top of the background.
The code that works:
guy.setBounds(0,0,100,100);
panel.add(guy);
backgroundPic.setBounds(0,0,550,550);
panel.add(backgroundPic);
setVisible(true);
The code that I'd like to work:
backgroundPic.setBounds(0,0,550,550);
panel.add(backgroundPic);
guy.setBounds(0,0,100,100);
panel.add(guy);
setVisible(true);
If you are only worrying about one background image, then I would suggest to extend JPanel, override paintComponent and paint the background image.
If you have to care about the Z-order of several components, then JLayeredPane is your best alternative.
Here is a small snippet showing the first option:
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.net.MalformedURLException;
import java.net.URL;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Test2 {
private static class PanelWithBackground extends JPanel {
private Image backgroundImage;
private Point backgroundLocation = new Point();
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (getBackgroundImage() != null) {
g.drawImage(getBackgroundImage(), backgroundLocation.x, backgroundLocation.y, this);
}
}
public Image getBackgroundImage() {
return backgroundImage;
}
public void setBackgroundImage(Image backgroundImage) {
this.backgroundImage = backgroundImage;
repaint();
}
public Point getBackgroundLocation() {
return backgroundLocation;
}
public void setBackgroundLocation(Point backgroundLocation) {
this.backgroundLocation = backgroundLocation;
repaint();
}
}
protected static void initUI() throws MalformedURLException {
JFrame frame = new JFrame("test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
PanelWithBackground panelWithBackground = new PanelWithBackground();
panelWithBackground.setLayout(null);
panelWithBackground.setBackgroundImage(new ImageIcon(new URL(
"http://2.bp.blogspot.com/-PqKuKt5mRmc/Tvi-K-4FVVI/AAAAAAAACKg/YwzkME5gGvk/s1600/black+background.jpg")).getImage());
JLabel guy = new JLabel(new ImageIcon(new URL(
"http://www.clipproject.info/Cliparts_Free/Menschen_Free/Clipart-Cartoon-Design-04.gif")));
// Next 2 lines should rather be performed by a LayoutManager
panelWithBackground.setPreferredSize(new Dimension(1024, 768));
guy.setBounds(50, 200, guy.getPreferredSize().width, guy.getPreferredSize().height);
panelWithBackground.add(guy);
frame.add(panelWithBackground);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
try {
initUI();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
}
You can use the Z order, to indicate the order the components should be rendered:
java.awt.Container.getComponentZOrder(Component)
According documentation:
Returns the z-order index of the component inside the container. The
higher a component is in the z-order hierarchy, the lower its index.
The component with the lowest z-order index is painted last, above all
other child components.
Parameters: comp the component being queried
Returns: the z-order
index of the component; otherwise returns -1 if the component is null
or doesn't belong to the container
I wont claim to be a java expert nor will i claim this is correct, just a guess, but try and remove the
.setBounds()
and if that has no effect, try using
.setSize()
best of luck :)