In the overridden function for my JFrame:
#Override
protected void paintComponent(Graphics g) {
BufferedImage imagePerson;
try {
imagePerson = ImageIO.read(new File("errol.gif"));
} catch (IOException e) {
imagePerson = null;
}
g.drawImage(imagePerson, i * increment, j * increment - 1, null);
}
How can I change this so the animation on the gif is shown (without using threading). I have spent many hours trying to get this to work but to no avail.
You could use an ImageIcon for this purpose. Have a look here and here. If you need the animation on a JPanel, simply add a JLabel (with the ImageIcon) to the panel.
Check this example for displaying an animated gif in Swing. you dont have to use any threads:
Icon imgIcon = new ImageIcon(this.getClass().getResource("ajax-loader.gif"));
JLabel label = new JLabel(imgIcon);
label.setBounds(668, 43, 46, 14); // for example, you can use your own values
frame.getContentPane().add(label);
Source
Related
I am writing a program that consists of three different panels.
This is part of my bottom panel. I display an image using BufferedImage, and I would like to create some text that will appear around 350px into the image, and 15px down. I cannot manage to get this to work and overlay over the bufferedImage.
My current code is as follows (For the bottom panel):
public class BtmPanel extends JPanel {
BtmPanel(){
try {
JLabel imgLabel = new JLabel();
final BufferedImage img = ImageIO.read(new File("image.png"));
ImageIcon icon = new ImageIcon(img);
imgLabel.setIcon(icon);
this.add(imgLabel);
}
catch(IOException ie){
System.out.println("image does not exist");
}
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawString("Y: " + MiddlePanel.y ,350,15);
}
}
There are a couple of ways you might achieve this, depending on your needs and desires.
For example, rather than using a JLabel to display the image, you could paint it directly yourself, for example...
public class BtmPanel extends JPanel {
private BufferedImage image;
BtmPanel(){
try {
image = ImageIO.read(new File("image.png"));
}
catch(IOException ie){
System.out.println("image does not exist");
}
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (image != null) {
g.drawImage(0, 0, image, this);
}
g.drawString("Y: " + MiddlePanel.y ,350,15);
}
}
The reason for doing it this way is you don't (really) control the placement of the image within a JLabel (lots of things can affect it's positioning).
Another solution would be to draw the text directly onto the BufferedImage itself. Which you would use would depend on how dynamic the text might be and a bunch of other factors
A way to do this is doing the exact inverse of your example, overriding the JPanel's paint method painting a BufferedImage (creating a background with your image), and then you can normally add the JLabel with text on your JPanel extension.
Please note that if JPanel is resized and you don't want to have a bad quality background, you'll have to manually create a resized version to adapt the container, or, at least, resize your buffered image with a little logic to keep Width/Height ratio... not that easy!
For the basic version you can try something like the following (taken from a working example) paintComponent overridden function:
#Override
protected void paintComponent(Graphics g) {
Image background = backgroundImage.getScaledInstance(this.getWidth(), this.getHeight(), Image.SCALE_DEFAULT);
super.paintComponent(g);
if (backgroundImage != null) {
g.drawImage(background, 0, 0, null);
}
}
Hope this helps ;)
I am trying to draw an image to a JPanel which in turn is added to a JFrame, see here:
JFrame screen;
public void welcome(){
screen = new JFrame("Welcome");
screen.setVisible(true);
screen.pack();
screen.setBackground(Color.darkGray);
screen.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
// in the original code there is series of methods here that eventually calls the drawBoard() method
public void drawBoard(){
try {
final BufferedImage gboard = ImageIO.read(new File("cutsomGameBoard.jpg"));
final BufferedImage featPanel = ImageIO.read(new File("extraPanel.png"));
board = new JPanel(){
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(gboard, 0, 0, this);
}
};
extra = new JPanel(){
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(featPanel, 0, 0, this);
}
};
board.setSize(480, 480);
extra.setSize(480, 320);
}
catch (IOException e) {
e.printStackTrace();
}
}
gameScreen.add(toolbar, BorderLayout.PAGE_START);
gameScreen.add(board, BorderLayout.EAST);
gameScreen.add(extra, BorderLayout.WEST);
gameScreen.setVisible(true);
screen.add(gameScreen);
}
My problem is that when running the code, only a small corner of the buffered image is visible and I am not sure if it is a problem with the frame layout, the panel size or the drawImage method arguments, ideas?
P.S. The output: screenshot of java window
You didn't override the getPreferredSize() method of your custom component so the default size is basically (10, 10) which is the size of a panel using a FlowLayout with no added components.
Don't use a JPanel to display an image. Or if you do want to use a JPanel then you need to implement the getPreferredSize() method to return the size of your image.
The easiest solution is to just use a JLabel with an ImageIcon.
Read the section from the Swing tutorial on How to Use Icons for more information and working examples.
I wrote a class that uses buttons to play radio stations broadcast to the internet.
When the buttons are pressed, I also wanted to have a series of images in the Frame selectively hidden and shown.
I am trying to do this by adding Images, setting "setVisible(false);" and then overriding the setVisible method when the button is clicked.
It isn't viable in it's current state. Is there a way to do this?
I'm pretty new to writing code.
public void actionPerformed(ActionEvent e)
{
JButton button = (JButton)e.getSource();
String text = button.getText();
JLabel img = new JLabel(new ImageIcon("resources/1920.png"));
img.setBounds(642, 230, 100, 100); // x, y, width, height
add(img);
img.setVisible(false);
if (text.equals("1920a"))
{
try
{
getMediaPlayer().setURI(mediaPaths[0]);
img.setVisible(true);
}
catch (URISyntaxException e1)
{
e1.printStackTrace();
}
Each time you press the button, you are creating a new instance of a JLabel and adding it to the screen, but you're not keeping track of them...
// Yet ANOTHER label...which one it is, nobody knows...
JLabel img = new JLabel(new ImageIcon("resources/1920.png"));
img.setBounds(642, 230, 100, 100); // x, y, width, height
add(img);
img.setVisible(false);
If you only want a single image on the screen at a time, then simply change the icon label of a single label...
Start by declaring an instance field for the pictures...
public class ... {
//...
private JLabel pictureLabel;
Add the label to the screen...
public ... { // Public constructor
//...
pictureLabel = new JLabel();
add(pictureLabel);
Now, when you want to change the picture, simply change the icon property of the label...
pictureLabel.setIcon(new ImageIcon("resources/1920.png"));
I have a GUI with a created JPanel and a "Start" button. All I need is when I click "Start", an image will be loaded and appear on that JPanel.
But my problem is when I click "Start", nothing happens.
Can anyone help me fix this problem?
Here is my code:
private BufferedImage image;
public class ImagePanel extends JPanel {
public ImagePanel() {
try {
image = ImageIO.read(new File("C:\\Users\\HienTran\\Desktop\\Miranda-Kerr-16-240x320.jpg"));
} catch (IOException ex) {
// handle exception...
}
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, null);
}
}
private void startBtnActionPerformed(java.awt.event.ActionEvent evt) {
stopBtn.setEnabled(true);
startBtn.setEnabled(false);
imageArea.add(new ImagePanel()); // imageArea is the JPanel in the GUI
}
When I replace 2 lines of imageArea by creating a new JFrame as below, that JFrame shows up with the image I added.
private void startBtnActionPerformed(java.awt.event.ActionEvent evt) {
stopBtn.setEnabled(true);
startBtn.setEnabled(false);
JFrame test = new JFrame("Window");
test.add(new ImagePanel());
test.setSize(image.getWidth(), image.getHeight() + 30);
test.setVisible(true);
}
When you add components to a visible GUI the basic code is:
panel.add(...);
panel.revalidate();
panel.repaint();
However, that probably won't help because by default a JPanel uses a FlowLayout and a FlowLayout respects the size of the component. Your ImagePanel will have a size of (0, 0) since you did not override the getPreferredSize() method.
There is no need to create a custom panel to paint your image. Just use a JLabel with an Icon then you let the label worry about the size. Don't reinvent the wheel.
I suggest you read the Swing tutorial for the basics. Maybe the section on How to Use Labels would be a good place to start. The tutorial will also show you a better way to design your class wo that you follow Swing guidelines.
First fix a bit:
try {
image = ImageIO.read(new File("C:\\Users\\HienTran\\Desktop\\Miranda-Kerr-16-240x320.jpg"));
} catch (IOException ex) {
ex.printStacktrace(); // see if there is an exception, like not finding or something
}
than:
If you add a panel, than need a layout refresh and a gui refresh:
imageArea.add(new ImagePanel());
imageArea.revalidate(); // refresh layout
imageArea.repaint(); // shedule painting
Is it possible to overlay a Button over a Label in Swing?
For example, if have a JLabel with image and no text, and i want to overlay my button over this JLabel. Label is defined something like:
myLabel = new javax.swing.JLabel(new ImageIcon( myPicture ));
If not, then any ideas how can i realize this, thank you.
EDIT: Actually i read about adding JPanel to a JLabel, when i add a Panel with button layout, it compiles fine but nothing is visible, just the JLabel with image
UPDATE: As suggested by #paranoid-android, somehow i have solved my problem. However i still have to know how can i customize the positions of components overlayed on top of JLabel as i don't have much control (probably because normally i use netbeans for drawing layouts, and this would require hard coding).
Something Like this worked:
ImagePanel(Image image, int id) {
this.image = image;
this.tile = false;
JButton backButton = new JButton();
JButton nextButton = new JButton();
backButton.setText(" BACK ");
nextButton.setText(" NEXT ");
add(backButton);
add(nextButton);
};
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, getWidth(), getHeight(), this);
}
You can do it using a JLayeredPane, although if I understand correctly, the absolute best way to do that would be to override paintComponent:
// as part of your JPanel
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g.drawImage(background, 0, 0, this);
}
Then you can add components to the panel as you like, without the need for the JLabel.
You can overlap the button and the label, but you would have to do this with a Fixed Layout. You might be able to pull if off with a gridBagLayout, but I doubt it.
Here is more on what you will need.
http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html
Thanks rtheunissen.
That did the trick for me.
I modified it a little.
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g); //To change body of generated methods, choose Tools | Templates.
try {
ImageIcon icon = new ImageIcon(getClass().getClassLoader().getResource("img/lake.jpeg"));
g.drawImage(icon.getImage(),0,0,this);
} catch (Exception ex) {
Logger.getLogger(InfoPanel.class.getName()).log(Level.SEVERE, null, ex);
}
}