在网站上收集每个网页的使用情况统计数据是常见的做法,我对类似的事情感兴趣,但对于GUI:s。您可以看到谷歌浏览器(和其他人)收集使用情况统计数据,以便谷歌可以找出人们使用的功能,数据挖掘似乎“有效”的内容。
这样做的直接方法是明确记录与每个GUI元素的交互,但这既乏味又容易在GUI缺失部分出错。
所以我想知道,这是一个解决的问题吗?是否存在可以提供类似于每个组件细分的代码分析,指标(访问次数,点击次数等)的摘要?自动添加到整个AWT / Swing组件树中的所有组件?
这些信息需要汇总到一个文件中,以便可以发送给“我们”进行汇总和数据挖掘,以推动决策等。
我并不确切地知道我想要什么,所以我也要求找出好的想法和其他人所面对的问题。
答案 0 :(得分:6)
虽然这不是一个完整的解决方案,但它可能有助于指导您更接近可行的事情。我同意上一张海报,可以在代码中添加钩子,这在大型项目中变得无法管理。此外,如果您错过了应用程序的一部分并开始检查数据,则每次用户使用该组件时都会有一个空白区域。
相反,您可以直接监听由UI中的每个组件生成的AWTEvents。这很容易成为数据挖掘的源信息。以下代码显示了如何完成此操作:
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();
}
});
}
}
在这种情况下,我已经收听了鼠标事件。这些似乎是最有用的,因为它们可以告诉您用户点击了什么。从这里开始,您需要找出需要收集的内容,以便建立用户点击内容的图片。我也会对用户没有点击的内容感兴趣。
围绕使用此技术的自动UI测试有很多工作要做。 Abbot和FEST是我用过的例子。您可能希望了解它们如何处理AWTEvents以防有任何帮助。
答案 1 :(得分:2)
嗯,您首先会希望以某种方式收到使用情况统计信息。所以你打算让你的应用程序连接到数据库吗?您是否会有另一个处理使用情况统计信息的应用?简而言之,我会创建一个像这样的函数
void LogUsage(此对象ID或句柄名称/标题文本等)
让该函数处理处理统计使用的所有处理。当然,您需要做/某些/类型的工作,例如将此函数添加到onClicks,编辑更改等,但这应该相当简单。特别是如果您的LogUsage函数只需要一些独特的东西(比如名称)并将其用于统计信息。
然后,LogUsage功能还可以远程管理连接并清除自上次传输以来可能存储的任何缓存。
简单地说,如果您创建了一个接受该对象的LogUsage函数,并且您总是获取该名称。您可以在整个程序中轻松复制/粘贴此行
LogUsage(本);
编辑 -
我也注意到你正在寻找建议:我会做我上面所说的;一个简单的LogUsage函数,它接受一个参数(如对象),并获取名称,例如 - btnLogin,然后将该名称处理成某种文件。您显然会先将此文件加载到某种地图或数组中,然后检查它是否存在。如果没有,只需单击(或使用)即可将其添加到列表中。如果存在,则增加其使用点。你显然不想在文本框等中的OnChange方法上调用LogUsage,但可能都是onFocus,Clicks或者你真正想要跟踪的所有内容。
最后,你最终可能会发送一些类似btnLogin(5)的信息,表示用户点击了btnLogin 5次。
处理所有这些接收到的数据是另一项努力,这就是为什么我肯定会将它发送到数据库而不是接收,比如电子邮件或服务器目录中充满了使用统计信息的文件。无论哪种方式,您都需要处理它并将其转换为图形或可排序的使用统计信息等。
答案 2 :(得分:0)
答案 3 :(得分:0)
嗯,据我所知,我从未见过为Swing应用程序自动收集任何使用情况统计信息。
在我看来,实现这样一个功能的最简单方法是使用look'n'feel:这样,每个组件将透明地与最合适的记录器相关联(JCheckBox将被监听以进行检查,而JSCrollBar会记录其滚动条。)
您可以考虑询问有关该功能的Kirill Grouchnikov,但我担心即使Substance也没有实现该功能。