使用JPanel扩展类设置背景

时间:2014-07-17 15:39:25

标签: java swing jpanel drawimage

在我的Main我想要创建JFrame,然后我想创建一个BackgroundPanel,我想在JFrame中添加这个。

这是主要类:

public class Main {

    public static void main(String args[]) {
        Frame frame = new Frame();
        BackgroundPanel back = new BackgroundPanel();
        frame.getContentPane().add(back);
        frame.setSize(400, 287);
        frame.setVisible(true);
    }
}

这是 BackgroundPanel 类:

import java.awt.Graphics;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class BackgroundPanel extends JPanel {

    private Image img;

    public BackgroundPanel() {
        img = Toolkit.getDefaultToolkit().createImage(getClass().getResource("sfondo.png"));
        loadImage(img);
    }

    private void loadImage(Image img) {
        try {
            MediaTracker track = new MediaTracker(this);
            track.addImage(img, 0);
            track.waitForID(0);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        setOpaque(false);
        g.drawImage(img, 0, 0, null);
    }
}

JFrame是正常的JFrame类。

当我执行它时,没有错误,只是它没有背景就发出了正常的JFrame。 请帮帮我!

@nIcEcOw我使用第一个answear中的代码在JPanel上打印我的图像。但是当我执行它时,输出会出错。

这个错误:

Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: input == null!
    at javax.imageio.ImageIO.read(ImageIO.java:1388)
    at paintingexample.CustomPanel.<init>(PaintingExample.java:82)
    at paintingexample.PaintingExample.displayGUI(PaintingExample.java:28)
    at paintingexample.PaintingExample.access$000(PaintingExample.java:19)
    at paintingexample.PaintingExample$1.run(PaintingExample.java:42)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:312)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:733)
    at java.awt.EventQueue.access$200(EventQueue.java:103)
    at java.awt.EventQueue$3.run(EventQueue.java:694)
    at java.awt.EventQueue$3.run(EventQueue.java:692)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:703)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
BUILD SUCCESSFUL (total time: 1 second)

我对项目的结构感到困惑。 我注意到我无法将包文件夹放在bin目录中;这在我的想法中造成了冲突。 我不明白我如何将java文件放在src和bin文件夹中的bin文件夹中。 我的java文件在包文件夹中。我可以这样做吗?

我正在使用NetBeans IDE 8.0

我是红色NetBeans的图像导入教程,还提示我创建另一个包来导入图像。 现在我的代码是:

import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;

public class PaintingExample {

    private ImagePanel imagePanel;

