/* * Lilith - a log event viewer. * Copyright (C) 2007-2015 Joern Huxhorn * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package de.huxhorn.lilith.swing.preferences; import de.huxhorn.sulky.io.IOUtilities; import java.awt.EventQueue; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import javax.swing.event.EventListenerList; import javax.swing.event.TableModelEvent; import javax.swing.event.TableModelListener; import javax.swing.table.TableModel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class SoundLocationTableModel implements TableModel { private final Logger logger = LoggerFactory.getLogger(SoundLocationTableModel.class); private static final int EVENT_NAME_COLUMN = 0; private static final int SOUND_LOCATION_COLUMN = 1; private Map<String, String> data; private List<String> keys; private final EventListenerList eventListenerList; public SoundLocationTableModel(Map<String, String> data) { eventListenerList = new EventListenerList(); setData(data); } public void setData(Map<String, String> data) { this.data = data; if(data != null) { this.keys = new ArrayList<>(data.keySet()); Collections.sort(this.keys); } else { keys = null; } fireTableChange(); } public Map<String, String> getData() { return data; } public int getRowCount() { if(data == null) { return 0; } return data.size(); } public int getColumnCount() { return 2; } public String getColumnName(int columnIndex) { switch(columnIndex) { case SoundLocationTableModel.EVENT_NAME_COLUMN: return "Event"; case SoundLocationTableModel.SOUND_LOCATION_COLUMN: return "Location"; } return null; } public Class<?> getColumnClass(int columnIndex) { return String.class; } public boolean isCellEditable(int rowIndex, int columnIndex) { if(keys == null || rowIndex < 0 || rowIndex >= keys.size()) { return false; } return columnIndex == SOUND_LOCATION_COLUMN; } public Object getValueAt(int rowIndex, int columnIndex) { if(keys == null || rowIndex < 0 || rowIndex >= keys.size()) { return null; } String key = keys.get(rowIndex); switch(columnIndex) { case SoundLocationTableModel.EVENT_NAME_COLUMN: return key; case SoundLocationTableModel.SOUND_LOCATION_COLUMN: return data.get(key); } return null; } public void setValueAt(Object aValue, int rowIndex, int columnIndex) { String newValue = (String) aValue; if(keys == null || rowIndex < 0 || rowIndex >= keys.size()) { return; } switch(columnIndex) { case SoundLocationTableModel.EVENT_NAME_COLUMN: { String key = keys.remove(rowIndex); String value = data.remove(key); data.put(newValue, value); keys.add(newValue); Collections.sort(keys); fireTableChange(); } break; case SoundLocationTableModel.SOUND_LOCATION_COLUMN: { String key = keys.get(rowIndex); data.put(key, newValue); fireTableChange(); } } } private void fireTableChange() { TableModelEvent event = new TableModelEvent(this); fireTableChange(event); } private void fireTableChange(TableModelEvent evt) { Runnable r = new SoundLocationTableModel.FireTableChangeRunnable(evt); if(EventQueue.isDispatchThread()) { r.run(); } else { EventQueue.invokeLater(r); } } private class FireTableChangeRunnable implements Runnable { private TableModelEvent event; FireTableChangeRunnable(TableModelEvent event) { this.event = event; } public void run() { Object[] listeners; synchronized(eventListenerList) { listeners = eventListenerList.getListenerList(); } // Process the listeners last to first, notifying // those that are interested in this event for(int i = listeners.length - 2; i >= 0; i -= 2) { if(listeners[i] == TableModelListener.class) { TableModelListener listener = ((TableModelListener) listeners[i + 1]); if(logger.isDebugEnabled()) { logger.debug("Firing TableChange at {}.", listener.getClass().getName()); } try { listener.tableChanged(event); } catch(Throwable ex) { if(logger.isWarnEnabled()) logger.warn("Exception while firing change!", ex); IOUtilities.interruptIfNecessary(ex); } } } } } public void addTableModelListener(TableModelListener l) { synchronized(eventListenerList) { eventListenerList.add(TableModelListener.class, l); } } public void removeTableModelListener(TableModelListener l) { synchronized(eventListenerList) { eventListenerList.remove(TableModelListener.class, l); } } }