com.u2apple.tool.ui.MainFrame.java Source code

Java tutorial

Introduction

Here is the source code for com.u2apple.tool.ui.MainFrame.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.u2apple.tool.ui;

import com.shuame.wandoujia.bean.Device;
import com.shuame.wandoujia.bean.Modal;
import com.shuame.wandoujia.bean.ProductId;
import com.shuame.wandoujia.bean.Value;
import com.u2apple.tool.Profile;
import com.u2apple.tool.Source;
import com.u2apple.tool.cache.DeviceCache;
import com.u2apple.tool.ui.worker.FilterWorker;
import com.u2apple.tool.ui.worker.WhiteListDeviceRankingWorker;
import com.u2apple.tool.ui.worker.DeviceRankingWorker;
import com.u2apple.tool.ui.worker.DeviceWorker;
import com.u2apple.tool.ui.worker.RootRankingWorker;
import com.u2apple.tool.ui.worker.ModelWorker;
import com.u2apple.tool.ui.worker.DeviceQueryWorker;
import com.u2apple.tool.constant.Constants;
import com.u2apple.tool.dao.DeviceDao;
import com.u2apple.tool.filter.DevicePatternFilter;
import com.u2apple.tool.model.AndroidDevice;
import com.u2apple.tool.model.AndroidDeviceRanking;
import com.u2apple.tool.ui.table.DeviceDetailTableModel;
import com.u2apple.tool.ui.table.DeviceTableModel;
import com.u2apple.tool.core.KnockOffTool;
import com.u2apple.tool.core.TestCaseTool;
import com.u2apple.tool.dao.DeviceXmlDao;
import com.u2apple.tool.dao.DeviceXmlDaoJaxbImpl;
import com.u2apple.tool.ui.worker.ErrorDetectionWorker;
import com.u2apple.tool.ui.worker.ExcludeFilterWorker;
import com.u2apple.tool.ui.worker.FakeDetectionWorker;
import com.u2apple.tool.ui.worker.NewDeviceFilterWorker;
import com.u2apple.tool.ui.worker.QueryFilterWorker;
import com.u2apple.tool.ui.worker.ShuameMobileDeviceWorker;
import com.u2apple.tool.ui.worker.UnnormalDeviceFilterWorker;
import com.u2apple.tool.util.AndroidDeviceUtils;
import com.u2apple.tool.util.ConditionUtils;
import com.u2apple.tool.util.QueryPattern;
import java.awt.Color;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.SwingWorker;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListSelectionEvent;
import javax.xml.bind.JAXBException;
import javax.xml.bind.PropertyException;
import org.apache.commons.lang3.StringUtils;

/**
 *
 * @author Adam
 */
public class MainFrame extends javax.swing.JFrame {

    private final DeviceXmlDao deviceDao = new DeviceXmlDaoJaxbImpl();

