简体   繁体   中英

Swing issues drawing 2 images

I'm trying to design a GUI using SWING.My problem is that I'm not sure how the paintComponent method works. I'm trying to display 2 images but only the one from PanClass is displayed.Here is the relevant code(2 classes) .

import javax.swing.*;
import java.io.*;
import java.awt.*;
import java.awt.image.*;
import javax.imageio.*;
import java.awt.Image;

public class LP3 extends JPanel
{
    public static BufferedImage image;
    public static BufferedImage image2;
    private JFrame frame=new JFrame();
    private PanClass Panel=new PanClass();

    public LP3()
    {
        try
        {               
            image2=ImageIO.read(new File("New Game.png"));     
        }
        catch (IOException e)
        {
            //Nothing
        }
        frame.setSize(1000,100);
        frame.setResizable(true);
        frame.add(Panel);
        Panel.setOpaque(true);
        frame.pack();
        frame.setVisible(true);     
    }

    public void paintComponent(Graphics g)
    {
        g.drawImage(image2,0,0,null);
    }
}

Class No2:

import javax.swing.*;
import java.io.*;
import java.awt.*;
import java.awt.image.*;
import javax.imageio.*;
import java.awt.Image;

public class PanClass extends JPanel
{
    private static BufferedImage theimage;
    private static BufferedImage image2;
    private JPanel a=new JPanel();

    public PanClass()
    {
        a.setLayout(null);
        a.setOpaque(true);
        try
        {                 
            theimage = ImageIO.read(new File(design4.jpg"));
        }
        catch (IOException e)
        {
            //Not handled.
        }
    }

    public void paintComponent(Graphics g)
    {
        g.drawImage(theimage,0,0,null);
    }
}

The code as it is now displays only the image from PanClass. If I get to add the drawing of both images to be done in the PanClass then both will be correctly drawn. I am interested in knowing why this happens as I'm more interested in learning how it works rather than getting the job done. Also If I create a JFrame and a JLayered Pane in a class, then create 2 more classes drawing an image with paintComponent() (using similar code to the above) and then add an instance of each class on the Layered Pane on a different Layer of the first class, why nothing is displayed?

(My main method is supposed to be on LP3 but I'm just using an IDE that allows you to call methods directly on instances without having a main method-used for learning)

You didn't add LP3 to the JFrame but only PanClass was added. So the LP3 's paintComponent() is not called.

You can add both component (may be define proper LayoutManager eg GridLayout ) to call both paintComponent()


Points you doing wrong in your program :

  • Naming Conventions used by you in your code, does not implies with Java. Please do refer to Java Naming Conventions for more info. Two easy things use Pascal Notions for Class Names and Camel notation for Variable Names.
  • Whenever one needs to override the method of the super class, it is BEST to keep the ACCESS SPECIFIER , the same, as much as possible. In your case, the Access Specifier for the paintComponent(...) method is protected and not public .
  • Especially while overriding paintComponent(...) , it is BEST to call super.paintComponent(...) , in the overridden method.
  • Inside your PanClass which extends JPanel you are creating a new JPanel a , which is not what you want, if you look closely. You want PanClass itself.
  • Make it a customary habit to override, the getPreferredSize() , of the JPanel/JComponent , when ever you are extending it to any class.
  • Always define the behaviour how the JFrame needs to go off, when the X Button is pressed. For more Info JFrame.setDefaultCloseOperation(...)
  • Whenever overriding a method of super class, its best to prefix it with an Annotations. More information on Java Annotation Tutorials
  • I hope after everything, a small information related to Concurrency in Swing , is worth mentioning :-)
  • Last but not the least, the answer is very much given by @StanislavL

Please consider this code for more reference :

import javax.swing.*;
import java.io.*;
import java.awt.*;
import java.awt.image.*;
import javax.imageio.*;
import java.awt.Image;
import java.net.URL;

public class LP3 extends JPanel
{
    public static BufferedImage image;
    public static BufferedImage image2;
    private JFrame frame = new JFrame();
    private PanClass panel = new PanClass();

    public LP3()
    {
        setOpaque(true);
        try
        {               
            image2=ImageIO.read(new URL(
                "https://encrypted-tbn1.gstatic.com/images?q=tbn:" + 
                "ANd9GcQCluuYpyVQYZuADHAYIfpkRO7SaWMn0OCM_nGH6Tr2SCFtGtE_"));     
        }
        catch (IOException e)
        {
            //Nothing
            e.printStackTrace();
        }           
    }

    @Override
    public Dimension getPreferredSize()
    {
        return (new Dimension(300, 300));
    }

    @Override
    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        g.drawImage(image2,0,0,this);
    }

    private void displayGUI()
    {
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.setResizable(true);
        JPanel contentPane = new JPanel();
        contentPane.setLayout(new GridLayout(0, 1, 5, 5));
        contentPane.add(panel);
        contentPane.add(this);
        frame.setContentPane(contentPane);
        frame.pack();
        frame.setVisible(true); 
    }

    public static void main(String[] args)
    {
        Runnable runnable = new Runnable()
        {
            @Override
            public void run()
            {
                new LP3().displayGUI();
            }
        };
        EventQueue.invokeLater(runnable);
    }
}

class PanClass extends JPanel
{
    private static BufferedImage theimage;
    private static BufferedImage image2;

    public PanClass()
    {
        setOpaque(true);
        try
        {                 
            theimage = ImageIO.read(
                new URL(
                    "https://encrypted-tbn0.gstatic.com/" + 
                    "images?q=tbn:ANd9GcR5PNwAcLVjphhST_" + 
                    "S-K_dU0CEAuXM0g4oc1-v1r-z5VJFuemOD"));
        }
        catch (IOException e)
        {
            //Not handled.
            e.printStackTrace();
        }
    }

    @Override
    public Dimension getPreferredSize()
    {
        return (new Dimension(300, 300));
    }

    @Override
    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        g.drawImage(theimage, 0, 0, this);
    }
}

EDIT : !

  • I forgot one very important point the previous time regarding your use of g.draw(...) , you using null for the ImageObserver part, which in this case is your JPanel and not null

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM