Graphics2D.drawImage()调用成功但JPanel上图像未显示的问题
JPanel绘制图像不显示问题排查
我正在开发一款类似Window Kill的游戏,需要在JPanel上绘制图像。通过System.out.println()可以确认图像绘制逻辑已经执行,而且线程中也调用了repaint()方法,但运行程序时图像始终无法显示。我试过在paintComponent()里绘制椭圆,椭圆能正常显示;也尝试用JLabel添加图像,同样没效果。相关代码如下:
package org.example.View.GamePagePanels; import org.example.Controller; import org.example.Location; import org.example.View.BossHeadView; import org.example.View.EntityView; import org.example.View.EpsilonView; import org.example.movement.EpsilonKeylistener; import javax.swing.*; import java.awt.*; import java.util.ArrayList; import java.util.UUID; public class BossHeadPanel extends JPanel { private boolean Isometric=false; private boolean isRigid=false; private String ID=""; public Thread thread; public boolean isIsometric() { return Isometric; } public void setIsometric(boolean isometric) { Isometric = isometric; } public boolean isRigid() { return isRigid; } public void setRigid(boolean rigid) { isRigid = rigid; } public String getID() { return ID; } public void setID(String ID) { this.ID = ID; } JLabel smiley; Image image; public BossHeadPanel() { setLayout(null); ID= UUID.randomUUID().toString(); setLayout(null); setFocusable(true); addKeyListener(EpsilonKeylistener.getEpsilonKeylistener()); setBackground(Color.black); setVisible(true); ImageIcon icon=new ImageIcon("src/main/resources/icons/boss.png"); image= icon.getImage(); smiley=new JLabel(); smiley.setIcon(icon); smiley.setBounds(0,0,100,100); smiley.setVisible(true); this.add(smiley); thread=new Thread(new Runnable() { @Override public void run() { while (Controller.isRunning){ ArrayList<EntityView> entities=EntityView.entityViews; for(int i=0;i< entities.size();i++){ EntityView ent=entities.get(i); if(isShowing()){ if ((ent.location.getX()>=getLocationOnScreen().getX() && ent.location.getX()<=getLocationOnScreen().getX()+getWidth() )|| ( ent.location.getY()>= getLocationOnScreen().getY() && ent.location.getY()<=getLocationOnScreen().getY()+getHeight())){ double x=ent.location.getX()-getLocationOnScreen().getX(); double y=ent.location.getY()-getLocationOnScreen().getY(); ent.panelLocations.put(getID(),new Location(x,y)); } } } if(isShowing()){ if((EpsilonView.getEpsilonView().getX()>=getLocationOnScreen().getX() && EpsilonView.getEpsilonView().getX()<=getLocationOnScreen().getX()+getWidth() )|| ( EpsilonView.getEpsilonView().getY()>= getLocationOnScreen().getY() && EpsilonView.getEpsilonView().getY()<=getLocationOnScreen().getY()+getHeight())){ double x=EpsilonView.getEpsilonView().getX()-getLocationOnScreen().getX(); double y=EpsilonView.getEpsilonView().getY()-getLocationOnScreen().getY(); EpsilonView.epsilonView.panelLocations.put(getID(),new Location(x,y)); } } try { Thread.sleep(10); } catch (InterruptedException e) { throw new RuntimeException(e); } repaint(); } } }); thread.start(); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2=(Graphics2D) g; g2.setColor(Color.green); g2.fillOval(0,0,20,20); if(image!=null){ g2.drawImage(image,0,0,100,100,this); System.out.println("image drawing"); }else{ System.out.println("the image doesn't load"); } } }
解决方法
修正资源加载路径
替换图片加载代码为类加载器方式,避免打包后路径失效:ImageIcon icon = new ImageIcon(getClass().getResource("/icons/boss.png"));确保
src/main/resources是项目的资源根目录,打包后icons/boss.png会在classpath根目录下。检查空布局的影响
空布局需要手动设置所有组件的尺寸和位置,确认JPanel本身的尺寸是否正确设置(比如通过setPreferredSize(new Dimension(xxx, xxx))),父容器是否正确布局这个JPanel。处理Swing线程安全
虽然repaint()是线程安全的,但如果后续有UI状态修改操作,建议用SwingUtilities.invokeLater()在EDT线程执行。另外,Controller.isRunning变量需要添加volatile修饰,确保线程能读取到最新值:public static volatile boolean isRunning = true;调整图像绘制坐标
考虑JPanel的内边距,避免图像被边框遮挡:@Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2=(Graphics2D) g; g2.setColor(Color.green); g2.fillOval(0,0,20,20); if(image!=null){ Insets insets = getInsets(); g2.drawImage(image, insets.left, insets.top, 100, 100, this); System.out.println("image drawing"); }else{ System.out.println("the image doesn't load"); } }
内容的提问来源于stack exchange,提问作者Howell
相关产品推荐
相关产品推荐

