【问题标题】:Loading image in Java Code from C drive从 C 盘加载 Java 代码中的图像
【发布时间】:2012-11-05 18:12:57
【问题描述】:

我是 Java 新手。我只是想在JFrame 中加载图像作为背景。我想做的是从 C 驱动器(那不是我的工作区)获取图像,所以我在 Board.java 中做了什么:

   ImageIcon i = new ImageIcon("C:/image.png");
   img =i.getImage();

并尝试将其画成这样:

    public void paint(Graphics g )
    { 
    super.paint(g);
    Graphics2D  g2d= (Graphics2D) g;
    g2d.drawImage(img, 0, 100, null);
    }

然后我像这样调用我的主类

   public static void main(String[] args) 
   {
    JFrame frame= new JFrame(" Game") ;
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(1200, 365);
    frame.setVisible(true);
    frame.add(new Board());

   }

但我没有显示任何图像,所以添加Image 是否合法?

【问题讨论】:

  • 当你调试 ImageIcon 里面的内容时?
  • 我已经提到了 image.png 的路径,直接来自 c 驱动器,如果可能的话,这就是我想要做的。
  • 如果是windows,不应该是ImageIcon i = new ImageIcon("C:\1.png");吗? (反斜杠而不是正斜杠)
  • @sampson-chen :无论如何,它应该是 "C:\\1.png" 。但这不是问题,“C:/image.png”应该可以正常工作
  • 我都试过了,都没有工作,我确实按照教程说明进行了编码,没有错误但加载图像时出现问题,当编译没有图像时

标签: java image swing jframe


【解决方案1】:
  • 不要在JFrame 中覆盖paint()
  • 不要在JFrame 上调用setSize(),而是在设置可见之前使用JFrame#pack()
  • 养成使用 / 的习惯,无论平台是否支持。

这是我做的一个例子:

  • 创建JPanel/JLabel实例
  • JPanel/JLabel 中覆盖paintComponent(..)
  • 覆盖getPreferredSize() 以将尺寸正确的尺寸/组件返回为Image
  • JPanel/Jlabel 添加到JFrame 实例
  • 通过JFrame#pack()打包JFrame
  • 设置JFrame可见

Test.java:

//necessary imports
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

    static String filename = "c:/test.jpg";//your file path and name here use / as it will work on linux platforms too so get into the habbit

    /**
     * Default constructor
     */
    public Test() throws Exception {
        initComponents();
    }

    /**
     * Initialize GUI and components (including ActionListeners etc)
     */
    private void initComponents() throws Exception {
        JFrame frame = new JFrame("Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        final Image background = ImageIO.read(new File(filename));
        final Dimension jpanelDimensions = new Dimension(new ImageIcon(background).getIconWidth(), new ImageIcon(background).getIconHeight());

        frame.add(new JPanel() {
            @Override
            protected void paintComponent(Graphics grphcs) {
                super.paintComponent(grphcs);
                grphcs.drawImage(background, 0, 0, null);
            }

            //return a JPanel that matches images size
            @Override
            public Dimension getPreferredSize() {
                return jpanelDimensions;
            }
        });

        frame.setResizable(false);

        //pack frame (size JFrame to match preferred sizes of added components and set visible
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {

        /**
         * Create GUI and components on Event-Dispatch-Thread
         */
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    //set nimbus look and feel
                    for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                        if ("Nimbus".equals(info.getName())) {
                            UIManager.setLookAndFeel(info.getClassName());
                            break;
                        }
                    }
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) {
                    e.printStackTrace();
                }
                try {
                    //create GUI instance
                    Test test = new Test();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        });
    }
}

【讨论】:

  • 非常好的例子。 +1 建议。
【解决方案2】:

改用此格式位置

C:\\1.png

【讨论】:

  • -1:不!在 Windows 上只有 cmd.exe 需要 \,该 API 与 / 配合得很好
  • @abhishekkumar,由于转义序列,\\ 被翻译为 \。
  • 我将其更改为 / 而不是 \ 并加载了图像,
  • 总是使用/,只有cmd.exe需要\\
【解决方案3】:

对于 Swing,您必须使用 paintComponent() 代替 paint()。

【讨论】:

  • 但是没有任何图像,请您检查上述代码并告诉我问题。
  • JFrame 没有 paintComponent(Graphics) 方法,OP 可以(并且应该)使用 @Override 表示法确认。这就是为什么大多数使用过 Swing 的人会建议不要直接在顶级容器上绘制,而是向其中添加自定义面板并从那里获取的原因之一。
  • Board.java 不继承自 JFrame。参见 frame.add(board)
【解决方案4】:

在您的代码中:

frame.add(new Board());移动到frame.setVisible(true);之前,即:

另外,添加frame.pack();

public static void main(String[] args) 
{
    JFrame frame= new JFrame("Game") ;
    frame.add(new Board());
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(1200, 365);
    frame.pack();
    frame.setVisible(true);
}

一旦 JFrame 设置为可见,则应该只有事件调度线程才能触摸它。

作为旁注,请覆盖 paintComponent() 而不是 paint(),除非您确切知道自己在做什么:http://docs.oracle.com/javase/tutorial/uiswing/painting/closer.html

要点是 paint() 实际上负责调用以下内容:paintComponent()paintBorder()paintChildren()。所以如果你只是盲目地覆盖paint(),它会以你不希望的方式改变你的组件的行为。

【讨论】:

  • 确实不应该在同一个JFrame 实例上调用setSize()pack()。此外,所有 Swing 组件都应通过 SwingUtilities.invokeXXXEvent Dispatch Thread 中创建和更改
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-23
  • 1970-01-01
  • 2016-07-27
  • 1970-01-01
  • 2013-02-06
相关资源
最近更新 更多