2010-01-13 1 views
24

La collecte de statistiques d'utilisation par page Web sur les sites est une pratique courante, je suis intéressé par une chose similaire, mais pour GUI: s. Vous voyez Google Chrome (et d'autres) collecter des statistiques d'utilisation afin que Google puisse découvrir les fonctionnalités que les utilisateurs utilisent, pour extraire des données de ce qui semble fonctionner. Une manière simple de procéder est de consigner explicitement l'interaction avec chaque élément de l'interface graphique, mais cela est à la fois fastidieux et sujet aux erreurs dans les parties manquantes de l'interface graphique.Existe-t-il de bons outils pour trouver des statistiques d'utilisation de l'interface graphique, des volets et des composants?

Donc ce que je me demande, est-ce un problème résolu? Existe-t-il des éléments pouvant fournir un résumé similaire au profilage de code, aux statistiques (nombre de visites, clics, etc.) ventilés par composant? Automatiquement ajouté à tous les composants dans l'arbre entier des composants AWT/Swing?

Ces informations doivent être résumées dans un fichier afin qu'il puisse être envoyé à « nous » pour l'agrégation et l'exploration de données, pour prendre des décisions, etc.

Je ne sais pas vraiment exactement ce que je veux, donc Je demande également de trouver de bonnes idées et ce que d'autres ont fait qui ont fait face à ce problème.

+1

EXCELLENTE question, car elle montre que vous pensez réellement à la convivialité (que de nombreux programmeurs ont tendance à ignorer). Une solution encore plus complète permettrait de suivre le mouvement du pointeur pour voir ce qu'ils survolent pour obtenir des explications. Les personnes effectuant des études sur la convivialité suivent les actions, les points focaux de l'attention et le mouvement du pointeur. – BobMcGee

Répondre

6

Bien que ce ne soit pas une solution complète, il pourrait vous aider à vous rapprocher de quelque chose de réalisable. Je suis d'accord avec le poster précédent, qu'il est possible d'ajouter des hooks dans votre code, cela devient ingérable sur un grand projet. Aussi, si vous manquez une partie de l'application et venez examiner les données, vous aurez un espace vide chaque fois que l'utilisateur utilise ce composant. A la place, vous pouvez écouter directement les AWTEvents générés par chaque composant de l'interface utilisateur. Cela pourrait facilement être l'information source pour votre exploration de données. Le code suivant vous montre comment cela est fait:

package awteventlistenerexample; 

import java.awt.AWTEvent; 
import java.awt.BorderLayout; 
import java.awt.EventQueue; 
import java.awt.FlowLayout; 
import java.awt.Toolkit; 
import java.awt.event.AWTEventListener; 
import java.awt.event.ActionEvent; 
import java.awt.event.MouseEvent; 
import java.awt.event.WindowAdapter; 
import java.awt.event.WindowEvent; 
import javax.swing.AbstractAction; 
import javax.swing.Action; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 

public class Test { 
    private static final String ACTION_CLOSE = "Close"; 
    private JFrame frame; 
    public Test() { 
     frame = new JFrame(); 
     initActions(); 
     frame.setLayout(new BorderLayout()); 
     frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); 
     frame.addWindowListener(new WindowAdapter() { 
      @Override 
      public void windowClosing(WindowEvent e) { 
       frame.getRootPane().getActionMap().get(ACTION_CLOSE).actionPerformed(null); 
      } 
     }); 

     JPanel content = new JPanel(new FlowLayout()); 
     content.add(new JLabel("Creature")); 
     JButton badger = new JButton("Badger"); 
     badger.setName("badger"); 
     JButton ferret = new JButton("Ferret"); 
     ferret.setName("ferret"); 
     JButton stoat = new JButton("Stoat"); 
     stoat.setName("stoat"); 
     content.add(badger); 
     content.add(ferret); 
     content.add(stoat); 
     frame.add(content, BorderLayout.CENTER); 

     JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER)); 
     JButton close = new JButton(frame.getRootPane().getActionMap().get(ACTION_CLOSE)); 
     buttonPanel.add(close); 

     frame.add(buttonPanel, BorderLayout.SOUTH); 
     frame.setSize(200, 150); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    private void initActions() { 
     Action close = new AbstractAction("Close") { 
      public void actionPerformed(ActionEvent e) { 
       frame.dispose(); 
      } 
     }; 
     frame.getRootPane().getActionMap().put(ACTION_CLOSE, close); 
    } 

    public static void main(String args[]) { 
     // Attach listener to AWTEvents (Mouse Events) 
     Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() { 
      public void eventDispatched(AWTEvent event) { 
       if (event instanceof MouseEvent) { 
        MouseEvent m = (MouseEvent) event; 
        if (m.getID() == MouseEvent.MOUSE_CLICKED) { 
         System.out.println(m.toString()); 
        } 
       } 
      } 
     }, AWTEvent.MOUSE_EVENT_MASK); 

     EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       new Test(); 
      } 
     }); 
    } 
} 