    public void displayGUI() {
        JFrame frame = new JFrame("Swing Worker Example");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        JPanel contentPane = new JPanel();
        imagePanel = new ImagePanel();      
        contentPane.add(imagePanel);

        frame.setContentPane(contentPane);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

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


class ImagePanel extends JPanel {

    private ImageIcon imageIcon;

    public ImagePanel() {
        imageIcon = new javax.swing.ImageIcon(getClass().getResource("/org/me/myimageapp/newpackage/Schema elettrico divella rev 2014-Model.jpg"));
    }

    @Override
    public Dimension getPreferredSize() {
        return (imageIcon == null ? new Dimension(100, 100): new Dimension(
                                                   imageIcon.getIconWidth(), imageIcon.getIconHeight()));
    }

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

我改变了:

imageIcon = new ImageIcon(ImageIO.read(ImagePanel.class.getResource(
                                                    "/images/aeroplaneright.jpeg")));

imageIcon = new javax.swing.ImageIcon(getClass().getResource("/org/me/myimageapp/newpackage/aeroplaneright.jpg"));

@nIcEcOw你是我的英雄! :d 现在一切正常。 但只是另一件事:

现在我在一个更大的项目中使用你的ImagePanel类。 我还在项目的Main类中使用部分SwingTest代码来创建具有ImagePanel背景的自定义jframe类(FramePrincipale)的框架。当我执行我的bakcground获取一个框架,但是没有其他的swing元素(标签,textfields ..)是我定制的jframe的一部分。 我该如何解决这个问题?

这是Principale类(主项目类):

import java.awt.EventQueue;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.JPanel;


public class Principale {


    private ImagePanel imagePanel;
    private static FramePrincipale frame = new FramePrincipale();

    private void displayGUI() throws IOException {





        JPanel contentPane = new JPanel();
        imagePanel = new ImagePanel();      
        contentPane.add(imagePanel);

        frame.setContentPane(contentPane);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }



    public static void main(String[] args) {



        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                try {
                    new Principale().displayGUI();
                } catch (IOException ex) {
                    Logger.getLogger(Principale.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        };
        EventQueue.invokeLater(runnable);

  while (true) {


      frame.scriviLabel();


    }     

    }

}

FramePrincipale是一个位于同一项目中的JFrame表单。

@nIcEcOw:现在可以了!谢谢所有人! : - )

2 个答案:

答案 0 :(得分:2)

考虑到项目的目录结构如下所示:

 Since Images are Application Resources,
 it's always best to access them in the
 form of a URL, instead of File, as you are doing.
 Uncomment this below line and watch this answer
 of mine, as to HOW TO ADD IMAGES TO THE PROJECT
 https://stackoverflow.com/a/9866659/1057230
 In order to access images with getClass().getResource(path)
 here your Directory structure has to be like this
                 Project
                    |
         ------------------------
         |                      |
        bin                    src
         |                      |
     ---------             .java files             
     |       |                   
  package   images(folder)
  ( or              |
   .class        404error.jpg
   files, if
   no package
   exists.)

PaintingExample

import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;

public class PaintingExample {

    private ImagePanel imagePanel;

    private void displayGUI() {
        JFrame frame = new JFrame("Swing Worker Example");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        JPanel contentPane = new JPanel();
        imagePanel = new ImagePanel();      
        contentPane.add(imagePanel);

        frame.setContentPane(contentPane);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

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

class ImagePanel extends JPanel {

    private ImageIcon imageIcon;

    public ImagePanel() {
        try {
            imageIcon = new ImageIcon(ImageIO.read(ImagePanel.class.getResource(
                                                    "/images/aeroplaneright.jpeg")));
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }

    @Override
    public Dimension getPreferredSize() {
        return (imageIcon == null ? new Dimension(100, 100): new Dimension(
                                                   imageIcon.getIconWidth(), imageIcon.getIconHeight()));
    }

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

输出:

PAINTINGEXAMPLE

响应编辑

如编辑中所述,您使用了一些Integrated Development Environment - IDE来创建应用程序。因为,每个IDE使用的方式都有点不同。请参阅此帖子,如果add images to Java Project如何帮助您朝这个方向发展。

编辑NetBeans

  1. 创建Java项目
  2. 提供任何项目名称。就我而言,我正在使用 SwingTest 如图所示
  3. 提供包名称。就我而言,我正在使用 swingtest 如图所示
  4. 右键点击源包新 - &gt; Java包。下 新Java包窗口,提供包名称,在我的情况下,我使用的是图片
  5. 文件系统复制图像,然后返回 NetBeans IDE,右键单击已创建的 images 包并粘贴图像(在NetBeans IDE中)
  6. 通过右键单击 swingtest 包,新建 - &gt;创建两个类 Java Class ,其内容如下所示
  7. 就是这样,你现在已经完成了。运行项目,您就可以看到图像。请注意使用getClass().getResource(...) thingy:

    imageIcon = new ImageIcon(ImageIO.read(ImagePanel.class.getResource(
                                                        "/images/loyalperson.jpg")));
    

    SwingTest

    package swingtest;
    
    import java.awt.*;
    import javax.swing.*;
    
    public class SwingTest {
    
        private ImagePanel imagePanel;
    
        private void displayGUI() {
            JFrame frame = new JFrame("Swing Worker Example");
            frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    
            JPanel contentPane = new JPanel();
            imagePanel = new ImagePanel();      
            contentPane.add(imagePanel);
    
            frame.setContentPane(contentPane);
            frame.pack();
            frame.setLocationByPlatform(true);
            frame.setVisible(true);
        }
    
        public static void main(String[] args) {
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    new SwingTest().displayGUI();
                }
            };
            EventQueue.invokeLater(runnable);
        }
    }
    

    ImagePanel

    package swingtest;
    
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.io.IOException;
    import javax.imageio.ImageIO;
    import javax.swing.ImageIcon;
    import javax.swing.JPanel;
    
    public class ImagePanel extends JPanel {
    
        private ImageIcon imageIcon;
    
        public ImagePanel() {
            try {
                imageIcon = new ImageIcon(ImageIO.read(
                             ImagePanel.class.getResource("/images/loyalperson.jpg")));
            } catch (IOException ioe) {
                ioe.printStackTrace();
            }
        }
    
        @Override
        public Dimension getPreferredSize() {
            return (imageIcon == null ? new Dimension(100, 100): new Dimension(
                             imageIcon.getIconWidth(),imageIcon.getIconHeight()));
        }
    
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawImage(imageIcon.getImage(), 0, 0, this);
        }
    }
    

    图像步骤

    ProjectImages

    以下是loyalperson.jpg

    的链接

    编辑2:

    要添加自定义组件,请执行以下操作:

    1. 转到工具 - &gt;调色板 - &gt; Swing / AWT组件
    2. 点击新分类。在新调色板类别窗口中, 提供新类别名称
    3. 点击 确定 并关闭调色板管理器窗口
    4. 在编辑器中打开 ImagePanel ,现在选择源视图,现在 选择工具 - &gt;添加到调色板并选择类别 由你创造。
    5. 我想,会的。现在组件可以在上面看到 调色板窗口,在之前选择的类别下,可以拖放到JFrame / JComponent。

答案 1 :(得分:-1)

如果扩展JPanel为什么不在JPanel中覆盖paint方法然后使用图形 例如:g.drawImage(img,x,y,width,height,ImageObserver)?