    /**
     * Creates new form RecognitionToolJFrame
     */
    public MainFrame() {
        initComponents();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        buttonGroup1 = new javax.swing.ButtonGroup();
        jPanel1 = new javax.swing.JPanel();
        jPanel4 = new javax.swing.JPanel();
        jPanel5 = new javax.swing.JPanel();
        productIdLabel = new javax.swing.JLabel();
        productIdTextField = new javax.swing.JTextField();
        brandLabel = new javax.swing.JLabel();
        brandTextField = new javax.swing.JTextField();
        productLabel = new javax.swing.JLabel();
        productTextField = new javax.swing.JTextField();
        aliasLabel = new javax.swing.JLabel();
        aliasTextField = new javax.swing.JTextField();
        typeComboBox = new javax.swing.JComboBox();
        jLabel2 = new javax.swing.JLabel();
        enBrandLabel = new javax.swing.JLabel();
        enBrandTextField = new javax.swing.JTextField();
        enProductLabel = new javax.swing.JLabel();
        enProductTextField = new javax.swing.JTextField();
        jLabel4 = new javax.swing.JLabel();
        enAliasTextField = new javax.swing.JTextField();
        jPanel12 = new javax.swing.JPanel();
        jScrollPane4 = new javax.swing.JScrollPane();
        resultTextArea = new javax.swing.JTextArea();
        jPanel13 = new javax.swing.JPanel();
        connectButton = new javax.swing.JButton();
        deviceButton = new javax.swing.JButton();
        modelButton = new javax.swing.JButton();
        testCaseButton = new javax.swing.JButton();
        knockOffButton = new javax.swing.JButton();
        knockOffCheckBox = new javax.swing.JCheckBox();
        productIdButton = new javax.swing.JButton();
        updateModelButton = new javax.swing.JButton();
        conditionCheckBox = new javax.swing.JCheckBox();
        detailButton = new javax.swing.JButton();
        queryLimitSpinner = new javax.swing.JSpinner();
        allCheckBox = new javax.swing.JCheckBox();
        googleButton = new javax.swing.JButton();
        baiduButton = new javax.swing.JButton();
        sortButton = new javax.swing.JButton();
        updateTestCaseButton = new javax.swing.JButton();
        deviceCountButton = new javax.swing.JButton();
        addButton = new javax.swing.JButton();
        updateButton = new javax.swing.JButton();
        flushButton = new javax.swing.JButton();
        jPanel14 = new javax.swing.JPanel();
        resolutionLabel = new javax.swing.JLabel();
        resolutionComboBox = new javax.swing.JComboBox();
        partitionLabel = new javax.swing.JLabel();
        partitionTextField = new javax.swing.JTextField();
        jPanel6 = new javax.swing.JPanel();
        modelLabel = new javax.swing.JLabel();
        modelTextField = new javax.swing.JTextField();
        vidLabel = new javax.swing.JLabel();
        vidTextField = new javax.swing.JTextField();
        conditionComboBox = new javax.swing.JComboBox();
        conditionTextField = new javax.swing.JTextField();
        jLabel3 = new javax.swing.JLabel();
        vid2TextField = new javax.swing.JTextField();
        condition2ComboBox = new javax.swing.JComboBox();
        condition2TextField = new javax.swing.JTextField();
        jScrollPane1 = new javax.swing.JScrollPane();
        deviceTable = new javax.swing.JTable();
        queryPanel = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        daysSpinner = new javax.swing.JSpinner();
        deviceRankingButton = new javax.swing.JButton();
        errorRecognitionButton = new javax.swing.JButton();
        queryTextField = new javax.swing.JTextField();
        queryButton = new javax.swing.JButton();
        rootSpritButton = new javax.swing.JButton();
        filterButton = new javax.swing.JButton();
        unnormalDeviceFilterButton = new javax.swing.JButton();
        newDeviceFilterButton = new javax.swing.JButton();
        excludeFilterButton = new javax.swing.JButton();
        queryFilterButton = new javax.swing.JButton();
        removeDeviceButton = new javax.swing.JButton();
        othersDevicesButton = new javax.swing.JButton();
        fakeDetectionButton = new javax.swing.JButton();
        shuameMobileButton = new javax.swing.JButton();
        jPanel2 = new javax.swing.JPanel();
        jScrollPane2 = new javax.swing.JScrollPane();
        deviceDetailTable = new javax.swing.JTable();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Recognition Tool");

        jPanel1.setPreferredSize(new java.awt.Dimension(1900, 971));

        jPanel5.setBorder(javax.swing.BorderFactory.createTitledBorder("Device"));
        jPanel5.setFont(new java.awt.Font("", 0, 12)); // NOI18N

        productIdLabel.setFont(new java.awt.Font("", 0, 12)); // NOI18N
        productIdLabel.setText("Product ID:");

        productIdTextField.setFont(new java.awt.Font("", 0, 12)); // NOI18N
        productIdTextField.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                productIdTextFieldActionPerformed(evt);
            }
        });
        productIdTextField.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                productIdTextFieldPropertyChange(evt);
            }
        });
        productIdTextField.getDocument().addDocumentListener(new DocumentListener() {
            public void changedUpdate(DocumentEvent e) {
            }

            public void removeUpdate(DocumentEvent e) {
                String productId = productIdTextField.getText();
                boolean exists = deviceDao.productIdExists(productId);
                if (exists) {
                    productIdTextField.setBackground(Color.GREEN);
                } else {
                    productIdTextField.setBackground(Color.WHITE);
                }
            }

            public void insertUpdate(DocumentEvent e) {
                String productId = productIdTextField.getText();
                boolean exists = deviceDao.productIdExists(productId);
                if (exists) {
                    productIdTextField.setBackground(Color.GREEN);
                } else {
                    productIdTextField.setBackground(Color.WHITE);
                }
            }
        });

        brandLabel.setFont(new java.awt.Font("", 0, 12)); // NOI18N
        brandLabel.setText("Brand:");

        brandTextField.setFont(new java.awt.Font("", 0, 12)); // NOI18N

        productLabel.setFont(new java.awt.Font("", 0, 12)); // NOI18N
        productLabel.setText("Product:");

        productTextField.setFont(new java.awt.Font("", 0, 12)); // NOI18N

        aliasLabel.setFont(new java.awt.Font("", 0, 12)); // NOI18N
        aliasLabel.setText("Alias:");

        aliasTextField.setFont(new java.awt.Font("", 0, 12)); // NOI18N

        typeComboBox.setFont(new java.awt.Font("", 0, 12)); // NOI18N
        typeComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Phone&Pad", "Box", "Watch" }));

        jLabel2.setFont(new java.awt.Font("", 0, 12)); // NOI18N
        jLabel2.setText("Type:");

        enBrandLabel.setFont(new java.awt.Font("", 0, 12)); // NOI18N
        enBrandLabel.setText("EN Brand:");

        enBrandTextField.setFont(new java.awt.Font("", 0, 12)); // NOI18N
        enBrandTextField.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                enBrandTextFieldActionPerformed(evt);
            }
        });

        enProductLabel.setFont(new java.awt.Font("", 0, 12)); // NOI18N
        enProductLabel.setText("EN Product:");

        enProductTextField.setFont(new java.awt.Font("", 0, 12)); // NOI18N

        jLabel4.setFont(new java.awt.Font("", 0, 12)); // NOI18N
        jLabel4.setText("EN Alias:");

        enAliasTextField.setFont(new java.awt.Font("", 0, 12)); // NOI18N

        javax.swing.GroupLayout jPanel5Layout = new javax.swing.GroupLayout(jPanel5);
        jPanel5.setLayout(jPanel5Layout);
        jPanel5Layout.setHorizontalGroup(jPanel5Layout
                .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanel5Layout.createSequentialGroup()
                        .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                                .addComponent(enBrandLabel).addComponent(productIdLabel).addComponent(brandLabel))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addGroup(
                                jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                                        .addComponent(brandTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 208,
                                                Short.MAX_VALUE)
                                        .addComponent(productIdTextField).addComponent(enBrandTextField))
                        .addGap(18, 18, 18)
                        .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                                .addGroup(jPanel5Layout.createSequentialGroup().addGroup(jPanel5Layout
                                        .createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                                        .addComponent(productLabel).addComponent(jLabel2))
                                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                        .addGroup(jPanel5Layout
                                                .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                                .addComponent(typeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE,
                                                        javax.swing.GroupLayout.DEFAULT_SIZE,
                                                        javax.swing.GroupLayout.PREFERRED_SIZE)
                                                .addComponent(productTextField,
                                                        javax.swing.GroupLayout.PREFERRED_SIZE, 209,
                                                        javax.swing.GroupLayout.PREFERRED_SIZE)))
                                .addGroup(jPanel5Layout.createSequentialGroup().addComponent(enProductLabel)
                                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                        .addComponent(enProductTextField, javax.swing.GroupLayout.PREFERRED_SIZE,
                                                207, javax.swing.GroupLayout.PREFERRED_SIZE)))
                        .addGap(23, 23, 23)
                        .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                                .addComponent(aliasLabel).addComponent(jLabel4))
                        .addGap(18, 18, 18).addGroup(
                                jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                                        .addComponent(aliasTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 208,
                                                Short.MAX_VALUE)
                                        .addComponent(enAliasTextField))));
        jPanel5Layout.setVerticalGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanel5Layout.createSequentialGroup().addContainerGap().addGroup(jPanel5Layout
                        .createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(productIdLabel)
                        .addComponent(productIdTextField, javax.swing.GroupLayout.PREFERRED_SIZE,
                                javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(jLabel2).addComponent(typeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE,
                                javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGap(10, 10, 10)
                        .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                .addComponent(productLabel)
                                .addComponent(productTextField, javax.swing.GroupLayout.PREFERRED_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addComponent(brandLabel)
                                .addComponent(brandTextField, javax.swing.GroupLayout.PREFERRED_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addComponent(aliasLabel).addComponent(aliasTextField,
                                        javax.swing.GroupLayout.PREFERRED_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED,
                                javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                .addComponent(enBrandLabel)
                                .addComponent(enBrandTextField, javax.swing.GroupLayout.PREFERRED_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addComponent(enProductLabel)
                                .addComponent(enProductTextField, javax.swing.GroupLayout.PREFERRED_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addComponent(jLabel4).addComponent(enAliasTextField,
                                        javax.swing.GroupLayout.PREFERRED_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addContainerGap()));

        jPanel12.setBorder(javax.swing.BorderFactory.createTitledBorder("Result"));

        resultTextArea.setColumns(20);
        resultTextArea.setFont(new java.awt.Font("", 0, 13)); // NOI18N
        resultTextArea.setRows(5);
        jScrollPane4.setViewportView(resultTextArea);

        javax.swing.GroupLayout jPanel12Layout = new javax.swing.GroupLayout(jPanel12);
        jPanel12.setLayout(jPanel12Layout);
        jPanel12Layout
                .setHorizontalGroup(jPanel12Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(javax.swing.GroupLayout.Alignment.TRAILING,
                                jPanel12Layout.createSequentialGroup()
                                        .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                        .addComponent(jScrollPane4, javax.swing.GroupLayout.PREFERRED_SIZE, 864,
                                                javax.swing.GroupLayout.PREFERRED_SIZE)
                                        .addGap(35, 35, 35)));
        jPanel12Layout
                .setVerticalGroup(jPanel12Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(javax.swing.GroupLayout.Alignment.TRAILING,
                                jPanel12Layout.createSequentialGroup()
                                        .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                        .addComponent(jScrollPane4, javax.swing.GroupLayout.PREFERRED_SIZE, 114,
                                                javax.swing.GroupLayout.PREFERRED_SIZE)
                                        .addGap(19, 19, 19)));

        jPanel13.setBorder(javax.swing.BorderFactory.createTitledBorder("Action"));
        jPanel13.setFont(new java.awt.Font("", 0, 12)); // NOI18N

        connectButton.setFont(new java.awt.Font("", 0, 12)); // NOI18N
        connectButton.setIcon(
                new javax.swing.ImageIcon(getClass().getResource("/com/u2apple/tool/icon/New Filled-32.png"))); // NOI18N
        connectButton.setToolTipText("Get the latest device information.");
        connectButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                connectButtonActionPerformed(evt);
            }
        });

        deviceButton.setFont(new java.awt.Font("", 0, 12)); // NOI18N
        deviceButton.setIcon(
                new javax.swing.ImageIcon(getClass().getResource("/com/u2apple/tool/icon/Android-32.png"))); // NOI18N
        deviceButton.setToolTipText("Add device");
        deviceButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                deviceButtonActionPerformed(evt);
            }
        });

        modelButton.setFont(new java.awt.Font("", 0, 12)); // NOI18N
        modelButton.setIcon(
                new javax.swing.ImageIcon(getClass().getResource("/com/u2apple/tool/icon/Ruler Filled-32.png"))); // NOI18N
        modelButton.setToolTipText("Add model to system mode and recovery mode");
        modelButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                modelButtonActionPerformed(evt);
            }
        });

        testCaseButton.setFont(new java.awt.Font("", 0, 12)); // NOI18N
        testCaseButton.setIcon(
                new javax.swing.ImageIcon(getClass().getResource("/com/u2apple/tool/icon/Checked Filled-32.png"))); // NOI18N
        testCaseButton.setToolTipText("Add test case");
        testCaseButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                testCaseButtonActionPerformed(evt);
            }
        });

        knockOffButton.setFont(new java.awt.Font("", 0, 12)); // NOI18N
        knockOffButton.setIcon(
                new javax.swing.ImageIcon(getClass().getResource("/com/u2apple/tool/icon/Biotech Filled-32.png"))); // NOI18N
        knockOffButton.setToolTipText("Generate Knock-Off configuration");
        knockOffButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                knockOffButtonActionPerformed(evt);
            }
        });

        knockOffCheckBox.setFont(new java.awt.Font("", 0, 12)); // NOI18N
        knockOffCheckBox.setText("Knock-Off");

        productIdButton.setFont(new java.awt.Font("", 0, 12)); // NOI18N
        productIdButton.setIcon(
                new javax.swing.ImageIcon(getClass().getResource("/com/u2apple/tool/icon/RFID Signal-32.png"))); // NOI18N
        productIdButton.setToolTipText("Fullfill device information");
        productIdButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                productIdButtonActionPerformed(evt);
            }
        });

        updateModelButton.setFont(new java.awt.Font("", 0, 12)); // NOI18N
        updateModelButton
                .setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/u2apple/tool/icon/Ruler-32.png"))); // NOI18N
        updateModelButton.setToolTipText("Add model to current vid");
        updateModelButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                updateModelButtonActionPerformed(evt);
            }
        });

        conditionCheckBox.setFont(new java.awt.Font("", 0, 12)); // NOI18N
        conditionCheckBox.setText("Condition");

        detailButton.setFont(new java.awt.Font("", 0, 12)); // NOI18N
        detailButton.setIcon(new javax.swing.ImageIcon(
                getClass().getResource("/com/u2apple/tool/icon/View Details Filled-32.png"))); // NOI18N
        detailButton.setToolTipText("Device detail");
        detailButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                detailButtonActionPerformed(evt);
            }
        });

        queryLimitSpinner.setFont(new java.awt.Font("", 0, 12)); // NOI18N
        queryLimitSpinner.setModel(new javax.swing.SpinnerNumberModel(10, 1, 100, 10));

        allCheckBox.setFont(new java.awt.Font("", 0, 12)); // NOI18N
        allCheckBox.setText("All");

        googleButton.setFont(new java.awt.Font("", 0, 12)); // NOI18N
        googleButton.setIcon(
                new javax.swing.ImageIcon(getClass().getResource("/com/u2apple/tool/icon/Google Logo-32.png"))); // NOI18N
        googleButton.setToolTipText("Google");
        googleButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                googleButtonActionPerformed(evt);
            }
        });

        baiduButton.setFont(new java.awt.Font("", 0, 12)); // NOI18N
        baiduButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/u2apple/tool/icon/B-32.png"))); // NOI18N
        baiduButton.setToolTipText("Baidu");
        baiduButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                baiduButtonActionPerformed(evt);
            }
        });

        sortButton.setFont(new java.awt.Font("", 0, 12)); // NOI18N
        sortButton.setIcon(new javax.swing.ImageIcon(
                getClass().getResource("/com/u2apple/tool/icon/Descending Sorting-32.png"))); // NOI18N
        sortButton.setToolTipText("Sort models under a vid");
        sortButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                sortButtonActionPerformed(evt);
            }
        });

        updateTestCaseButton.setFont(new java.awt.Font("", 0, 12)); // NOI18N
        updateTestCaseButton.setIcon(new javax.swing.ImageIcon(
                getClass().getResource("/com/u2apple/tool/icon/Checkmark Filled-32.png"))); // NOI18N
        updateTestCaseButton.setToolTipText("Update test case");
        updateTestCaseButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                updateTestCaseButtonActionPerformed(evt);
            }
        });

        deviceCountButton.setFont(new java.awt.Font("", 0, 12)); // NOI18N
        deviceCountButton
                .setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/u2apple/tool/icon/Sigma-32.png"))); // NOI18N
        deviceCountButton.setToolTipText("Device Count");
        deviceCountButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                deviceCountButtonActionPerformed(evt);
            }
        });

        addButton.setIcon(
                new javax.swing.ImageIcon(getClass().getResource("/com/u2apple/tool/icon/Plus Math-32.png"))); // NOI18N
        addButton.setToolTipText("Add new device and model");
        addButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addButtonActionPerformed(evt);
            }
        });

        updateButton.setIcon(new javax.swing.ImageIcon(
                getClass().getResource("/com/u2apple/tool/icon/Available Updates-32.png"))); // NOI18N
        updateButton.setToolTipText("Update");
        updateButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                updateButtonActionPerformed(evt);
            }
        });

        flushButton
                .setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/u2apple/tool/icon/Save-32.png"))); // NOI18N
        flushButton.setToolTipText("Flush devices to file");
        flushButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                flushButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel13Layout = new javax.swing.GroupLayout(jPanel13);
        jPanel13.setLayout(jPanel13Layout);
        jPanel13Layout
                .setHorizontalGroup(jPanel13Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(jPanel13Layout.createSequentialGroup().addContainerGap().addGroup(jPanel13Layout
                                .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                                .addComponent(productIdButton, javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                .addComponent(deviceButton, javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                .addComponent(
                                        knockOffButton, javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                                .addGap(18, 18, 18)
                                .addGroup(
                                        jPanel13Layout
                                                .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                                .addGroup(jPanel13Layout.createSequentialGroup()
                                                        .addComponent(detailButton).addGap(18, 18, 18)
                                                        .addComponent(queryLimitSpinner,
                                                                javax.swing.GroupLayout.PREFERRED_SIZE, 65,
                                                                javax.swing.GroupLayout.PREFERRED_SIZE)
                                                        .addGap(18, 18, 18)
                                                        .addComponent(allCheckBox,
                                                                javax.swing.GroupLayout.PREFERRED_SIZE, 81,
                                                                javax.swing.GroupLayout.PREFERRED_SIZE)
                                                        .addGap(18, 18, 18).addComponent(connectButton)
                                                        .addGap(18, 18, 18).addComponent(deviceCountButton)
                                                        .addGap(18, 18, 18).addComponent(googleButton)
                                                        .addGap(18, 18, 18).addComponent(baiduButton))
                                                .addGroup(jPanel13Layout.createSequentialGroup()
                                                        .addGroup(jPanel13Layout
                                                                .createParallelGroup(
                                                                        javax.swing.GroupLayout.Alignment.TRAILING,
                                                                        false)
                                                                .addGroup(javax.swing.GroupLayout.Alignment.LEADING,
                                                                        jPanel13Layout.createSequentialGroup()
                                                                                .addComponent(testCaseButton)
                                                                                .addGap(18, 18, 18)
                                                                                .addComponent(updateTestCaseButton)
                                                                                .addGap(18, 18, 18)
                                                                                .addComponent(knockOffCheckBox)
                                                                                .addGap(18, 18, 18).addComponent(
                                                                                        sortButton,
                                                                                        javax.swing.GroupLayout.PREFERRED_SIZE,
                                                                                        0, Short.MAX_VALUE))
                                                                .addGroup(javax.swing.GroupLayout.Alignment.LEADING,
                                                                        jPanel13Layout.createSequentialGroup()
                                                                                .addComponent(modelButton)
                                                                                .addGap(18, 18, 18)
                                                                                .addComponent(updateModelButton)
                                                                                .addGap(18, 18, 18)
                                                                                .addComponent(conditionCheckBox)
                                                                                .addGap(18, 18, 18)
                                                                                .addComponent(addButton)))
                                                        .addGap(18, 18, 18).addComponent(updateButton)
                                                        .addGap(18, 18, 18).addComponent(flushButton)))
                                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)));
        jPanel13Layout.setVerticalGroup(jPanel13Layout
                .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanel13Layout.createSequentialGroup()
                        .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addGroup(jPanel13Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                .addGroup(jPanel13Layout
                                        .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                        .addComponent(detailButton).addComponent(connectButton)
                                        .addGroup(jPanel13Layout
                                                .createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                                .addComponent(queryLimitSpinner,
                                                        javax.swing.GroupLayout.PREFERRED_SIZE, 41,
                                                        javax.swing.GroupLayout.PREFERRED_SIZE)
                                                .addComponent(allCheckBox, javax.swing.GroupLayout.PREFERRED_SIZE,
                                                        41, javax.swing.GroupLayout.PREFERRED_SIZE))
                                        .addComponent(productIdButton, javax.swing.GroupLayout.Alignment.TRAILING)
                                        .addComponent(deviceCountButton).addComponent(googleButton))
                                .addComponent(baiduButton))
                        .addGap(18, 18, 18)
                        .addGroup(jPanel13Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                .addGroup(jPanel13Layout.createSequentialGroup().addGroup(jPanel13Layout
                                        .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                        .addGroup(jPanel13Layout
                                                .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING,
                                                        false)
                                                .addComponent(deviceButton, javax.swing.GroupLayout.DEFAULT_SIZE,
                                                        javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                                .addComponent(modelButton, javax.swing.GroupLayout.DEFAULT_SIZE,
                                                        javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                                .addComponent(updateModelButton,
                                                        javax.swing.GroupLayout.DEFAULT_SIZE,
                                                        javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                                .addComponent(addButton).addComponent(conditionCheckBox))
                                        .addComponent(updateButton)).addGap(18, 18, 18)
                                        .addGroup(jPanel13Layout
                                                .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                                .addComponent(testCaseButton).addComponent(knockOffButton)
                                                .addComponent(updateTestCaseButton).addComponent(sortButton)
                                                .addComponent(knockOffCheckBox)))
                                .addComponent(flushButton))));

        jPanel14.setBorder(javax.swing.BorderFactory.createTitledBorder("Knock-Off"));

        resolutionLabel.setFont(new java.awt.Font("", 0, 12)); // NOI18N
        resolutionLabel.setText("Resolution:");

        resolutionComboBox.setFont(new java.awt.Font("", 0, 12)); // NOI18N
        resolutionComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "320x480", "480x800",
                "480x854", "540x960", "720x1184", "720x1280", "800x1280", "1080x1776", "1080x1920", "1440x2392" }));
        resolutionComboBox.setSelectedIndex(5);

        partitionLabel.setFont(new java.awt.Font("", 0, 12)); // NOI18N
        partitionLabel.setText("Partition:");

        partitionTextField.setFont(new java.awt.Font("", 0, 12)); // NOI18N

        javax.swing.GroupLayout jPanel14Layout = new javax.swing.GroupLayout(jPanel14);
        jPanel14.setLayout(jPanel14Layout);
        jPanel14Layout.setHorizontalGroup(jPanel14Layout
                .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanel14Layout.createSequentialGroup()
                        .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addGroup(jPanel14Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                .addComponent(resolutionLabel).addComponent(partitionLabel))
                        .addGap(18, 18, 18)
                        .addGroup(jPanel14Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                .addComponent(resolutionComboBox, javax.swing.GroupLayout.PREFERRED_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addComponent(partitionTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 779,
                                        javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGap(24, 24, 24)));
        jPanel14Layout.setVerticalGroup(jPanel14Layout
                .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanel14Layout.createSequentialGroup()
                        .addGroup(jPanel14Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                .addComponent(resolutionLabel).addComponent(resolutionComboBox,
                                        javax.swing.GroupLayout.PREFERRED_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(jPanel14Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                .addComponent(partitionLabel).addComponent(partitionTextField,
                                        javax.swing.GroupLayout.PREFERRED_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)));

        jPanel6.setBorder(javax.swing.BorderFactory.createTitledBorder("Model"));
        jPanel6.setFont(new java.awt.Font("", 0, 12)); // NOI18N

        modelLabel.setFont(new java.awt.Font("", 0, 12)); // NOI18N
        modelLabel.setText("Model:");

        modelTextField.setFont(new java.awt.Font("", 0, 12)); // NOI18N
        modelTextField.getDocument().addDocumentListener(new DocumentListener() {
            public void changedUpdate(DocumentEvent e) {
                checkModelExistence();
            }

            public void removeUpdate(DocumentEvent e) {
                checkModelExistence();
            }

            public void insertUpdate(DocumentEvent e) {
                checkModelExistence();
            }
        });

        vidLabel.setFont(new java.awt.Font("", 0, 12)); // NOI18N
        vidLabel.setText("VID:");

        vidTextField.setFont(new java.awt.Font("", 0, 12)); // NOI18N
        vidTextField.getDocument().addDocumentListener(new DocumentListener() {
            public void changedUpdate(DocumentEvent e) {
                checkModelExistence();
            }

            public void removeUpdate(DocumentEvent e) {
                checkModelExistence();
            }

            public void insertUpdate(DocumentEvent e) {
                checkModelExistence();
            }
        });

        conditionComboBox.setFont(new java.awt.Font("", 0, 12)); // NOI18N
        conditionComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Board", "Brand", "Cpu",
                "Device", "Hardware", "Manufacturer", "Adb_Device", "Display_ID", "Product_Name" }));
        conditionComboBox.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                conditionComboBoxActionPerformed(evt);
            }
        });

        conditionTextField.setFont(new java.awt.Font("", 0, 12)); // NOI18N
        conditionTextField.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                conditionTextFieldFocusGained(evt);
            }
        });

        jLabel3.setFont(new java.awt.Font("", 0, 12)); // NOI18N
        jLabel3.setText("VID2:");

        vid2TextField.setFont(new java.awt.Font("", 0, 12)); // NOI18N

        condition2ComboBox.setFont(new java.awt.Font("", 0, 12)); // NOI18N
        condition2ComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Board", "Brand", "Cpu",
                "Device", "Hardware", "Manufacturer", "Adb_Device", "Display_ID", "Product_Name" }));
        condition2ComboBox.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                condition2ComboBoxActionPerformed(evt);
            }
        });

        condition2TextField.setFont(new java.awt.Font("", 0, 12)); // NOI18N

        javax.swing.GroupLayout jPanel6Layout = new javax.swing.GroupLayout(jPanel6);
        jPanel6.setLayout(jPanel6Layout);
        jPanel6Layout.setHorizontalGroup(jPanel6Layout
                .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanel6Layout.createSequentialGroup().addContainerGap()
                        .addGroup(jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                .addComponent(modelLabel)
                                .addComponent(vidLabel, javax.swing.GroupLayout.Alignment.TRAILING))
                        .addGap(18, 18, 18)
                        .addGroup(jPanel6Layout
                                .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                                .addGroup(jPanel6Layout.createSequentialGroup()
                                        .addComponent(vidTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 72,
                                                javax.swing.GroupLayout.PREFERRED_SIZE)
                                        .addGap(18, 18, 18).addComponent(jLabel3)
                                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                        .addComponent(vid2TextField, javax.swing.GroupLayout.PREFERRED_SIZE, 72,
                                                javax.swing.GroupLayout.PREFERRED_SIZE))
                                .addComponent(modelTextField))
                        .addGap(54, 54, 54)
                        .addGroup(
                                jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                                        .addComponent(conditionComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 90,
                                                javax.swing.GroupLayout.PREFERRED_SIZE)
                                        .addComponent(condition2ComboBox, 0, 1, Short.MAX_VALUE))
                        .addGroup(jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                .addGroup(jPanel6Layout.createSequentialGroup().addGap(4, 4, 4).addComponent(
                                        conditionTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 160,
                                        javax.swing.GroupLayout.PREFERRED_SIZE))
                                .addGroup(jPanel6Layout.createSequentialGroup()
                                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                        .addComponent(condition2TextField, javax.swing.GroupLayout.PREFERRED_SIZE,
                                                160, javax.swing.GroupLayout.PREFERRED_SIZE)))
                        .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)));
        jPanel6Layout.setVerticalGroup(jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanel6Layout.createSequentialGroup().addGroup(jPanel6Layout
                        .createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE).addComponent(vidLabel)
                        .addComponent(vidTextField, javax.swing.GroupLayout.PREFERRED_SIZE,
                                javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(jLabel3)
                        .addComponent(vid2TextField, javax.swing.GroupLayout.PREFERRED_SIZE,
                                javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(conditionComboBox, javax.swing.GroupLayout.PREFERRED_SIZE,
                                javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(conditionTextField, javax.swing.GroupLayout.PREFERRED_SIZE,
                                javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addGroup(jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                .addComponent(condition2ComboBox, javax.swing.GroupLayout.PREFERRED_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addComponent(condition2TextField, javax.swing.GroupLayout.PREFERRED_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addComponent(modelLabel).addComponent(modelTextField,
                                        javax.swing.GroupLayout.PREFERRED_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.PREFERRED_SIZE))));

        javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4);
        jPanel4.setLayout(jPanel4Layout);
        jPanel4Layout
                .setHorizontalGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(jPanel4Layout.createSequentialGroup().addContainerGap().addGroup(jPanel4Layout
                                .createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                                .addComponent(jPanel13, javax.swing.GroupLayout.Alignment.LEADING,
                                        javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE,
                                        Short.MAX_VALUE)
                                .addComponent(jPanel14, javax.swing.GroupLayout.Alignment.LEADING,
                                        javax.swing.GroupLayout.PREFERRED_SIZE, 899, Short.MAX_VALUE)
                                .addComponent(jPanel6, javax.swing.GroupLayout.Alignment.LEADING,
                                        javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE,
                                        Short.MAX_VALUE)
                                .addComponent(jPanel5, javax.swing.GroupLayout.Alignment.LEADING,
                                        javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE,
                                        Short.MAX_VALUE)
                                .addComponent(jPanel12, javax.swing.GroupLayout.PREFERRED_SIZE, 899,
                                        Short.MAX_VALUE))
                                .addContainerGap(88, Short.MAX_VALUE)));
        jPanel4Layout.setVerticalGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanel4Layout.createSequentialGroup()
                        .addComponent(jPanel5, javax.swing.GroupLayout.PREFERRED_SIZE,
                                javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(18, 18, 18)
                        .addComponent(jPanel6, javax.swing.GroupLayout.PREFERRED_SIZE,
                                javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(18, 18, 18)
                        .addComponent(jPanel14, javax.swing.GroupLayout.PREFERRED_SIZE,
                                javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(jPanel13, javax.swing.GroupLayout.PREFERRED_SIZE,
                                javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(jPanel12, javax.swing.GroupLayout.PREFERRED_SIZE, 156,
                                javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addContainerGap()));

        deviceTable.setFont(new java.awt.Font("", 0, 12)); // NOI18N
        deviceTable.setModel(new DeviceTableModel(new ArrayList<AndroidDeviceRanking>()));
        initRowSelectionEvent();
        jScrollPane1.setViewportView(deviceTable);

        jLabel1.setFont(new java.awt.Font("", 0, 12)); // NOI18N
        jLabel1.setText("Days:");

        daysSpinner.setFont(new java.awt.Font("", 0, 12)); // NOI18N
        daysSpinner.setModel(new javax.swing.SpinnerNumberModel(1, 0, 10, 1));

        deviceRankingButton.setFont(new java.awt.Font("", 0, 12)); // NOI18N
        deviceRankingButton.setIcon(new javax.swing.ImageIcon(
                getClass().getResource("/com/u2apple/tool/icon/Question Mark Filled-32.png"))); // NOI18N
        deviceRankingButton.setToolTipText("Unrecognized devices trend");
        deviceRankingButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                deviceRankingButtonActionPerformed(evt);
            }
        });

        errorRecognitionButton.setFont(new java.awt.Font("", 0, 12)); // NOI18N
        errorRecognitionButton.setIcon(
                new javax.swing.ImageIcon(getClass().getResource("/com/u2apple/tool/icon/Bug Filled-32.png"))); // NOI18N
        errorRecognitionButton.setToolTipText("Error detection");
        errorRecognitionButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                errorRecognitionButtonActionPerformed(evt);
            }
        });

        queryTextField.setFont(new java.awt.Font("", 0, 14)); // NOI18N
        queryTextField.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                queryTextFieldActionPerformed(evt);
            }
        });

        queryButton.setFont(new java.awt.Font("", 0, 12)); // NOI18N
        queryButton.setIcon(
                new javax.swing.ImageIcon(getClass().getResource("/com/u2apple/tool/icon/Search Filled-32.png"))); // NOI18N
        queryButton.setToolTipText("Query by model");
        queryButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                queryButtonActionPerformed(evt);
            }
        });

        rootSpritButton.setIcon(new javax.swing.ImageIcon(
                getClass().getResource("/com/u2apple/tool/icon/Restriction Shield Filled-32.png"))); // NOI18N
        rootSpritButton.setToolTipText("Mobile root spirit device ranking list");
        rootSpritButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                rootSpritButtonActionPerformed(evt);
            }
        });

        filterButton
                .setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/u2apple/tool/icon/Like-32.png"))); // NOI18N
        filterButton.setToolTipText("Pattern Filter");
        filterButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                filterButtonActionPerformed(evt);
            }
        });

        unnormalDeviceFilterButton.setIcon(
                new javax.swing.ImageIcon(getClass().getResource("/com/u2apple/tool/icon/Define Location-32.png"))); // NOI18N
        unnormalDeviceFilterButton.setToolTipText("Unnormal device filter");
        unnormalDeviceFilterButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                unnormalDeviceFilterButtonActionPerformed(evt);
            }
        });

        newDeviceFilterButton
                .setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/u2apple/tool/icon/New-32.png"))); // NOI18N
        newDeviceFilterButton.setToolTipText("Brand new devices filter");
        newDeviceFilterButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                newDeviceFilterButtonActionPerformed(evt);
            }
        });

        excludeFilterButton.setIcon(
                new javax.swing.ImageIcon(getClass().getResource("/com/u2apple/tool/icon/Not Equal-32.png"))); // NOI18N
        excludeFilterButton.setToolTipText("Exclude filter");
        excludeFilterButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                excludeFilterButtonActionPerformed(evt);
            }
        });

        queryFilterButton
                .setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/u2apple/tool/icon/Filter-32.png"))); // NOI18N
        queryFilterButton.setToolTipText("Query filter");
        queryFilterButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                queryFilterButtonActionPerformed(evt);
            }
        });

        removeDeviceButton
                .setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/u2apple/tool/icon/Delete-32.png"))); // NOI18N
        removeDeviceButton.setToolTipText("Remove row");
        removeDeviceButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                removeDeviceButtonActionPerformed(evt);
            }
        });

        othersDevicesButton
                .setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/u2apple/tool/icon/More-32.png"))); // NOI18N
        othersDevicesButton.setToolTipText("Others");
        othersDevicesButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                othersDevicesButtonActionPerformed(evt);
            }
        });

        fakeDetectionButton
                .setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/u2apple/tool/icon/Copy-32.png"))); // NOI18N
        fakeDetectionButton.setToolTipText("Fake detection");
        fakeDetectionButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                fakeDetectionButtonActionPerformed(evt);
            }
        });

        shuameMobileButton.setIcon(
                new javax.swing.ImageIcon(getClass().getResource("/com/u2apple/tool/icon/Question Mark-32.png"))); // NOI18N
        shuameMobileButton.setToolTipText("List unidentified devices of Shuame mobile");
        shuameMobileButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                shuameMobileButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout queryPanelLayout = new javax.swing.GroupLayout(queryPanel);
        queryPanel.setLayout(queryPanelLayout);
        queryPanelLayout.setHorizontalGroup(queryPanelLayout
                .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(queryPanelLayout.createSequentialGroup().addGroup(queryPanelLayout
                        .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                        .addGroup(queryPanelLayout.createSequentialGroup().addComponent(filterButton)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                .addComponent(othersDevicesButton)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                .addComponent(unnormalDeviceFilterButton)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(newDeviceFilterButton)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                .addComponent(excludeFilterButton)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(queryFilterButton).addGap(18, 18, 18).addComponent(jLabel1)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(daysSpinner, javax.swing.GroupLayout.PREFERRED_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(deviceRankingButton, javax.swing.GroupLayout.PREFERRED_SIZE, 68,
                                        javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED,
                                        javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                .addComponent(shuameMobileButton))
                        .addComponent(queryTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 679,
                                javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addGroup(queryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                .addGroup(queryPanelLayout.createSequentialGroup().addComponent(queryButton)
                                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                        .addComponent(removeDeviceButton))
                                .addGroup(queryPanelLayout.createSequentialGroup().addComponent(rootSpritButton)
                                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                        .addComponent(errorRecognitionButton)
                                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                        .addComponent(fakeDetectionButton)))
                        .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)));
        queryPanelLayout.setVerticalGroup(queryPanelLayout
                .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(queryPanelLayout.createSequentialGroup().addContainerGap().addGroup(queryPanelLayout
                        .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(queryPanelLayout.createSequentialGroup().addComponent(errorRecognitionButton)
                                .addGap(0, 0, Short.MAX_VALUE))
                        .addGroup(queryPanelLayout.createSequentialGroup().addGroup(queryPanelLayout
                                .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                .addComponent(fakeDetectionButton).addComponent(filterButton)
                                .addGroup(queryPanelLayout
                                        .createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                        .addComponent(daysSpinner, javax.swing.GroupLayout.PREFERRED_SIZE,
                                                javax.swing.GroupLayout.DEFAULT_SIZE,
                                                javax.swing.GroupLayout.PREFERRED_SIZE)
                                        .addComponent(jLabel1))
                                .addComponent(othersDevicesButton).addComponent(unnormalDeviceFilterButton)
                                .addComponent(newDeviceFilterButton).addComponent(excludeFilterButton)
                                .addComponent(queryFilterButton)
                                .addComponent(deviceRankingButton, javax.swing.GroupLayout.PREFERRED_SIZE, 41,
                                        javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addComponent(rootSpritButton).addComponent(shuameMobileButton)).addPreferredGap(
                                        javax.swing.LayoutStyle.ComponentPlacement.RELATED, 12, Short.MAX_VALUE)))
                        .addGroup(queryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                .addComponent(queryButton)
                                .addGroup(queryPanelLayout
                                        .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                        .addComponent(queryTextField, javax.swing.GroupLayout.Alignment.TRAILING,
                                                javax.swing.GroupLayout.PREFERRED_SIZE, 41,
                                                javax.swing.GroupLayout.PREFERRED_SIZE)
                                        .addComponent(removeDeviceButton)))
                        .addContainerGap()));

        deviceDetailTable.setFont(new java.awt.Font("", 0, 12)); // NOI18N
        deviceDetailTable.setModel(new DeviceDetailTableModel(new ArrayList<AndroidDevice>()));
        deviceDetailTable.setCellSelectionEnabled(true);
        jScrollPane2.setViewportView(deviceDetailTable);

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(jPanel2Layout
                .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanel2Layout.createSequentialGroup().addComponent(jScrollPane2,
                        javax.swing.GroupLayout.PREFERRED_SIZE, 1839, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(0, 1, Short.MAX_VALUE)));
        jPanel2Layout.setVerticalGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanel2Layout.createSequentialGroup()
                        .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 219, Short.MAX_VALUE)
                        .addContainerGap()));

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(jPanel1Layout
                .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanel1Layout.createSequentialGroup().addContainerGap()
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                .addGroup(jPanel1Layout.createSequentialGroup()
                                        .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE,
                                                javax.swing.GroupLayout.DEFAULT_SIZE,
                                                javax.swing.GroupLayout.PREFERRED_SIZE)
                                        .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                                .addGroup(jPanel1Layout.createSequentialGroup()
                                        .addGroup(jPanel1Layout
                                                .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                                .addComponent(queryPanel, javax.swing.GroupLayout.DEFAULT_SIZE,
                                                        javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE,
                                                        903, javax.swing.GroupLayout.PREFERRED_SIZE))
                                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                        .addComponent(jPanel4, javax.swing.GroupLayout.PREFERRED_SIZE,
                                                javax.swing.GroupLayout.DEFAULT_SIZE,
                                                javax.swing.GroupLayout.PREFERRED_SIZE)
                                        .addGap(18, 18, 18)))));
        jPanel1Layout.setVerticalGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanel1Layout.createSequentialGroup().addGap(0, 0, 0)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                .addGroup(jPanel1Layout.createSequentialGroup()
                                        .addComponent(queryPanel, javax.swing.GroupLayout.PREFERRED_SIZE,
                                                javax.swing.GroupLayout.DEFAULT_SIZE,
                                                javax.swing.GroupLayout.PREFERRED_SIZE)
                                        .addGap(4, 4, 4).addComponent(jScrollPane1,
                                                javax.swing.GroupLayout.PREFERRED_SIZE, 600,
                                                javax.swing.GroupLayout.PREFERRED_SIZE))
                                .addComponent(jPanel4, javax.swing.GroupLayout.PREFERRED_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED).addComponent(jPanel2,
                                javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE,
                                javax.swing.GroupLayout.PREFERRED_SIZE)));

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(
                javax.swing.GroupLayout.Alignment.TRAILING,
                layout.createSequentialGroup()
                        .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, 1856,
                                javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addContainerGap()));
        layout.setVerticalGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                        .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE,
                                javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)));

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void initRowSelectionEvent() {
        deviceTable.getSelectionModel().addListSelectionListener((ListSelectionEvent e) -> {
            int row = deviceTable.getSelectedRow();
            //When refresh table model data, row will be -1.
            if (row >= 0) {
                String vid = (String) deviceTable.getValueAt(row, 0);
                String model = (String) deviceTable.getValueAt(row, 1);
                String brand = (String) deviceTable.getValueAt(row, 2);
                vidTextField.setText(vid);
                modelTextField.setText(model);
                brandTextField.setText(brand);
            }
            //Auto fullfil device information.
            initDevice();
        });

        deviceTable.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent me) {
                JTable table = (JTable) me.getSource();
                Point p = me.getPoint();
                int row = table.rowAtPoint(p);
                if (me.getClickCount() == 2) {
                    String vid = (String) deviceTable.getValueAt(row, 0);
                    String model = (String) deviceTable.getValueAt(row, 1);
                    String brand = (String) deviceTable.getValueAt(row, 2);
                    AndroidDeviceRanking androidDevice = new AndroidDeviceRanking();
                    androidDevice.setVid(vid);
                    androidDevice.setRoProductModel(model);
                    androidDevice.setRoProductBrand(brand);
                    androidDevice.setCheckDate(new Date());
                    try {
                        DeviceCache.markDeviceChecked(androidDevice);
                    } catch (JAXBException ex) {
                        Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    DeviceTableModel tableModel = (DeviceTableModel) deviceTable.getModel();
                    tableModel.removeRow(row);
                }
            }
        });
    }

    private void deviceButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deviceButtonActionPerformed
        addDevice();
    }//GEN-LAST:event_deviceButtonActionPerformed

    private void addDevice() {
        String productId = productIdTextField.getText();
        String brand = brandTextField.getText();
        String product = productTextField.getText();
        String alias = aliasTextField.getText();

        //English
        String englishBrand = enBrandTextField.getText();
        String englishProductName = enProductTextField.getText();
        String englishAlias = enAliasTextField.getText();

        int type = typeComboBox.getSelectedIndex();
        if (StringUtils.isBlank(productId)) {
            JOptionPane.showMessageDialog(jPanel13, "Product ID should not be blank.");
        } else if (StringUtils.isBlank(brand)) {
            JOptionPane.showMessageDialog(jPanel13, "Brand should not be blank.");
        } else if (StringUtils.isBlank(product)) {
            JOptionPane.showMessageDialog(jPanel13, "Product should not be blank.");
        } else {

            String brandKey = AndroidDeviceUtils.getBrandByProductId(productId);
            Device device = new Device();
            device.setProductId(productId);
            device.setBrand(brandKey);
            device.setProduct(product);
            device.setAlias(alias);
            device.setChineseBrand(brand);
            device.setEnglishAlias(englishAlias);
            device.setEnglishBrand(englishBrand);
            device.setEnglishProduct(englishProductName);
            if (type != 0) {
                device.setType(type);
            }
            deviceDao.addDevice(device);
            resultTextArea.setText("Add device " + productId);
        }
    }

    private void productIdTextFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_productIdTextFieldActionPerformed

    }//GEN-LAST:event_productIdTextFieldActionPerformed

    private void knockOffButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_knockOffButtonActionPerformed
        String productId = StringUtils.trim(productIdTextField.getText());
        String resolution = StringUtils.trim((String) resolutionComboBox.getSelectedItem());
        String partition = StringUtils.trim(partitionTextField.getText());

        if (StringUtils.isBlank(productId)) {
            JOptionPane.showMessageDialog(jPanel13, "Product ID should not be blank.");
        } else if (StringUtils.isBlank(resolution)) {
            JOptionPane.showMessageDialog(jPanel13, "Resolution should not be blank.");
        } else if (StringUtils.isBlank(partition)) {
            JOptionPane.showMessageDialog(jPanel13, "Partition should not be blank.");
        } else {
            String config = KnockOffTool.getKnockOffConfig(productId, resolution, partition);
            resultTextArea.setText(config);
        }
    }//GEN-LAST:event_knockOffButtonActionPerformed

    private void testCaseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_testCaseButtonActionPerformed
        addTestCase();
    }//GEN-LAST:event_testCaseButtonActionPerformed

    private void addTestCase() {
        final String productId = StringUtils.trim(productIdTextField.getText());
        final String vid = StringUtils.trim(vidTextField.getText());
        final String roProductModel = StringUtils.trim(modelTextField.getText());
        final String vid2 = StringUtils.trim(vid2TextField.getText());
        //Validation.
        if (StringUtils.isBlank(productId)) {
            JOptionPane.showMessageDialog(jPanel13, "Product ID should not be blank.");
        } else if (StringUtils.isBlank(vid)) {
            JOptionPane.showMessageDialog(jPanel13, "Vid should not be blank.");
        } else {
            //Generate test case.
            Set<String> vidSet = new HashSet<>();
            vidSet.add(vid);
            if (!StringUtils.equalsIgnoreCase(vid, Constants.RECOVERY_VID)) {
                vidSet.add(Constants.RECOVERY_VID);
            }
            if (!StringUtils.equalsIgnoreCase(vid, Constants.COMMON_VID)) {
                vidSet.add(Constants.COMMON_VID);
            }
            if (StringUtils.isNotBlank(vid2)) {
                vidSet.add(vid2);
            }
            generateTestCase(vidSet.toArray(new String[vidSet.size()]), roProductModel, productId);
        }
    }

    private void generateTestCase(String[] vids, String roProductModel, String productId) {
        //Generate test case.
        String text;
        text = "Add test case for " + Arrays.toString(vids) + " model " + roProductModel;
        //Setting required properties.
        AndroidDevice androidDevice = new AndroidDevice();
        //            androidDevice.setVid(vid);
        androidDevice.setRoProductModel(roProductModel);
        androidDevice.setProductId(productId);
        androidDevice.setVids(vids);

        if (knockOffCheckBox.isSelected()) {
            //TODO: knock off case.
            String partitions = StringUtils.trim(partitionTextField.getText());
            String resolution = StringUtils.trim((String) resolutionComboBox.getSelectedItem());
            text = TestCaseTool.generateDeviceTestCase(productId, vids[0], roProductModel, resolution, partitions);
        }

        if (conditionCheckBox.isSelected()) {
            //1st condition.
            String condition = (String) conditionComboBox.getSelectedItem();
            String conditionValue = conditionTextField.getText();
            if (StringUtils.isNotBlank(conditionValue)) {
                switch (condition) {
                case "Board":
                    androidDevice.setRoProductBoard(conditionValue);
                    break;
                case "Brand":
                    //                        String roProductBrand = AndroidDeviceUtils.getBrandByProductId(productId);
                    androidDevice.setRoProductBrand(conditionValue);
                    break;
                case "Cpu":
                    androidDevice.setCpuHardware(conditionValue);
                    break;
                case "Device":
                    androidDevice.setRoProductDevice(conditionValue);
                    break;
                case "Hardware":
                    androidDevice.setRoHardware(conditionValue);
                    break;
                case "Manufacturer":
                    androidDevice.setRoProductManufacturer(conditionValue);
                    break;
                case "Adb_Device":
                    androidDevice.setAdbDevice(conditionValue);
                    break;
                case "Display_ID":
                    androidDevice.setRoBuildDisplayId(conditionValue);
                    break;
                case "Product_Name":
                    androidDevice.setRoProductName(conditionValue);
                    break;
                }
            }

            //2nd condition.
            String condition2 = (String) condition2ComboBox.getSelectedItem();
            String condition2Value = condition2TextField.getText();
            if (StringUtils.isNotBlank(condition2Value) && !condition.equalsIgnoreCase(condition2)) {
                switch (condition2) {
                case "Board":
                    androidDevice.setRoProductBoard(condition2Value);
                    break;
                case "Brand":
                    androidDevice.setRoProductBrand(condition2Value);
                    break;
                case "Cpu":
                    androidDevice.setCpuHardware(condition2Value);
                    break;
                case "Device":
                    androidDevice.setRoProductDevice(condition2Value);
                    break;
                case "Hardware":
                    androidDevice.setRoHardware(condition2Value);
                    break;
                case "Manufacturer":
                    androidDevice.setRoProductManufacturer(condition2Value);
                    break;
                case "Adb_Device":
                    androidDevice.setAdbDevice(condition2Value);
                    break;
                case "Display_ID":
                    androidDevice.setRoBuildDisplayId(condition2Value);
                    break;
                case "Product_Name":
                    androidDevice.setRoProductName(condition2Value);
                    break;
                }
            }

        }
        TestCaseTool.generateTestCase(androidDevice);
        resultTextArea.append(System.getProperty("line.separator"));
        resultTextArea.append(text);
    }

    private void connectButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_connectButtonActionPerformed
        AndroidDevice device = new DeviceDao().getLatestDevice();
        if (device != null) {
            productIdTextField.setText(device.getProductId());
            brandTextField.setText(device.getRoProductBrand());
            vidTextField.setText(device.getVid());
            modelTextField.setText(device.getRoProductModel());
            partitionTextField.setText(device.getPartitions());
            resolutionComboBox.setSelectedItem(device.getResolution());
        }
    }//GEN-LAST:event_connectButtonActionPerformed

    private void deviceRankingButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deviceRankingButtonActionPerformed
        int days = (int) daysSpinner.getValue();
        new DeviceRankingWorker(days, this.deviceTable).execute();
        Profile.SOURCE = Source.Shuame;
    }//GEN-LAST:event_deviceRankingButtonActionPerformed

    private void productIdButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_productIdButtonActionPerformed
        initDevice();
    }//GEN-LAST:event_productIdButtonActionPerformed

    private void initDevice() {
        String brand = brandTextField.getText();
        String model = modelTextField.getText();
        String productId = AndroidDeviceUtils.buildProductId(brand, model);
        String productName = AndroidDeviceUtils.getProductName(brand, model);
        productIdTextField.setText(productId);
        String brandOfProductId = AndroidDeviceUtils.getBrandByProductId(productId);
        //Chinese
        brandTextField.setText(deviceDao.getChineseBrand(brandOfProductId));
        productTextField.setText(productName);
        aliasTextField.setText("");
        //English
        enBrandTextField.setText(deviceDao.getEnglishBrand(brandOfProductId));
        enProductTextField.setText(productName);
        enAliasTextField.setText("");
        //Update condition checkbox.
        if (StringUtils.containsIgnoreCase(model, brand)) {
            conditionCheckBox.setSelected(false);
        } else {
            conditionCheckBox.setSelected(true);
        }

        //Initialize conditon text field.
        if (conditionComboBox.getSelectedIndex() != 1) {
            conditionComboBox.setSelectedIndex(1);
        }
        //ConditionComboBox must be set before conditionTextField.
        conditionTextField.setText(brand);
        condition2TextField.setText("");
        typeComboBox.setSelectedIndex(0);
        vid2TextField.setText("");
    }

    private void checkModelExistence() {
        String vid = vidTextField.getText();
        String model = modelTextField.getText();
        if (StringUtils.isNotBlank(vid) && StringUtils.isNotBlank(model)) {
            new ModelWorker(vid, model, modelTextField).execute();
        }
    }

    private void modelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_modelButtonActionPerformed
        addModel();
    }//GEN-LAST:event_modelButtonActionPerformed

    private void addModel() {
        String productId = productIdTextField.getText();
        String model = modelTextField.getText();
        String vid = vidTextField.getText();
        String vid2 = vid2TextField.getText();

        if (StringUtils.isBlank(productId)) {
            JOptionPane.showMessageDialog(jPanel13, "Product ID should not be blank.");
        } else if (StringUtils.isBlank(model)) {
            JOptionPane.showMessageDialog(jPanel13, "Model should not be blank.");
        } else if (StringUtils.isBlank(vid)) {
            JOptionPane.showMessageDialog(jPanel13, "vid should not be blank.");
        } else {
            Set<String> vidSet = new HashSet<>();
            vidSet.add(vid);
            if (!StringUtils.equalsIgnoreCase(Constants.RECOVERY_VID, vid)) {
                vidSet.add(Constants.RECOVERY_VID);
            }

            if (!StringUtils.equalsIgnoreCase(Constants.COMMON_VID, vid)) {
                vidSet.add(Constants.COMMON_VID);
            }

            if (StringUtils.isNotBlank(vid2)) {
                vidSet.add(vid2);
            }
            String[] vids = vidSet.toArray(new String[vidSet.size()]);

            Map<String, String> conditions = new LinkedHashMap<>();
            if (conditionCheckBox.isSelected()) {
                //1st conditon.
                String condition = (String) conditionComboBox.getSelectedItem();
                String conditionValue = conditionTextField.getText();
                if (StringUtils.isNotBlank(conditionValue)) {
                    conditions.put(condition.toLowerCase(), conditionValue);
                }

                //2nd condition value.
                String condition2 = (String) condition2ComboBox.getSelectedItem();
                String condition2Value = condition2TextField.getText();
                if (StringUtils.isNotBlank(condition2Value) && !condition2.equalsIgnoreCase(condition)) {
                    conditions.put(condition2.toLowerCase(), condition2Value);
                }
            }

            addModel(productId, conditions, model, vids);

            //Update log
            //            DeviceLogDao dao = new DeviceLogDao();
            //            dao.updateDeviceLog(productId, vids, aModel);
            resultTextArea.append(System.getProperty("line.separator"));
            resultTextArea.append("Add model " + model + " to " + Arrays.toString(vids));
        }
    }

    private void errorRecognitionButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_errorRecognitionButtonActionPerformed
        new ErrorDetectionWorker(this.deviceTable).execute();
        Profile.SOURCE = Source.Shuame;
        //        IdentifyAnalyticsService service = new IdentifyAnalyticsService();
        //        try {
        //            List<List<AndroidDeviceRanking>> deviceList = service.analytics();
        //            String csv = CsvUtils.toCsv(deviceList);
        //            Files.write(Paths.get(Constants.IDENTIFY_ANALYTICS_FILE), csv.getBytes());
        //        } catch (SQLException | IOException ex) {
        //            JOptionPane.showMessageDialog(jPanel13, ex.getMessage());
        //        }
        //        JOptionPane.showMessageDialog(jPanel13, "Identity analytics result has been generated.");
    }//GEN-LAST:event_errorRecognitionButtonActionPerformed

    private void updateModelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_updateModelButtonActionPerformed
        updateModel();
    }//GEN-LAST:event_updateModelButtonActionPerformed

    private void updateModel() {
        String productId = productIdTextField.getText();
        String model = modelTextField.getText();
        String vid = vidTextField.getText();
        if (StringUtils.isBlank(productId)) {
            JOptionPane.showMessageDialog(jPanel13, "Product ID should not be blank.");
        } else if (StringUtils.isBlank(vid)) {
            JOptionPane.showMessageDialog(jPanel13, "vid should not be blank.");
        } else {
            String[] vids = { vid };
            Map<String, String> conditions = new LinkedHashMap<>();
            if (conditionCheckBox.isSelected()) {
                //1st conditon.
                String condition = (String) conditionComboBox.getSelectedItem();
                String conditionValue = conditionTextField.getText();
                if (StringUtils.isNotBlank(conditionValue)) {
                    conditions.put(condition.toLowerCase(), conditionValue);
                }

                //2nd condition value.
                String condition2 = (String) condition2ComboBox.getSelectedItem();
                String condition2Value = condition2TextField.getText();
                if (StringUtils.isNotBlank(condition2Value) && !condition2.equalsIgnoreCase(condition)) {
                    conditions.put(condition2.toLowerCase(), condition2Value);
                }
            }
            addModel(productId, conditions, model, vids);
            resultTextArea.append(System.getProperty("line.separator"));
            resultTextArea.append("Add model " + model + " to " + Arrays.toString(vids));
        }
    }

    /** ?Modals*/
    private void addModel(String productId, Map<String, String> conditions, String model, String[] vids) {
        Modal newModel = new Modal();
        ProductId newProductId = new ProductId();
        newProductId.setValue(productId);
        newProductId.setCondition(ConditionUtils.build(conditions));
        List<ProductId> productIds = new ArrayList<>();
        productIds.add(newProductId);
        newModel.setProductId(productIds);
        Value value = new Value();
        if (StringUtils.isBlank(model)) {
            //????.
            model = Constants.BLANK;
        }
        value.setValue(model);
        List<Value> values = new ArrayList<>();
        values.add(value);
        newModel.setValues(values);
        deviceDao.addModel(vids, newModel);
    }

    private void queryButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_queryButtonActionPerformed
        String query = queryTextField.getText();
        int limit = (int) queryLimitSpinner.getValue();
        if (StringUtils.isNotBlank(query)) {
            if (QueryPattern.isMacAddress(query) || QueryPattern.isQQ(query)) {
                new DeviceWorker(query, limit, this.deviceDetailTable).execute();
            } else {
                new DeviceQueryWorker(query, this.deviceTable).execute();
            }
        } else {
            JOptionPane.showMessageDialog(jPanel1, "Query should not be blank.");
        }
    }//GEN-LAST:event_queryButtonActionPerformed

    private void detailButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_detailButtonActionPerformed
        String vid = vidTextField.getText();
        String brand = conditionTextField.getText();
        String model = modelTextField.getText();
        int limit = (int) queryLimitSpinner.getValue();
        boolean isAll = allCheckBox.isSelected();
        if (StringUtils.isBlank(vid)) {
            JOptionPane.showMessageDialog(jPanel1, "Vid should not be blank.");
        } else if (model == null) {
            JOptionPane.showMessageDialog(jPanel1, "Model should not be blank.");
        } else {
            SwingWorker<List<AndroidDevice>, Void> deviceWorker = new DeviceWorker(vid, brand, model, limit, isAll,
                    Profile.SOURCE, this.deviceDetailTable);
            deviceWorker.execute();
        }

    }//GEN-LAST:event_detailButtonActionPerformed

    private void productIdTextFieldPropertyChange(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_productIdTextFieldPropertyChange

    }//GEN-LAST:event_productIdTextFieldPropertyChange

    private void googleButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_googleButtonActionPerformed
        String model = modelTextField.getText();
        String brand = brandTextField.getText();
        if (StringUtils.isBlank(brand)) {
            String productId = productIdTextField.getText();
            brand = AndroidDeviceUtils.getBrandByProductId(productId);
        }
        if (StringUtils.isNotBlank(brand) || StringUtils.isNotBlank(model)) {

            StringBuilder commandBuilder = new StringBuilder();
            commandBuilder.append("explorer \"https://www.google.com/webhp?hl=zh-CN#hl=zh-CN&q=");
            //Append query.
            if (StringUtils.equalsIgnoreCase(model, brand) || StringUtils.containsIgnoreCase(model, brand)) {
                commandBuilder.append(model);
            } else {
                commandBuilder.append(brand);
                commandBuilder.append(" ");
                commandBuilder.append(model);
            }
            commandBuilder.append(" \"");
            try {
                Runtime.getRuntime().exec(commandBuilder.toString());
            } catch (IOException ex) {
                Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex);
            }
        } else {
            JOptionPane.showMessageDialog(jPanel13, "Brand and Model both are blank.");
        }
    }//GEN-LAST:event_googleButtonActionPerformed

    private void baiduButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_baiduButtonActionPerformed
        String model = modelTextField.getText();
        String brand = brandTextField.getText();
        if (StringUtils.isBlank(brand)) {
            String productId = productIdTextField.getText();
            brand = AndroidDeviceUtils.getBrandByProductId(productId);
        }

        if (StringUtils.isNotBlank(brand) || StringUtils.isNotBlank(model)) {

            StringBuilder commandBuilder = new StringBuilder();
            commandBuilder.append("explorer \"http://www.baidu.com/s?wd=");
            //Append query.
            if (StringUtils.equalsIgnoreCase(model, brand) || StringUtils.containsIgnoreCase(model, brand)) {
                commandBuilder.append(model);
            } else {
                commandBuilder.append(brand);
                commandBuilder.append(" ");
                commandBuilder.append(model);
            }
            commandBuilder.append(" \"");
            try {
                Runtime.getRuntime().exec(commandBuilder.toString());
            } catch (IOException ex) {
                Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex);
            }
        } else {
            JOptionPane.showMessageDialog(jPanel13, "Brand and Model both are blank.");
        }
    }//GEN-LAST:event_baiduButtonActionPerformed

    private void sortButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_sortButtonActionPerformed
        String vid = vidTextField.getText();
        if (StringUtils.isNotBlank(vid) && vid.length() == 4) {
            //            RecognitionTool.sortModel(vid);
            deviceDao.format(vid);
            resultTextArea.setText("Sorting  " + vid + " is done.");
        } else {
            JOptionPane.showMessageDialog(jPanel13, "Vid is blank or invalid.");
        }
    }//GEN-LAST:event_sortButtonActionPerformed

    private void rootSpritButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rootSpritButtonActionPerformed
        int days = (int) daysSpinner.getValue();
        new RootRankingWorker(days, this.deviceTable).execute();
        Profile.SOURCE = Source.RootSpirit;
    }//GEN-LAST:event_rootSpritButtonActionPerformed

    private void updateTestCaseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_updateTestCaseButtonActionPerformed
        updateTestCase();
    }//GEN-LAST:event_updateTestCaseButtonActionPerformed

    private void updateTestCase() {
        final String productId = StringUtils.trim(productIdTextField.getText());
        final String vid = StringUtils.trim((String) vidTextField.getText());
        final String roProductModel = StringUtils.trim(modelTextField.getText());
        //Validation.
        if (StringUtils.isBlank(productId)) {
            JOptionPane.showMessageDialog(jPanel13, "Product ID should not be blank.");
        } else if (StringUtils.isBlank(vid)) {
            JOptionPane.showMessageDialog(jPanel13, "Vid should not be blank.");
        } else {
            //Generate test case.
            Set<String> vidSet = new HashSet<>();
            vidSet.add(vid);
            generateTestCase(vidSet.toArray(new String[vidSet.size()]), roProductModel, productId);
        }
    }

    private void deviceCountButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deviceCountButtonActionPerformed
        //            int deviceCount = RecognitionTool.getDeviceCount();
        int deviceCount = deviceDao.deviceCount();
        resultTextArea.setText("Device count: " + deviceCount);

    }//GEN-LAST:event_deviceCountButtonActionPerformed

    private void filterButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_filterButtonActionPerformed
        DeviceTableModel deviceTableModel = (DeviceTableModel) deviceTable.getModel();
        List<AndroidDeviceRanking> androidDevices = deviceTableModel.getAndroidDevices();
        if (androidDevices != null && androidDevices.size() > 0) {
            new FilterWorker(androidDevices, deviceTable).execute();
        }
    }//GEN-LAST:event_filterButtonActionPerformed

    private void unnormalDeviceFilterButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_unnormalDeviceFilterButtonActionPerformed
        //        String vid = vidTextField.getText();
        //        String model = modelTextField.getText();
        //        String brand = conditionTextField.getText();
        //        AndroidDevice androidDevice = new AndroidDevice();
        //        androidDevice.setVid(vid);
        //        androidDevice.setRoProductModel(model);
        //        androidDevice.setRoProductBrand(brand);
        //        DevicePatternFilter filter = new DevicePatternFilter();
        //        boolean matches = filter.matches(androidDevice);
        //        if (matches) {
        //            resultTextArea.setText(model + " Match");
        //        } else {
        //            resultTextArea.setText(model + " Not match");
        //        }
        DeviceTableModel deviceTableModel = (DeviceTableModel) deviceTable.getModel();
        List<AndroidDeviceRanking> androidDevices = deviceTableModel.getAndroidDevices();
        if (androidDevices != null && androidDevices.size() > 0) {
            new UnnormalDeviceFilterWorker(androidDevices, deviceTable).execute();
        }
    }//GEN-LAST:event_unnormalDeviceFilterButtonActionPerformed

    private void addButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addButtonActionPerformed
        addDevice();
        addModel();
        addTestCase();
    }//GEN-LAST:event_addButtonActionPerformed

    private void updateButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_updateButtonActionPerformed
        updateModel();
        updateTestCase();
    }//GEN-LAST:event_updateButtonActionPerformed

    private void newDeviceFilterButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newDeviceFilterButtonActionPerformed
        DeviceTableModel deviceTableModel = (DeviceTableModel) deviceTable.getModel();
        List<AndroidDeviceRanking> androidDevices = deviceTableModel.getAndroidDevices();
        if (androidDevices != null && androidDevices.size() > 0) {
            new NewDeviceFilterWorker(androidDevices, deviceTable).execute();
        }
    }//GEN-LAST:event_newDeviceFilterButtonActionPerformed

    private void excludeFilterButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_excludeFilterButtonActionPerformed
        DeviceTableModel deviceTableModel = (DeviceTableModel) deviceTable.getModel();
        List<AndroidDeviceRanking> androidDevices = deviceTableModel.getAndroidDevices();
        if (androidDevices != null && androidDevices.size() > 0) {
            new ExcludeFilterWorker(androidDevices, deviceTable).execute();
        }
    }//GEN-LAST:event_excludeFilterButtonActionPerformed

    private void queryFilterButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_queryFilterButtonActionPerformed
        DeviceTableModel deviceTableModel = (DeviceTableModel) deviceTable.getModel();
        String query = queryTextField.getText();
        List<AndroidDeviceRanking> androidDevices = deviceTableModel.getAndroidDevices();
        if (androidDevices != null && androidDevices.size() > 0 && StringUtils.isNotBlank(query)) {
            new QueryFilterWorker(androidDevices, deviceTable, query).execute();
        }
    }//GEN-LAST:event_queryFilterButtonActionPerformed

    private void queryTextFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_queryTextFieldActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_queryTextFieldActionPerformed

    private void removeDeviceButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_removeDeviceButtonActionPerformed
        DeviceTableModel tableModel = (DeviceTableModel) deviceTable.getModel();
        int[] rows = deviceTable.getSelectedRows();
        for (int row : rows) {
            tableModel.removeRow(row);
        }
    }//GEN-LAST:event_removeDeviceButtonActionPerformed

    private void othersDevicesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_othersDevicesButtonActionPerformed
        DeviceTableModel deviceTableModel = (DeviceTableModel) deviceTable.getModel();
        List<AndroidDeviceRanking> androidDevices = deviceTableModel.getAndroidDevices();
        if (androidDevices != null && !androidDevices.isEmpty()) {
            new FilterWorker(androidDevices, deviceTable, true).execute();
        }
    }//GEN-LAST:event_othersDevicesButtonActionPerformed

    private void condition2ComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_condition2ComboBoxActionPerformed
        String condition = (String) condition2ComboBox.getSelectedItem();
        DeviceDetailTableModel tableModel = (DeviceDetailTableModel) deviceDetailTable.getModel();
        if (tableModel != null) {
            List<AndroidDevice> devices = tableModel.getAndroidDevices();
            if (devices != null && !devices.isEmpty()) {
                AndroidDevice device = devices.get(0);
                switch (condition) {
                case "Board":
                    condition2TextField.setText(device.getRoProductBoard());
                    break;
                case "Brand":
                    condition2TextField.setText(device.getRoProductBrand());
                    break;
                case "Cpu":
                    condition2TextField.setText(device.getCpuHardware());
                    break;
                case "Device":
                    condition2TextField.setText(device.getRoProductDevice());
                    break;
                case "Hardware":
                    condition2TextField.setText(device.getRoHardware());
                    break;
                case "Manufacturer":
                    condition2TextField.setText(device.getRoProductManufacturer());
                    break;
                case "Adb_Device":
                    condition2TextField.setText(device.getAdbDevice());
                    break;
                case "Display_ID":
                    condition2TextField.setText(device.getRoBuildDisplayId());
                    break;
                case "Product_Name":
                    condition2TextField.setText(device.getRoProductName());
                    break;
                }
            }
        }
    }//GEN-LAST:event_condition2ComboBoxActionPerformed

    private void conditionTextFieldFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_conditionTextFieldFocusGained
        conditionCheckBox.setSelected(true);
    }//GEN-LAST:event_conditionTextFieldFocusGained

    private void conditionComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_conditionComboBoxActionPerformed
        String condition = (String) conditionComboBox.getSelectedItem();
        DeviceDetailTableModel tableModel = (DeviceDetailTableModel) deviceDetailTable.getModel();
        if (tableModel != null) {
            List<AndroidDevice> devices = tableModel.getAndroidDevices();
            if (devices != null && !devices.isEmpty()) {
                AndroidDevice device = devices.get(0);
                switch (condition) {
                case "Board":
                    conditionTextField.setText(device.getRoProductBoard());
                    break;
                case "Brand":
                    conditionTextField.setText(device.getRoProductBrand());
                    break;
                case "Cpu":
                    conditionTextField.setText(device.getCpuHardware());
                    break;
                case "Device":
                    conditionTextField.setText(device.getRoProductDevice());
                    break;
                case "Hardware":
                    conditionTextField.setText(device.getRoHardware());
                    break;
                case "Manufacturer":
                    conditionTextField.setText(device.getRoProductManufacturer());
                    break;
                case "Adb_Device":
                    conditionTextField.setText(device.getAdbDevice());
                    break;
                case "Display_ID":
                    conditionTextField.setText(device.getRoBuildDisplayId());
                    break;
                case "Product_Name":
                    condition2TextField.setText(device.getRoProductName());
                    break;
                }
            }
        }
    }//GEN-LAST:event_conditionComboBoxActionPerformed

    private void flushButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_flushButtonActionPerformed
        try {
            deviceDao.flush();
            resultTextArea.setText("Flush is done.");
        } catch (JAXBException | IOException ex) {
            resultTextArea.setText("Flush is failed as " + ex.getMessage());
        }
    }//GEN-LAST:event_flushButtonActionPerformed

    private void fakeDetectionButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fakeDetectionButtonActionPerformed
        new FakeDetectionWorker(this.deviceTable).execute();
    }//GEN-LAST:event_fakeDetectionButtonActionPerformed

    private void shuameMobileButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_shuameMobileButtonActionPerformed
        int days = (int) daysSpinner.getValue();
        new ShuameMobileDeviceWorker(days, this.deviceTable).execute();
        Profile.SOURCE = Source.ShuameMobile;
    }//GEN-LAST:event_shuameMobileButtonActionPerformed

    private void enBrandTextFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_enBrandTextFieldActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_enBrandTextFieldActionPerformed

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException
                | javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(MainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null,
                    ex);
        }
        //</editor-fold>
        //</editor-fold>
        //</editor-fold>
        //</editor-fold>

        //</editor-fold>
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new MainFrame().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton addButton;
    private javax.swing.JLabel aliasLabel;
    private javax.swing.JTextField aliasTextField;
    private javax.swing.JCheckBox allCheckBox;
    private javax.swing.JButton baiduButton;
    private javax.swing.JLabel brandLabel;
    private javax.swing.JTextField brandTextField;
    private javax.swing.ButtonGroup buttonGroup1;
    private javax.swing.JComboBox condition2ComboBox;
    private javax.swing.JTextField condition2TextField;
    private javax.swing.JCheckBox conditionCheckBox;
    private javax.swing.JComboBox conditionComboBox;
    private javax.swing.JTextField conditionTextField;
    private javax.swing.JButton connectButton;
    private javax.swing.JSpinner daysSpinner;
    private javax.swing.JButton detailButton;
    private javax.swing.JButton deviceButton;
    private javax.swing.JButton deviceCountButton;
    private javax.swing.JTable deviceDetailTable;
    private javax.swing.JButton deviceRankingButton;
    private javax.swing.JTable deviceTable;
    private javax.swing.JTextField enAliasTextField;
    private javax.swing.JLabel enBrandLabel;
    private javax.swing.JTextField enBrandTextField;
    private javax.swing.JLabel enProductLabel;
    private javax.swing.JTextField enProductTextField;
    private javax.swing.JButton errorRecognitionButton;
    private javax.swing.JButton excludeFilterButton;
    private javax.swing.JButton fakeDetectionButton;
    private javax.swing.JButton filterButton;
    private javax.swing.JButton flushButton;
    private javax.swing.JButton googleButton;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel12;
    private javax.swing.JPanel jPanel13;
    private javax.swing.JPanel jPanel14;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel4;
    private javax.swing.JPanel jPanel5;
    private javax.swing.JPanel jPanel6;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JScrollPane jScrollPane4;
    private javax.swing.JButton knockOffButton;
    private javax.swing.JCheckBox knockOffCheckBox;
    private javax.swing.JButton modelButton;
    private javax.swing.JLabel modelLabel;
    private javax.swing.JTextField modelTextField;
    private javax.swing.JButton newDeviceFilterButton;
    private javax.swing.JButton othersDevicesButton;
    private javax.swing.JLabel partitionLabel;
    private javax.swing.JTextField partitionTextField;
    private javax.swing.JButton productIdButton;
    private javax.swing.JLabel productIdLabel;
    private javax.swing.JTextField productIdTextField;
    private javax.swing.JLabel productLabel;
    private javax.swing.JTextField productTextField;
    private javax.swing.JButton queryButton;
    private javax.swing.JButton queryFilterButton;
    private javax.swing.JSpinner queryLimitSpinner;
    private javax.swing.JPanel queryPanel;
    private javax.swing.JTextField queryTextField;
    private javax.swing.JButton removeDeviceButton;
    private javax.swing.JComboBox resolutionComboBox;
    private javax.swing.JLabel resolutionLabel;
    private javax.swing.JTextArea resultTextArea;
    private javax.swing.JButton rootSpritButton;
    private javax.swing.JButton shuameMobileButton;
    private javax.swing.JButton sortButton;
    private javax.swing.JButton testCaseButton;
    private javax.swing.JComboBox typeComboBox;
    private javax.swing.JButton unnormalDeviceFilterButton;
    private javax.swing.JButton updateButton;
    private javax.swing.JButton updateModelButton;
    private javax.swing.JButton updateTestCaseButton;
    private javax.swing.JTextField vid2TextField;
    private javax.swing.JLabel vidLabel;
    private javax.swing.JTextField vidTextField;
    // End of variables declaration//GEN-END:variables
}