Dans ce cas, j'ai écouté Mouse Events. Ceux-ci semblent être les plus utiles car ils peuvent vous dire ce sur quoi l'utilisateur a cliqué. À partir de là, vous devrez déterminer ce que vous devez collecter afin de créer une image de ce sur quoi l'utilisateur a cliqué. Je serais également intéressé par ce que l'utilisateur n'a pas cliqué sur.

Il y a beaucoup de travail entourant le test automatisé de l'interface utilisateur qui utilise cette technique. Abbot et FEST sont des exemples que j'ai utilisés. Vous pourriez vouloir regarder comment ils traitent AWTEvents au cas où il y aurait quelque chose d'utile.

+0

Excellente réponse. – Pindatjuh

+0

Alors, comment obtenez-vous quel volet a été cliqué à partir de l'événement de la souris? –

0

Netbeans et Eclipse ont tous deux des mécanismes pour collecter des statistiques sur l'interface utilisateur, mais je n'ai aucune idée de la facilité d'utilisation de ces applications externes en fonction de leurs plates-formes.

0

Eh bien, pour autant que je sache, je n'ai jamais vu de statistiques d'utilisation de collecte automatique pour les applications Swing. À mon avis, le moyen le plus simple d'implémenter une telle fonctionnalité serait d'utiliser look'n'feel: de cette façon, chaque composant sera associé de manière transparente aux meilleurs loggers (un JCheckBox sera écouté pour les contrôles, tandis que un JSCrollBar aurait son scroll enregistré).

Vous pouvez penser à demander Kirill Grouchnikov à propos de cette fonctionnalité, mais je crains que même Substance ne l'implémente pas.

2

Eh bien, vous attendez d'abord de recevoir les statistiques d'utilisation. Alors, allez-vous connecter votre application à une base de données? Allez-vous avoir une autre application qui traite les statistiques d'utilisation? Bref, je créerais une fonction comme celui-ci

LogUsage void (ce numéro d'identification objet ou gérer le nom/texte de légende, etc.)

et laisser cette fonction gérer tout le traitement de la manipulation statistique d'utilisation. Bien sûr, vous devrez faire/un peu/un genre de travail comme ajouter cette fonction à onClicks, éditer les changements etc, mais cela devrait être assez simple. Surtout si votre fonction LogUsage prend juste quelque chose d'unique (comme le nom) et l'utilise pour les statistiques.

La fonction LogUsage peut également gérer la connexion à distance et effacer tout le cache qu'elle peut avoir stocké depuis sa dernière transmission. En termes simples, si vous avez créé une fonction LogUsage qui accepte l'objet, vous saisissez toujours le nom.Vous pouvez simplement copier/coller cette ligne tout au long de votre programme

LogUsage (this);

Modifier-

J'ai aussi remarqué que vous cherchez des suggestions: Je ferais ce que je disais ci-dessus; une simple fonction LogUsage qui accepte un paramètre tel que l'objet, et saisit le nom, par exemple - btnLogin, puis traite ce nom dans un type de fichier. Vous devez évidemment d'abord charger ce fichier dans une sorte de carte ou de tableau, vérifiez pour voir s'il existe en premier. Sinon, il l'ajoute à la liste en 1 clic (ou usage). S'il existe, il incrémente son point d'utilisation. Vous ne voudrez évidemment pas appeler LogUsage sur la méthode OnChange dans une zone de texte, etc, mais probablement sur onFocus, Clicks, ou tout ce que vous voulez vraiment garder la trace. À la fin, vous pourriez vous retrouver avec quelque chose comme btnLogin (5) qui vous est envoyé, indiquant que l'utilisateur a cliqué 5 fois sur btnLogin.

La gestion de toutes ces données reçues est un autre effort, c'est pourquoi je l'enverrais définitivement à une base de données plutôt que de recevoir, disons un e-mail ou un répertoire serveur de fichiers de statistiques d'utilisation. De toute façon, vous aurez besoin de quelque chose pour le transformer et le transformer en graphiques ou statistiques d'utilisation triable, etc.

Questions connexes