2017-01-27 5 views
-3

Je l'ai essayé pendant des heures maintenant. J'ai une classe qui étend JComponent, et dans son paintComponent j'essaye de dessiner une image, mais je ne peux pas. Voici mon code:Comment afficher une image bufferedImage dans un composant JComponent?

public class Main extends JComponent{ 



public static void main(String[] args) { 

    Main main = new Main(); 

    JFrame frame = new JFrame(Info.getGameTitle()); 
    frame.add(main); 

    frame.setSize(Info.getWidth(), Info.getHeight()); 
    frame.setResizable(false); 

    frame.addWindowListener(new WindowAdapter(){ 
     public void windowClosing(WindowEvent e){ 
      System.out.println("Window closed"); 
      System.exit(0); 
     } 
    }); 

    frame.setAlwaysOnTop(true); 
    frame.setFocusable(true); 
    frame.setAutoRequestFocus(true); 
    frame.setLocationRelativeTo(null); 

    frame.setVisible(true); 

    Graphics g = main.getGraphics(); 

    main.paint(g); 


} 

public void paintComponent(Graphics g) { 
    super.paintComponent(g); 

    BufferedImage image = null; 
    try { 
     image = ImageIO.read(new FileInputStream("images/01.jpg")); 
    }catch(FileNotFoundException e) { 
     System.out.println("Could not find file!"); 
     e.printStackTrace(); 
    }catch(IOException e) { 
     System.out.println("Could not read file!"); 
     e.printStackTrace(); 
    } 

    g.drawImage(image, 0, 0, this); 


    } 
} 

Il n'y a aucune exception, donc l'image semble être chargée. Cependant, rien n'apparaît à l'écran. Si j'essaie de dessiner des formes ou du texte, cela fonctionne bien. Qu'est-ce que je fais de mal?

EDIT: Maintenant, j'ai fourni un exemple de travail.

+1

Envisager de fournir un [exemple runnable] (https://stackoverflow.com/help/mcve) ce qui démontre votre problème. Ce n'est pas un vidage de code, mais un exemple de ce que vous faites qui met en évidence le problème que vous rencontrez. Cela entraînera moins de confusion et de meilleures réponses. – MadProgrammer

+0

Sachez que 'paintComponent' sera appelé * très * souvent. Par conséquent, ce n'est pas une bonne idée de faire des choses qui prennent du temps (comme lire un fichier image) là –

+0

Quel est le problème avec un 'JLabel'? – MadProgrammer

Répondre

0

Essayez cette

BufferedImage image = null; 
    try { 
     image = ImageIO.read(new File(fullpathname+"/01.jpg")); 
    }catch(Exception e) { 
     System.out.println("Could not read file!"); 
     e.printStackTrace(); 
    } 

public void paintComponent(Graphics g) { 
    super.paintComponent(g); 


    g.drawImage(image, 0, 0, this); 


} 

lecture jette plus d'exceptions

IllegalArgumentException - if input is null. 
IOException - if an error occurs during reading. 

afin attrapant le plus général (exception) couvrira ce

+0

* "Il ne lance aucune exception" * - suggère que l'image a été chargée et que 'FileInputStream' fonctionne correctement - [' ImageIO.read (InputStream) '] (https://docs.oracle.com/javase /7/docs/api/javax/imageio/ImageIO.html#read(javax.imageio.stream.ImageInputStream)) – MadProgrammer

+0

"Il ne lance aucune exception" - suggère que l'image a été chargée: vérifiez vos papiers – gpasch

+0

pour m'éclairer sur ce point;) – MadProgrammer

0

Essayez ceci:

image image = ImageIO.read (nouveau fichier (fichier)); g.drawImage (image, 0, 0, this);

+0

Utiliser 'FileInputStream' fonctionne bien – MadProgrammer

1
Graphics g = main.getGraphics(); 
main.paint(g); 

Non, non, non, NO, NON! Un temps infini NON! Ce n'est pas comme ça que ça fonctionne!

Jetez un oeil à Performing Custom Painting et Painting in AWT and Swing pour une meilleure compréhension de la façon dont la peinture fonctionne dans Swing.

getGraphics peut retourner null et retournera uniquement le dernier contexte utilisé pour peindre le composant, tout ce qui y est peint sera effacé lors du prochain cycle de peinture.

Il n'y a jamais une bonne raison d'appeler manuellement paint, mais ne le faites pas.

Vous devriez être faire quelque chose de plus le long des lignes de

Example output

import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.image.BufferedImage; 
import java.io.FileInputStream; 
import java.io.IOException; 
import javax.imageio.ImageIO; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class Test { 

    public static void main(String[] args) { 
     new Test(); 
    } 

    public Test() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
        ex.printStackTrace(); 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     private BufferedImage img = null; 

     public TestPane() { 
      try { 
       img = ImageIO.read(new FileInputStream("...")); 
      } catch (IOException ex) { 
       ex.printStackTrace(); 
      } 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return img == null ? new Dimension(200, 200) : new Dimension(img.getWidth(), img.getHeight()); 
     } 

     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D) g.create(); 
      if (img != null) { 
       g2d.drawImage(img, 0, 0, this); 
      } 
      g2d.dispose(); 
     } 

    } 
} 

