2010-06-28 6 views
2

J'ai créé une classe JButton personnalisée pour représenter des espaces sur un tableau de monopole. Le jeu est multijoueur donc une grande partie des informations nécessaires pour dessiner le bouton est conservée sur le serveur (accessible via RMI).Arrêtez JButton repeindre sur la souris?

Mon problème est que lorsque je souris sur le bouton, il semble automatiquement appeler repaint() (et dessine une bordure). Cela rend le programme très lent car il doit extraire des données du serveur chaque fois que la souris est sur l'un des espaces.

J'ai essayé de trouver un moyen d'arrêter cela, mais tout le monde sur Internet semble avoir un problème avec le bouton pour repeindre() plutôt que de l'arrêter.

Est-ce que quelqu'un connaît une méthode que je peux remplacer ou une propriété que je peux changer pour arrêter cela?

+1

est-ce que vous ne pourriez pas faire une copie locale de l'état de jeux au lieu de le tirer du serveur? – josefx

Répondre

4

Je suggère que votre conception Reconsidérer. J'avoue que je ne connais pas tous les facteurs en jeu, mais d'après votre description, je pense que l'état du tableau ne change pas très souvent, donc il n'y a aucune raison d'appeler le serveur à chaque tentative de peinture. Au lieu de cela, si votre serveur diffusait des événements de jeu au client, vous auriez l'état dont vous avez besoin localement lorsque les appels repaint seront effectués. De même, d'après votre description, il semble que vous puissiez appeler le serveur depuis votre code repaint, déclenché par des événements de souris. Cela très bien peut être fait dans l'EDT. Vous ne devriez pas faire d'appels de serveur dans votre thread de peinture, car cela ralentira le reste de votre interface graphique. Les appels longs doivent être effectués dans un thread de travail. Jetez un oeil à SwingWorker et concepts around threading in Swing pour plus de détails.

Même ainsi, je ne pense pas que le fait de jouer avec la logique de repaint serait le meilleur plan d'action. Fournir à votre bouton ce dont il a besoin pour se rendre lui-même est une meilleure étape.

1

Bien sûr, vous pouvez, mais pas simple. Quoi que vous essayiez de peindre sur le JButton, ayez le dump dans un BufferedImage. Le paint() de votre JButton devrait essentiellement renvoyer une image mise en mémoire tampon. Les images tamponnées sont très rapides pendant les repeints, elles sont juste une matrice de pixels et il ne faudra pas beaucoup de temps entre les repeints.

package test; 

import java.awt.Graphics; 

import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 

public class ButtonTest { 
    public static void main(String[] args){ 
     new ButtonTest().test(); 
    } 

    public void test(){ 
     JFrame frame = new JFrame("TestFrame"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     JPanel pnl = new JPanel(); 
     pnl.add(new MyButton()); 
     frame.add(pnl); 
     frame.setSize(600, 600); 
     frame.setVisible(true); 
    } 

    class MyButton extends JButton{ 
     public void paint(Graphics g){ 
      //return a buffered image everytime 
     } 
    } 
} 

Bien que la technique ci-dessus semble un peu stupide, vous pouvez essentiellement avoir une image en mémoire tampon dans la mémoire et qui devrait être retourné par la méthode de peinture(). Et tout ce que vous recevez du serveur (RMI) peut être sauvegardé dans l'objet BufferedImage en utilisant un thread séparé en arrière-plan.

1

Avez-vous essayé de désactiver la peinture de la bordure de mise au point? Jetez un oeil à the JButton API documentation pour plus de détails.

En outre, vous pouvez essayer de mettre en cache les données affichées sur le bouton. Et, est-ce qu'un bouton est vraiment approprié pour ce que vous essayez de faire? N'oubliez pas que les utilisateurs s'attendent à ce que les éléments GUI connus réagissent de manière très spécifique.

2

Il ne devrait jamais être de grands calculs dans le repeindre() (et de la peinture()) méthodes de vos composants Swing, et encore moins les appels serveur ...