Есть ли какие-либо хорошие инструменты для нахождения статистики использования графический интерфейса пользователя, сломанных стекол и компонентов? [закрытый]

Собирающие статистические данные использования за интернет-страницу на территориях - обычная практика, я интересуюсь подобной вещью, но для GUI:s. Вы видите, что Google Chrome (и другие) собирает статистические данные использования, таким образом, Google может узнать, что показывает использование людей к моему данными, что, кажется, «работает».

Прямой способ сделать это должно явно зарегистрировать взаимодействие с каждым элементом графический интерфейса пользователя, но это и утомительно и подвержено ошибкам в недостающих частях графический интерфейса пользователя.

Таким образом, что интересно, действительно ли это - решенная проблема? Действительно ли там что-нибудь существующее, который может предоставить резюме, подобное профилированию кодекса, метрики (количество посещений, щелчков, и т.д.) сломанный на за компонент? Автоматически добавленный ко всем компонентам в целом дереве компонентов AWT/Swing?

Эта информация должна была бы быть получена в итоге к файлу, таким образом, ее можно послать «нам» для скопления и сбора данных, чтобы стимулировать решения и т.д.

Я действительно не знаю точно, что я хочу, таким образом, я также прошу узнавать хорошие идеи и что другие люди сделали, которые стояли перед этой проблемой.

24
задан Christian 13 January 2010 в 15:24
поделиться

4 ответа

В типичной реализации, где int является 32-разрядной, -1 при преобразовании в неподписанную int является 4 294 967 295, которая действительно является ≥ 1000.

Даже если вы рассматриваете вычитание в беззнаковом мире, 1000 - (4 294 967 295) = -4,294,966,295 = 1 001 , что вы получаете.

Поэтому при сравнении без подписи с с подписью gcc появится предупреждение. (Если предупреждение не отображается, установите флаг -Wsign-compare .)

-121--1260933-

Перестроение только измененных источников ДОЛЖНО быть поведением по умолчанию. Конечно, если изменить центральный заголовок, включенный почти во все зависимые файлы cpp, это вызовет почти полную перестройку. Посмотрите, что происходит, если вы изменяете только один файл cpp (добавляя комментарий или одинаково), если компилируется больше, чем эта единица компиляции, то я предлагаю вам инвестировать больше времени, чтобы исследовать его, в конечном итоге, давая вам мой EMail, чтобы глубже взглянуть на конфигурацию.

Другая возможность заключается в том, что вы составляете под окнами и используете версию 2.8, которая имеет ошибку, связанную с этим. Посмотрите на версию 2.9, чтобы узнать, нет ли этого дефекта: http ://www.mail-archive.com/cmake @ cmake.org/msg24876.html

-121--3643167-

Хотя это не полное решение, оно может помочь вам приблизиться к чему-то работоспособному. Я согласен с предыдущим плакатом, что можно добавить крючки в свой код, это становится неуправляемым на большом проекте. Кроме того, если вы пропустите часть приложения и придете, чтобы проверить данные, у вас будет пустое место каждый раз, когда пользователь использует этот компонент.

Вместо этого вы можете прослушивать 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();
            }
        });
    }
}

В этом случае я прослушал события мыши. Они кажутся наиболее полезными, так как они могут рассказать вам, на что нажал пользователь. Отсюда вам нужно будет выяснить, что нужно собрать, чтобы создать картину того, на что нажал пользователь. Мне также было бы интересно, на что пользователь также не нажимал.

Существует много работы вокруг автоматизированного тестирования пользовательского интерфейса, в котором используется этот метод. Аббат и FEST - примеры, которые я использовал. Вы можете посмотреть, как они обрабатывают AWTEvents на случай, если там есть что-то полезное.

6
ответ дан 29 November 2019 в 00:29
поделиться
std::string::iterator it;
char* c;
if (&*it == c)

Отмена передачи итератора приводит к ссылке на объект с указаниями. Таким образом, обособление дает указатель на объект.

Edit
Конечно, это не очень актуально, так как гораздо лучший подход состоит в том, чтобы полностью отказаться от сравнения и полагаться на функцию find , которая уже существует, чтобы делать то, что вы хотите.

-121--4121291-

Вот реализация глубокого сравнения, где стек используется для отслеживания пути к сравниваемому текущему объекту.

C # реализация глубокого/рекурсивного сравнения объектов в .net 3,5

Я также использовал его в подобных типах кода, работающих с генерацией операторов xpath для определенных xml-узлов.

-121--3048020-

Netbeans и Eclipse имеют механизмы сбора статистики пользовательского интерфейса, но я понятия не имею, насколько легко использовать эти приложения на основе их платформ.

0
ответ дан 29 November 2019 в 00:29
поделиться

Сначала вы ожидаете получить статистику использования каким-либо образом. Вы собираетесь подключить приложение к базе данных? У вас будет другое приложение, обрабатывающее статистику использования? Короче говоря, я бы создал такую функцию, как

void LogUsage (этот идентификатор объекта или имя дескриптора/текст подписи и т.д.)

и позволил бы этой функции обрабатывать всю обработку обработки статистического использования. Конечно, вам потребуется выполнить/какую-то/такую работу, как добавление этой функции в onClicks, редактирование изменений и т.д., но это должно быть довольно просто. Особенно если функция LogUsage просто принимает что-то уникальное (например, имя) и использует это для статистики.

Функция LogUsage также может затем управлять удаленным подключением и очищением любого кэша, сохраненного с момента последней передачи.

Проще говоря, если вы создали функцию LogUsage, которая принимает объект, и всегда берете имя. Вы можете просто скопировать/вставить эту строку на протяжении всей программы

LogUsage (this);

Edit -

Я также заметил, что вы ищете предложения: я бы сделал то, что сказал выше; простая функция LogUsage, которая принимает парам, такой как объект, и захватывает имя, например, btnLogin, а затем обрабатывает это имя в какой-то файл. Вы, очевидно, сначала загрузите этот файл в какую-то карту или массив, сначала проверьте, существует ли он. Если нет, он добавляет его в список с помощью 1 щелчка (или использования). Если он существует, он увеличивает свою точку использования. Вы, очевидно, не хотите вызывать LogUsage по методу OnChange в текстовом поле и т.д., но, вероятно, все onFocus, Clicks, или что вы действительно хотите, чтобы сохранить трек.

В конце концов, вы можете получить что-то вроде btnLogin (5), что указывает на то, что пользователь нажимал на btnLogin 5 раз.

Обработка всех этих полученных данных является еще одной попыткой, поэтому я бы определенно отправил их в базу данных, а не получил, скажем, электронное письмо или каталог сервера, полный файлов статистики использования. В любом случае, вам понадобится что-то, чтобы обработать его и превратить его в графики или сортируемую статистику использования и т. Д.

2
ответ дан 29 November 2019 в 00:29
поделиться

Ну, насколько я знаю, я никогда не видел автоматического сбора статистики использования для приложений Swing.

На мой взгляд, самым простым способом реализации такой возможности было бы использование look'n'feel: таким образом, каждый компонент будет прозрачно ассоциироваться с наиболее подходящими логгерами (JCheckBox будет прослушиваться для проверки, в то время как в JSCrollBar будет записываться прокрутка).

Вы можете подумать о том, чтобы спросить Кирилла Гручникова об этой функции, но я боюсь, что даже Substance ее не реализует.

0
ответ дан 29 November 2019 в 00:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: