2013-04-06 4 views
0

Bonjour J'ai un problème pour peindre une image sur un panneau et l'ajouter sur le cadre.Peinture JPanel/JComponent

import java.awt.Graphics; 
import java.awt.Image; 
import java.util.Random; 
import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
public class CardComponent extends JPanel { 
int x;int y; 
String[] str = { 
      "D:\\Images\\ImageCards\\Clubs_Ace.png", 
      "D:\\Images\\ImageCards\\Clubs_King.png", 
      "D:\\Images\\ImageCards\\Clubs_Queen.png", 
      "D:\\Images\\ImageCards\\Clubs_Jack.png", 
      "D:\\Images\\ImageCards\\Clubs_10.png", 
      "D:\\Images\\ImageCards\\Clubs_9.png", 
      "D:\\Images\\ImageCards\\Clubs_8.png", 
      "D:\\Images\\ImageCards\\Clubs_7.png", 
      "D:\\Images\\ImageCards\\Clubs_6.png", 
      "D:\\Images\\ImageCards\\Clubs_5.png", 
      "D:\\Images\\ImageCards\\Clubs_4.png", 
      "D:\\Images\\ImageCards\\Clubs_3.png", 
      "D:\\Images\\ImageCards\\Clubs_2.png", 
      "D:\\Images\\ImageCards\\Diamonds_Ace.png", 
      "D:\\Images\\ImageCards\\Diamonds_King.png", 
      "D:\\Images\\ImageCards\\Diamonds_Queen.png", 
      "D:\\Images\\ImageCards\\Diamonds_Jack.png", 
      "D:\\Images\\ImageCards\\Diamonds_10.png", 
      "D:\\Images\\ImageCards\\Diamonds_9.png", 
      "D:\\Images\\ImageCards\\Diamonds_8.png", 
      "D:\\Images\\ImageCards\\Diamonds_7.png", 
      "D:\\Images\\ImageCards\\Diamonds_6.png", 
      "D:\\Images\\ImageCards\\Diamonds_5.png", 
      "D:\\Images\\ImageCards\\Diamonds_4.png", 
      "D:\\Images\\ImageCards\\Diamonds_3.png", 
      "D:\\Images\\ImageCards\\Diamonds_2.png", 
      "D:\\Images\\ImageCards\\Hearts_Ace.png", 
      "D:\\Images\\ImageCards\\Hearts_King.png", 
      "D:\\Images\\ImageCards\\Hearts_Queen.png", 
      "D:\\Images\\ImageCards\\Hearts_Jack.png", 
      "D:\\Images\\ImageCards\\Hearts_10.png", 
      "D:\\Images\\ImageCards\\Hearts_9.png", 
      "D:\\Images\\ImageCards\\Hearts_8.png", 
      "D:\\Images\\ImageCards\\Hearts_7.png", 
      "D:\\Images\\ImageCards\\Hearts_6.png", 
      "D:\\Images\\ImageCards\\Hearts_5.png", 
      "D:\\Images\\ImageCards\\Hearts_4.png", 
      "D:\\Images\\ImageCards\\Hearts_3.png", 
      "D:\\Images\\ImageCards\\Hearts_2.png", 
      "D:\\Images\\ImageCards\\Spades_Ace.png", 
      "D:\\Images\\ImageCards\\Spades_Ace.png", 
      "D:\\Images\\ImageCards\\Spades_King.png", 
      "D:\\Images\\ImageCards\\Spades_Queen.png", 
      "D:\\Images\\ImageCards\\Spades_Jack.png", 
      "D:\\Images\\ImageCards\\Spades_10.png", 
      "D:\\Images\\ImageCards\\Spades_9.png", 
      "D:\\Images\\ImageCards\\Spades_8.png", 
      "D:\\Images\\ImageCards\\Spades_7.png", 
      "D:\\Images\\ImageCards\\Spades_6.png", 
      "D:\\Images\\ImageCards\\Spades_5.png", 
      "D:\\Images\\ImageCards\\Spades_4.png", 
      "D:\\Images\\ImageCards\\Spades_3.png", 
      "D:\\Images\\ImageCards\\Spades_2.png"  
      }; 
    Image img; 
    public CardComponent(int x,int y) { 
     setOpaque(false); 
     this.x = x; 
     this.y = y; 
     setSize(100,150); 
     setVisible(true); 


    } 
    public void paint(Graphics g) { 
     super.paint(g); 
     Random r = new Random(); 
     String s = ""; 
     s = str[r.nextInt(str.length)]; 
     img = getToolkit().getImage(s); 
     g.drawImage(img,this.x , this.y, 100, 150, this); 
    } 
    public static void main(String[] args) { 
     CardComponent cc = new CardComponent(10,150); 
     JFrame jfrm = new JFrame(); 
     jfrm.setSize(100, 150); 
     jfrm.setVisible(true); 
     jfrm.getContentPane().add(cc); 
    } 
} 