Si votre image est toujours montrer, je pense que l'image est mal placée.

new FileInputStream("images/01.jpg") 

suggère que l'image réside dans le répertoire courant à partir duquel le programme est exécuté, ce n'est pas toujours la même que celle où le programme réside.

Vous pouvez utiliser System.getProperty("user.dir") pour déterminer le répertoire «en cours» et le comparer à l'emplacement du programme. Vous pouvez également utiliser File#exists pour tester si le fichier existe ou non, même si, je m'attendais à ce que le code lance un IOException si c'était le cas.

Une meilleure solution à long terme serait d'incorporer l'image dans l'application (en l'incluant généralement dans le Jar), ​​ceci élimine les problèmes ci-dessus.

Dans ce cas, vous devez utiliser ...

ImageIO.read(getClass().getResource("/images/01.jpg")); 

pour charger l'image

+0

Bon, ce que je ne comprends pas, c'est que vous surchargez paintComponent mais pour autant que je puisse le voir, il n'est jamais appelé. Ou quelque chose d'autre l'appelle automatiquement? –

+0

Voir [Peinture dans AWT et Swing] (http://www.oracle.com/technetwork/java/painting-140037.html) et [Performing Custom Painting] (http://docs.oracle.com/javase/tutorial/uiswing/painting /) pour plus de détails sur comment fonctionne la peinture dans Swing – MadProgrammer

+0

Quelqu'un peut-il expliquer la raison de la downvote? Puisque la question n'a pas reçu de nouvelles réductions ou de nouveaux votes serrés, cela ne peut pas être parce que la question est invalide. Comme aucune des autres réponses n'a reçu de downvotes (et ne parvient pas à résoudre le problème), je ne peux que supposer que vous avez une vendetta personnelle contre moi et/ou ne comprends pas vraiment la question/problème et la réponse – MadProgrammer

0

Soyez conscient que votre JComponent peut être peint des centaines de fois par seconde, par exemple lorsqu'il est partiellement masquée par une autre fenêtre mobile. Donc, la performance des méthodes paint est importante, sinon vous obtenez une interface graphique "laggy".

Par conséquent, je suggère de séparer la partie qui prend du temps (c'est-à-dire lire le fichier image) du JComponent.

public class ImageComponent extends JComponent { 

    private BufferedImage image; 

    public void setImage(final BufferedImage image) { 
     this.image = image; 
     repaint(); 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     if (image != null) 
      g.drawImage(image, 0, 0, this); 
    } 
} 

Quelque part d'autre dans votre code que vous lisez le fichier d'image et mettez-le dans le composant:

BufferedImage image = null; 
try { 
    image = ImageIO.read(new File(fullpathname+"/01.jpg")); 
}catch(Exception e) { 
    System.out.println("Could not read file!"); 
    e.printStackTrace(); 
} 
ImageComponent component = new ImageComponent(); 
component.setImage(image);