// Copyright 2004-2014 Jim Voris
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package com.qumasoft.guitools.qwin;
import com.qumasoft.qvcslib.Utility;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import javax.swing.SwingUtilities;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
/**
* Activity list model.
* @author Jim Voris
*/
public class ActivityListModel implements javax.swing.ListModel {
// TODO -- this should be configurable.
private static final int ACTVITY_PANE_MAXIMUM_SIZE = 5000; // 5000 rows of info.
// The backing store here will be a linked list.
private final List<String> activityList;
private final Map<ListDataListener, ListDataListener> activityListeners;
/**
* Creates a new instance of ActivityListModel.
*/
public ActivityListModel() {
this.activityListeners = Collections.synchronizedMap(new HashMap<ListDataListener, ListDataListener>());
this.activityList = Collections.synchronizedList(new LinkedList<String>());
}
private void notifyListeners(final ListDataEvent event) {
if (SwingUtilities.isEventDispatchThread()) {
privateNotifyListeners(event);
} else {
Runnable postEvent = new Runnable() {
@Override
public void run() {
privateNotifyListeners(event);
}
};
try {
SwingUtilities.invokeLater(postEvent);
} catch (Exception e) {
QWinUtility.logProblem(Level.WARNING, Utility.expandStackTraceToString(e));
}
}
}
private void privateNotifyListeners(ListDataEvent event) {
for (ListDataListener listener : activityListeners.values()) {
listener.contentsChanged(event);
}
}
/**
* Add a message to the model. Note that new messages are added to the beginning of the model so that new messages always appear at the top of the list.
* @param logMessage the log message to add.
*/
public void addMessage(String logMessage) {
if (activityList.size() > ACTVITY_PANE_MAXIMUM_SIZE) {
activityList.remove(ACTVITY_PANE_MAXIMUM_SIZE);
}
activityList.add(0, logMessage);
// Let any listeners know about the change.
notifyListeners(new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, 0, activityList.size() - 1));
}
@Override
public void addListDataListener(ListDataListener listener) {
activityListeners.put(listener, listener);
}
@Override
public Object getElementAt(int index) {
return activityList.get(index);
}
@Override
public int getSize() {
return activityList.size();
}
@Override
public void removeListDataListener(ListDataListener l) {
activityListeners.remove(l);
}
}