En classe est supérieure, le problème principal (ne peut pas peindre la carte) .Et j'ajouté cette chose au cadre principal (code inférieur) .Je ajouté principale méthode dans toutes les classes juste pour vérifier si elle fonctionne bien . import java.awt.Button; import java.awt.Color; import java.awt.event.ActionEvent; import java.awt.event.ActionListener;

import javax.swing.JFrame; 
    import javax.swing.JLabel; 
    import javax.swing.JPanel; 
    import javax.swing.JSlider; 
    import javax.swing.event.ChangeEvent; 
    import javax.swing.event.ChangeListener; 


    public class PanelButtons extends JPanel{ 
Button but1; 
Button but2; 
    Button but3; 
JLabel jlab; 
JSlider jsl; 
public PanelButtons() { 
    setLayout(null); 
    Color c = new Color(0,120,0); 
    setSize(700,200); 
    setLocation(0,0); 
    setOpaque(false); 
    but1 = new Button("Check"); 
    but1.setBackground(Color.CYAN); 
    but1.setLocation(660, 350); 
    but1.setBounds(683, 650, 70, 40); 
    add(but1); 
    but2 = new Button("Fold"); 
    but2.setBackground(Color.CYAN); 
    but2.setLocation(660, 350); 
    but2.setBounds(753, 650, 70, 40); 
    add(but2); 
    but3 = new Button("Bet"); 
    but3.setBackground(Color.CYAN); 
    but3.setLocation(660, 350); 
    but3.setBounds(823, 650, 70, 40); 
    add(but3); 
    int money = Player.PremierMoney(); 
    jsl = new JSlider(0,1000); 
    jsl.setMajorTickSpacing(50); 
    jsl.setMinorTickSpacing(10); 
    jsl.setLabelTable(jsl.createStandardLabels(100)); 
    jsl.setPaintTicks(true); 
    jsl.setPaintLabels(true); 
    jsl.setSize(400, 150); 
    jsl.setBackground(c); 
    jlab = new JLabel("Ваша ставка"+jsl.getValue()); 
    jsl.addChangeListener(new ChangeListener() { 
     @Override 
     public void stateChanged(ChangeEvent ce) { 
      if(jsl.getValueIsAdjusting()) return; 
      jlab.setText("Ваша ставка:"+jsl.getValue()); 

     } 

    }); 
    jlab.setHorizontalTextPosition(JLabel.CENTER); 
    jlab.setVerticalAlignment(JLabel.BOTTOM); 
    jsl.setLocation(900,600); 
    jlab.setLocation(150,150); 
    add(jsl); 
    add(jlab); 
    but2.addActionListener(new ActionListener() { 


     @Override 
     public void actionPerformed(ActionEvent e) { 
      but1.setEnabled(false); 
      but2.setEnabled(false); 
      but3.setEnabled(false); 

     } 
    }); 
} 

public static void main(String[] args) { 
    JFrame jfrm = new JFrame("Some frame"); 
    jfrm.setSize(200, 200); 
    PanelButtons pb = new PanelButtons(); 
    jfrm.setContentPane(pb); 
    jfrm.setVisible(true); 
    jfrm.setDefaultCloseOperation(jfrm.EXIT_ON_CLOSE); 
} 
    } 

Cette classe décrit les boutons et le curseur. import java.awt.Color; import javax.swing.JFrame;

public class Images extends JFrame{ 
    Images() { 
     // CardComponent cc = new CardComponent(530,550); 
     PanelButtons pb = new PanelButtons(); 
     Color c = new Color(0,120,0); 
    // cc.setBounds(530, 550, 100, 150); 
     setSize(1366,750); 
     setBackground(c); 
     setContentPane(pb); 
    // setContentPane(cc); 
     setVisible(true); 
    }  




    public static void main(String[] args) { 
     Images im = new Images(); 
     im.setResizable(false); 
     im.setDefaultCloseOperation(EXIT_ON_CLOSE); 
    } 
    } 

Et c'est le cadre principal auquel j'ajoute des panneaux. Donc, le problème principal est où je peins la carte. Merci pour votre aide.

Répondre

0

Je suis un peu confus par votre code, je ne vois pas un objet CardComponent, vous devez instancier un objet de votre classe CardComponent puis l'ajouter à votre JFrame ou un composant dans le JFrame comme ça ...

Images im = new Images(); 
PanelButtons pb = new PanelButtons(); 
CardComponent cc = new CardComponent(x, y); 
im.setContentPane(pb); 
pb.setLayout(new BorderLayout()); 
pb.add(cc, BorderLayout.CENTER); 

