Préoccupations concernant la fonction de JPanel: paintcomponent()

bonjour, je suis nouveau en programmation java, et j'ai besoin que quelqu'un me décrivant ces lignes de code:

 public class drawpanel extends JPanel
 {
     public void paintComponent(Graphics g)
     { 
         super.paintComponent(g);
         ...
     }
 }

je ne comprends pas la ligne public void paintComponent(Graphics g): Pourquoi dois-je déclarer cette fonction si elle est prédéfinie dans JPanel?

Et cette ligne super.paintComponent(g): je ne comprends pas du tout. Je vous remercie pour votre aide.

17
demandé sur rekaszeru 2011-03-27 04:35:35

3 réponses

La Structure De Base:

extends mot clé DrawPanel hérite de JPanel. En d'autres termes, DrawPanel ""JPanel. En tant que tel, il peut outrepasser ses méthodes (celles qui ne sont pas marquées final). Vous pouvez le faire pour plusieurs raisons. Par exemple, vous pouvez vouloir obtenir l'accès au panneau Graphics classe, que vous pouvez utiliser pour dessiner un cercle sur le panneau, ou un graphique à barres, ou une chaîne de texte.

si vous n'annulez pas méthodes, puis quand vous étendez JPanel vous obtenez quelque chose comme ceci:

public class DrawPanel extends JPanel {
    //TODO not much
}

Toutefois, ce n'est pas très utile ...sauf si vous n'aimez pas le nom JPanel et que vous voulez l'appeler AwesomePanel (remarque: ne pas le faire). Si c'est tout ce que vous avez, vous êtes mieux de créer un exempleJPanel, comme ceci: JPanel drawPanel = new JPanel();


paintComponent:

Le but de l'extension JPanel doit remplacer paintComponent méthode. JPanel est invisible jusqu'à ce que vous substituez paintComponent ( note: être invisible est ce qui en fait un conteneur utile pour les boutons et autres composants). Vous avez raison, le paintComponent la méthode est prédéfinie (dans le JComponent classe si vous vous demandez), mais cette méthode n'est de faire un vide JPanel. Si vous voulez dessiner quelque chose sur le panneau, alors vous devez le modifier, comme ceci:

public class DrawPanel extends JPanel {
    @Override public void paintComponent(Graphics g) { // <-- HERE!
        //TODO draw stuff
    }
}

remarque:@Override la partie n'est pas strictement nécessaire mais c'est une bonne pratique de l'inclure car elle réduit le nombre d'erreurs d'exécution et améliore la lisibilité du code

Vous avez maintenant accès à l' Graphics objet g pour le panneau. Graphics est une classe d'assistance qui vous permet de dessiner des choses sur le panneau, comme ceci:

public class DrawPanel extends JPanel {
    @Override public void paintComponent(Graphics g) {
        g.drawOval(50, 50, 50, 50); // <-- draws an oval on the panel
    }
}

super.paintComponent:

métaphore utile (que je viens d'inventer): leJPanel est la toile, leGraphicsobjet est de votre pinceau, etsuper.paintComponent(g)est votre gomme. (Aussi,JFrameest votre chevalet.)

super.paintComponent(g) appelle paintComponent méthode de la superclasse deJPanel (JComponent class) pour effacer ce qui est dessiné sur le panneau. ceci est utile pour l'animation.

par exemple, envisagez de dessiner une horloge analogique sur le panneau. Vous avez besoin de rafraîchir chaque seconde, de sorte que chaque seconde vous devez effacer l'horloge précédente et redessiner l'horloge, en ajustant la seconde main. Si vous n'avez pas invoquer super.paintComponent(g) avant de redessiner l'horloge, il va juste continuer à dessiner de nouvelles horloges sur le dessus des anciennes horloges et en 60 secondes ce que vous aurez est juste un rempli en cercle, plus ou moins.

une seule chose à retenir: toujours appeler super.paintComponent(g) premier paintComponent méthode, comme ceci:

public class DrawPanel extends JPanel {
    public void paintComponent(Graphics g) {
        super.paintComponent(g); // <-- HERE!
        g.drawOval(50, 50, 50, 50);
    }
}

C'est ça. Hésitez pas à contactez-moi.


Exemple:

j'ai créé un exemple simple qui utilise ces concepts pour afficher une chaîne de texte sur un panneau (qui est placé à l'intérieur d'un cadre). Enregistrer dans votre IDE TestPanel.java.

import java.awt.*;
import java.util.*;
import javax.swing.*;

/**
 * A frame containing a panel that is sometimes red and sometimes 
 * blue. Also, it displays the word to go with it. 
 * 
 * Inspired by www.sometimesredsometimesblue.com.
 *
 */
public class TestPanel extends JPanel {

    private Random random = new Random();
    private boolean isRed;
    private String s = "";

    public TestPanel() {
        //randomly determine whether the background should be red
        isRed = random.nextBoolean();

        //set the background to blue
        setBackground(Color.BLUE);
        s = "BLUE";

        //if 'isRed' is true, set the background to red
        if (isRed) {
            setBackground(Color.RED);
            s = "RED";
        }
    }

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

        //write either "RED" or "BLUE" using graphics
        g.setColor(Color.WHITE);
        g.setFont(new Font("serif", Font.BOLD, 60));
        g.drawString(s, getWidth() / 2 - g.getFontMetrics().stringWidth(s) / 2,
                getHeight() / 2 + g.getFontMetrics().getHeight() / 2);
    }

    //main method: create an instance of TestPanel and output it on a JFrame
    public static void main(String[] args) {
        JFrame f = new JFrame();
        f.setSize(500, 500);
        f.setTitle("Sometimes Red, Sometimes Blue");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setContentPane(new TestPanel());
        f.setVisible(true);
    }
}
49
répondu TheBlackKeys 2011-07-15 00:37:52

paintComponent() est une méthode définie à l'origine dans la classe abstraite JComponent. Les composants qui étendent directement JComponent (s'ils sont exposés) ont l'option de passer outre paintComponent(). l'appel à super.paintComponent(g) appelle l'implémentation de paintComponent() (dans votre cas, C'est JPanel). Vous souhaitez remplacer paintComponent() si vous voulez faire d'autres choses avec Graphics g en plus de ce que JPanel fait déjà.

2
répondu Bala R 2011-03-27 00:39:51

il suffit de définir paintComponent() dans votre classe, si vous voulez changer la façon dont votre composant si dessinée. Dans votre implémentation personnalisée vous devez appeler super.paintComponent(g); c'est à dire une version de classe de base de paintComponent(), parce qu'il fait un peu de travail nécessaire pour préparer les composants pour le dessin.

1
répondu pajton 2011-03-27 00:42:51