com.pentacog.mctracker.ServerListAdapter.java Source code

Java tutorial

Introduction

Here is the source code for com.pentacog.mctracker.ServerListAdapter.java

Source

/*
 * This work is licensed under the Creative Commons Attribution-NonCommercial 3.0 New Zealand License. 
 * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc/3.0/nz/ or send a 
 * letter to Creative Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA.
 */
package com.pentacog.mctracker;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.pentacog.mctracker.GetServerDataTask.ServerDataResultHandler;

import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.widget.BaseAdapter;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;

/**
 * @author Affian
 *
 */
public class ServerListAdapter extends BaseAdapter implements Filterable {

    private ArrayList<Server> mOriginalValues = null;
    private ArrayList<Server> serverList = null;

    private final Object mLock = new Object();

    private ArrayFilter mFilter = null;

    /**
     * 
     */
    public ServerListAdapter() {
        this(new ArrayList<Server>());
    }

    /**
     * 
     * @param serverList
     */
    public ServerListAdapter(ArrayList<Server> serverList) {
        this.serverList = serverList;
        sort();
    }

    /**
     * 
     * @param servers
     */
    public ServerListAdapter(JSONArray servers) {
        this.serverList = new ArrayList<Server>();

        for (int i = 0; i < servers.length(); i++) {
            try {
                JSONObject obj = servers.getJSONObject(i);

                Server server = new Server(obj);
                serverList.add(server);

            } catch (JSONException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }
        sort();
    }

    /* (non-Javadoc)
     * @see android.widget.Adapter#getCount()
     */
    @Override
    public int getCount() {
        return serverList.size();
    }

    /* (non-Javadoc)
     * @see android.widget.Adapter#getItem(int)
     */
    @Override
    public Server getItem(int position) {
        return serverList.get(position);
    }

    /* (non-Javadoc)
     * @see android.widget.Adapter#getItemId(int)
     */
    @Override
    public long getItemId(int position) {
        return serverList.get(position).id;
    }

    /* (non-Javadoc)
     * @see android.widget.Adapter#getItemViewType(int)
     */
    @Override
    public int getItemViewType(int position) {
        return 0;
    }

    /* (non-Javadoc)
     * @see android.widget.Adapter#getView(int, android.view.View, android.view.ViewGroup)
     */
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        RelativeLayout serverView = null;
        ServerViewHolder holder = null;
        Server server = serverList.get(position);
        server.id = position;
        if (convertView == null) {
            serverView = (RelativeLayout) LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item,
                    parent, false);
            holder = new ServerViewHolder((int) getItemId(position), serverView);
            serverView.setTag(holder);
        } else {
            serverView = (RelativeLayout) convertView;
            holder = (ServerViewHolder) serverView.getTag();
            holder.id = (int) getItemId(position);
        }

        //set server name
        holder.serverTitle.setText(server.name);
        //set server IP
        String serverName = server.address.toString();
        if (!serverName.startsWith("/")) {
            int index = serverName.lastIndexOf('/');
            if (index != -1) {
                String tempString;
                tempString = serverName.substring(index + 1);
                serverName = serverName.substring(0, index);
                serverName += " " + tempString;
            }
        } else {
            serverName = serverName.replace("/", "");
        }
        if (server.port != 25565)
            serverName += ":" + server.port;
        holder.serverIp.setText(serverName);

        //set fav icon
        if (server.favorite) {
            holder.favStar.setVisibility(View.VISIBLE);
        } else {
            holder.favStar.setVisibility(View.INVISIBLE);
        }

        if (!server.queried) {
            AlphaAnimation a = new AlphaAnimation(1.0f, 0.2f);
            a.setRepeatCount(Animation.INFINITE);
            a.setRepeatMode(Animation.REVERSE);
            a.setDuration(300);
            holder.statusBar.setBackgroundColor(Color.BLUE);
            holder.statusBar.startAnimation(a);

            //         holder.loading.setVisibility(View.VISIBLE);
            holder.playerCount.setText("" + server.playerCount + "/" + server.maxPlayers);
            holder.serverData.setText(R.string.loading);
            holder.playerCount.setVisibility(View.INVISIBLE);
            holder.ping.setVisibility(View.INVISIBLE);
            new ServerViewUpdater(serverView, server);
        } else {
            setupServerCell(server, holder);
        }