Ce programme n'est pas fonctionnel mais j'espère que vous en aurez l'idée. Et je ne vous contentez le code de sorte que son possible, je manqué où vous instancier l'objet CardComponent donc si vous rencontrez toujours des problèmes, essayez de charger l'image de cette façon ...

public void paint(Graphics g) { 
    super.paint(g); 
    Random r = new Random(); 
    String s = ""; 
    s = str[r.nextInt(str.length)]; 
    img = ImageIcon(s).getImage(); 
    g.drawImage(img,this.x , this.y, 100, 150, this); 
} 

Je viens de rencontrer votre code et je une suggestion de plus. Dans le CardComponent définir les limites dans le constructeur en utilisant la méthode setBounds(x, y, 100, 150) puis dessiner l'image à partir du coin supérieur gauche (0, 0) en bas à droite (100, 150) ou (getWidth(), getHeight()).

Espérons que cela aide, bonne chance.

+0

Merci pour la réponse.Bien j'ai changé le code un peu, setContentPane à getContentPane.That objet que vous disiez qu'il a été commenté, parce que cela ne fonctionnait pas plus tôt, mais maintenant il le fait.Mais maintenant le problème est que 2 panneaux repeindre les uns les autres, de sorte que je ne peux voir qu'un d'entre eux.Quelle méthode peut nous donner la taille du panneau ou du composant? Comme vous le voyez je mets setSize(), mais ça ne marche pas ou peut-être devrions-nous le mettre en place est créé? – Psychoman

+0

Je viens d'éditer ma réponse. setBounds (int x, int y, largeur int, int height) ou setBounds (rectangle rect) fonctionnera avec une mise en page nulle et est probablement votre meilleur pari si vous n'utilisez pas LayoutManager, avec un LayoutManager comme je le définis habituellement taille des panneaux est en ajoutant cela au constructeur ... public CardComponent() { Dimension dim = this.getPreferredSize(); dim.width = 100; dim.height = 150; this.setPreferredSize (dim); } Est-ce que cela répond à votre question? –

+0

public CardComponent (int x, int y, hauteur int, largeur int) { \t \t setOpaque (false); \t \t this.x = x; \t \t this.y = y; \t \t this.hauteur = hauteur; \t \t ce.largeur = largeur; \t \t setLayout (null); \t \t setSize (100,150); \t \t setVisible (true); \t \t setBounds (this.x, this.y, this.hauteur, this.largeur); \t \t \t \t \t} \t public void peinture (Graphics g) { \t super.paint (g); \t Aléatoire r = nouveau Aléatoire(); \t Chaîne s = ""; \t s = str [r.nextInt (str.length)]; \t img = getToolkit(). GetImage (s); \t g.drawImage (img, 0, 0,100, 150, this); \t} C'est ce que vous vouliez dire? – Psychoman

3

Il ya un certain nombre de problèmes avec votre programme entier, le choix des dispositions null est significatif, cela va vous causer beaucoup de problèmes.

Mais, le problème important que vous êtes confronté est dans votre méthode paint

public void paint(Graphics g) { 
    super.paint(g); 
    Random r = new Random(); 
    String s = ""; 
    s = str[r.nextInt(str.length)]; 
    System.out.println(s); 
    img = getToolkit().getImage(s); 
    g.drawImage(img, this.x, this.y, 100, 150, this); 
} 

Il y a trois problèmes avec cette méthode.

  1. Vous devez surcharger paintComponent, c'est une méthode plus sûre pour effectuer une peinture personnalisée.
  2. Vous régénérez l'image au hasard sur chaque cycle de peinture. Vous devez vous rappeler que votre composant peut être peint pour un certain nombre de raisons et la plupart en dehors de votre contrôle. Cela signifie que chaque fois que le composant est peint, une nouvelle image est chargée. Vous devriez assigner une seule image au composant quand il est construit et peindre cette image.
  3. Le contexte Graphics transmis à votre composant a été traduit de sorte que le point 0x0 se trouve dans le coin supérieur gauche du composant. Cela signifie que toute la peinture est relative.

Votre code fait cela ...

g.drawImage(img, this.x, this.y, 100, 150, this); 

Cela signifie que l'image sera peint à pixels x/y par rapport à la position supérieure/gauche du composant. Au lieu de cela, vous devriez peindre autour de la position 0x0.

Dans votre exemple, vous faites également

jfrm.setVisible(true); 
jfrm.getContentPane().add(cc); 

Ceci est généralement une mauvaise idée, vous devriez changer ces deux déclarations, sinon il ressemblera rien n'a été peint.

Vous pouvez trouver la peine de prendre une lecture par