        return serverView;
    }

    /* (non-Javadoc)
     * @see android.widget.Adapter#getViewTypeCount()
     */
    @Override
    public int getViewTypeCount() {
        return 1;
    }

    /* (non-Javadoc)
     * @see android.widget.Adapter#hasStableIds()
     */
    @Override
    public boolean hasStableIds() {
        return false;
    }

    /* (non-Javadoc)
     * @see android.widget.Adapter#isEmpty()
     */
    @Override
    public boolean isEmpty() {
        return serverList.isEmpty();
    }

    /* (non-Javadoc)
     * @see android.widget.ListAdapter#areAllItemsEnabled()
     */
    @Override
    public boolean areAllItemsEnabled() {
        return true;
    }

    /* (non-Javadoc)
     * @see android.widget.ListAdapter#isEnabled(int)
     */
    @Override
    public boolean isEnabled(int position) {
        return true;
    }

    @Override
    public Filter getFilter() {
        if (mFilter == null) {
            mFilter = new ArrayFilter();
        }
        return mFilter;
    }

    public void remove(int position) {
        serverList.remove(position);
    }

    public void add(Server newServer) {
        serverList.add(newServer);
        sort();

    }

    public void refresh() {
        for (Server server : serverList) {
            server.queried = false;
        }
        this.notifyDataSetChanged();
    }

    public void sort() {
        Collections.sort(serverList, new Comparator<Server>() {

            @Override
            public int compare(Server object1, Server object2) {

                if (object1.favorite && !object2.favorite) {
                    return -1;
                } else if (object2.favorite && !object1.favorite) {
                    return 1;
                }

                return object1.name.compareTo(object2.name);
            }
        });
        notifyDataSetChanged();
    }

    public class ServerViewHolder {

        public int id;
        public TextView serverTitle;
        public TextView serverIp;
        public TextView playerCount;
        public TextView serverData;
        public TextView ping;
        public ImageView favStar;
        public ImageView statusBar;
        public ProgressBar loading;

        ServerViewHolder(int id, View serverView) {
            this.id = id;
            serverTitle = (TextView) serverView.findViewById(R.id.serverTitle);
            serverIp = (TextView) serverView.findViewById(R.id.serverIp);
            playerCount = (TextView) serverView.findViewById(R.id.playerCount);
            serverData = (TextView) serverView.findViewById(R.id.serverData);
            loading = (ProgressBar) serverView.findViewById(R.id.updating_server);
            ping = (TextView) serverView.findViewById(R.id.ping);
            favStar = (ImageView) serverView.findViewById(R.id.favStar);
            statusBar = (ImageView) serverView.findViewById(R.id.statusBar);
        }
    }

    private class ServerViewUpdater implements ServerDataResultHandler {
        private View view;

        public ServerViewUpdater(View view, Server server) {
            this.view = view;
            new GetServerDataTask(server, this).execute();
        }

        @Override
        public void onServerDataResult(Server server, String result) {
            ServerViewHolder holder = (ServerViewHolder) view.getTag();
            if (holder.id == server.id) {
                setupServerCell(server, holder);
            } else {
                server.queried = false;
            }

        }

    }

    private void setupServerCell(Server server, ServerViewHolder holder) {

        /*
         * No Internet = "Network Unreachable"
         * open port but no server = "The operation timed out"
         * No open ports = <address> - Connection refused
         */
        Animation a = holder.statusBar.getAnimation();
        if (a != null) {
            a.reset();
            holder.statusBar.clearAnimation();
        }
        if (server.motd.startsWith(MCServerTrackerActivity.ERROR_CHAR)) {
            holder.statusBar.setBackgroundColor(Color.RED);
            holder.playerCount.setVisibility(View.INVISIBLE);
            holder.ping.setVisibility(View.INVISIBLE);
        } else {
            holder.statusBar.setBackgroundColor(Color.GREEN);
            holder.playerCount.setVisibility(View.VISIBLE);
            holder.ping.setVisibility(View.VISIBLE);
        }
        holder.playerCount.setText("" + server.playerCount + "/" + server.maxPlayers);
        holder.serverData.setText(server.motd);
        holder.ping.setText("" + server.ping + "ms");

    }

    public final ArrayList<Server> getServerList() {
        return this.serverList;
    }

    private class ArrayFilter extends Filter {

        @Override
        protected FilterResults performFiltering(CharSequence prefix) {
            FilterResults results = new FilterResults();

            if (mOriginalValues == null) {
                synchronized (mLock) {
                    mOriginalValues = new ArrayList<Server>(serverList);
                }
            }

            if (prefix == null || prefix.length() == 0) {
                synchronized (mLock) {
                    ArrayList<Server> list = new ArrayList<Server>(mOriginalValues);
                    results.values = list;
                    results.count = list.size();
                }
            } else {
                String prefixString = prefix.toString().toLowerCase();

                final ArrayList<Server> values = mOriginalValues;
                final int count = values.size();

                final ArrayList<Server> newValues = new ArrayList<Server>(count);

                for (int i = 0; i < count; i++) {
                    final Server server = values.get(i);
                    final String valueText = server.name.toLowerCase();
                    final String valueIp = server.address.toLowerCase();
                    // First match against the whole, non-splitted value
                    if (valueText.startsWith(prefixString) || valueIp.startsWith(prefixString)) {
                        newValues.add(server);
                    } else {
                        final String[] words = valueText.split(" ");
                        final int wordCount = words.length;

                        for (int k = 0; k < wordCount; k++) {
                            if (words[k].startsWith(prefixString)) {
                                newValues.add(server);
                                break;
                            }
                        }

                        final String[] subnets = valueIp.split("\\.");
                        final int netCount = subnets.length;

                        for (int j = 0; j < netCount; j++) {
                            if (subnets[j].startsWith(prefixString)) {
                                newValues.add(server);
                                break;
                            }
                        }
                    }
                }

                results.values = newValues;
                results.count = newValues.size();
            }

            return results;
        }

        @SuppressWarnings("unchecked")
        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            //noinspection unchecked
            serverList = (ArrayList<Server>) results.values;
            if (results.count > 0) {
                notifyDataSetChanged();
            } else {
                notifyDataSetInvalidated();
            }
        }
    }

}