Mise à jour avec un exemple simple

Cette exa mple est destiné à démontrer la quantité de hits qu'une méthode paint peut prendre ainsi que le concept d'espace de coordonnées local.

enter image description here

import java.awt.Color; 
import java.awt.Component; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.FontMetrics; 
import java.awt.Graphics; 
import java.awt.GridBagLayout; 
import java.awt.Image; 
import java.io.File; 
import java.util.Random; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class Cards { 

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

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

       JFrame jfrm = new JFrame(); 
       jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       jfrm.setSize(100, 150); 
       jfrm.setVisible(true); 
       jfrm.add(new TestPane()); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     public TestPane() { 
      CardComponent cc = new CardComponent(); 
      setLayout(new GridBagLayout()); 
      add(cc); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      FontMetrics fm = g.getFontMetrics(); 
      // Simply render the location of the component relative to it's parent. 
      for (Component comp : getComponents()) { 
       String text = comp.getX() + "x" + comp.getY(); 
       g.drawString(text, comp.getX(), comp.getY() - fm.getHeight() + fm.getAscent()); 
      } 
     } 

    } 

    public class CardComponent extends JPanel { 

     String[] str; 
     Image img; 
     private int paintCount; 

     public CardComponent() { 
      File[] files = new File("C:\\Users\\swhitehead\\Documents\\My Dropbox\\MegaTokyo").listFiles(); 
      str = new String[files.length]; 
      for (int index = 0; index < files.length; index++) { 
       str[index] = files[index].getPath(); 
      } 
      setOpaque(false); 
      setVisible(true); 
     } 

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

     @Override 
     public Dimension getMinimumSize() { 
      return getPreferredSize(); 
     } 

     public void paint(Graphics g) { 
      paintCount++; 
      System.out.println(paintCount); 
      super.paint(g); 
      Random r = new Random(); 
      String s = ""; 
      s = str[r.nextInt(str.length)]; 
      img = getToolkit().getImage(s); 
      // Drawing image in the top left corner of the component 
      g.drawImage(img, 0, 0, 100, 150, this); 
      g.setColor(Color.RED); 
      g.drawRect(0, 0, getWidth(), getHeight()); 
      FontMetrics fm = g.getFontMetrics(); 
      String text = "Local 0x0"; 
      g.drawString(text, 0, fm.getAscent()); 
     } 
    } 
} 

Avec cet exemple, j'ai pu obtenir le paintCount à 3640 avant même touché le cadre.

Le chargement d'une image dans une méthode paint est également une mauvaise idée. Il est prévu que les méthodes paint reviennent aussi vite que possible, faute de quoi cela réduira les performances de votre programme.

+0

Merci, je vais le lire, mais j'ai quelques questions.Pourquoi setLayout (null) est une mauvaise idée? Je sais que vous devez faire plus de choses alors, mais je pense qu'il peut mieux organiser mon interface.Je suis d'accord que peinture 1 image de 1 composant est une idée plus sûre, mais j'ai 52 cartes, 52 composants, 52 classes, sons effrayants (ou peut-être je ne vous ai pas compris) .Mais je ne comprends pas 3 points, pouvez-vous expliquer pls ? Suivant sur l'image, merci, mais si je mets cette image dans un composant, puis dans un panneau avec coor (150,150) et l'image dessinerait coor (150,150) .Est-ce que l'image dessiner avec coor (300,300)? Merci d'aider! – Psychoman

+0

Les gestionnaires de mise en page réduisent la complexité et prennent en compte les différences dans la manière dont les différentes plateformes rendent le contenu. La question est, voulez-vous programmer le jeu ou la gestion de la mise en page? L'API Swing est conçue autour de l'utilisation de gestionnaires de disposition, vous jetez ainsi un large segment de l'API. Le problème avec la façon dont votre routine de peinture est configurée, est que chaque fois que 'CardComponent' est peint, il peint une nouvelle image aléatoire. Cela peut être fait en réponse à la redimensionnement du cadre, la souris a été déplacée sur le composant, des dizaines d'autres problèmes que vous n'avez aucun contrôle – MadProgrammer

+0

La plupart des PC modernes ont, quoi, 4mb de RAM, je ne pense pas que la mémoire est un problème. Si vous êtes vraiment inquiet, vous devriez seulement rendre ces cartes visibles de toute façon, quoi, peut-être 12? Point 3. Toute la peinture d'un composant (dans la méthode 'paint') est faite de sorte que la position x/y de 0x0 est le coin supérieur/gauche du composant. Votre installation a l'image a été peint à 10x150, tandis que le composant est seulement 100x150, ce qui signifie, les images ont été rendues à l'extérieur du composant – MadProgrammer