#82 - resolves issue with icon management and list updating after additions/deletions of icons. Updates the single and multi alias list editors to refresh their view any time that changes are made to the list of icons.

This commit is contained in:
Denny
2017-01-11 20:44:07 -05:00
parent 1352ef9092
commit 75cb6c27d4
10 changed files with 622 additions and 358 deletions

View File

@@ -21,15 +21,16 @@ package alias;
import alias.AliasEvent.Event;
import gui.editor.Editor;
import icon.Icon;
import icon.IconCellRenderer;
import icon.IconListCellRenderer;
import icon.IconManager;
import icon.IconModel;
import map.MapIcon;
import icon.IconTableModel;
import net.miginfocom.swing.MigLayout;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
@@ -56,6 +57,15 @@ public class AliasNameEditor extends Editor<Alias>
mAliasModel = aliasModel;
mIconManager = iconManager;
mIconManager.getModel().addTableModelListener(new TableModelListener()
{
@Override
public void tableChanged(TableModelEvent e)
{
refreshIcons();
}
});
init();
}
@@ -155,7 +165,7 @@ public class AliasNameEditor extends Editor<Alias>
mIconCombo = new JComboBox<Icon>(mIconManager.getIcons());
IconCellRenderer renderer = new IconCellRenderer(mIconManager);
IconListCellRenderer renderer = new IconListCellRenderer(mIconManager);
renderer.setPreferredSize(new Dimension(200, 30));
mIconCombo.setRenderer(renderer);
mIconCombo.addActionListener(new ActionListener()
@@ -187,6 +197,32 @@ public class AliasNameEditor extends Editor<Alias>
setModified(false);
}
private void refreshIcons()
{
if(mIconCombo != null)
{
EventQueue.invokeLater(new Runnable()
{
@Override
public void run()
{
mIconCombo.setModel(new DefaultComboBoxModel<>(mIconManager.getIcons()));
if(hasItem())
{
String iconName = getItem().getIconName();
Icon aliasIcon = mIconManager.getModel().getIcon(iconName);
if(aliasIcon != null)
{
mIconCombo.setSelectedItem(aliasIcon);
}
}
}
});
}
}
@Override
public void setItem(Alias alias)
{
@@ -237,7 +273,7 @@ public class AliasNameEditor extends Editor<Alias>
if(iconName == null)
{
iconName = IconModel.DEFAULT_ICON;
iconName = IconTableModel.DEFAULT_ICON;
}
Icon savedIcon = mIconManager.getModel().getIcon(iconName);
@@ -285,7 +321,7 @@ public class AliasNameEditor extends Editor<Alias>
if(mIconCombo.getSelectedItem() != null)
{
alias.setIconName(((MapIcon) mIconCombo.getSelectedItem()).getName());
alias.setIconName(((Icon) mIconCombo.getSelectedItem()).getName());
}
setModified(false);

View File

@@ -1,41 +1,29 @@
package alias;
import alias.AliasEvent.Event;
import alias.id.AliasIDType;
import alias.id.broadcast.BroadcastChannel;
import alias.id.priority.Priority;
import audio.broadcast.BroadcastModel;
import com.sun.org.apache.xpath.internal.operations.Mult;
import gui.editor.Editor;
import icon.Icon;
import icon.IconListCellRenderer;
import icon.IconManager;
import net.miginfocom.swing.MigLayout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sample.Listener;
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JColorChooser;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JSeparator;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import icon.Icon;
import icon.IconManager;
import map.MapIcon;
import icon.IconCellRenderer;
import net.miginfocom.swing.MigLayout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sample.Listener;
import alias.AliasEvent.Event;
import alias.id.priority.Priority;
public class MultipleAliasEditor extends Editor<List<Alias>>
implements Listener<AliasEvent>
{
@@ -76,6 +64,14 @@ public class MultipleAliasEditor extends Editor<List<Alias>>
mIconManager = iconManager;
mAliasModel.addListener(this);
mIconManager.getModel().addTableModelListener(new TableModelListener()
{
@Override
public void tableChanged(TableModelEvent e)
{
refreshIcons();
}
});
init();
}
@@ -140,7 +136,7 @@ public class MultipleAliasEditor extends Editor<List<Alias>>
mIconCombo = new JComboBox<Icon>(mIconManager.getIcons());
IconCellRenderer renderer = new IconCellRenderer(mIconManager);
IconListCellRenderer renderer = new IconListCellRenderer(mIconManager);
renderer.setPreferredSize(new Dimension(200, 30));
mIconCombo.setRenderer(renderer);
add(mIconCombo, "wrap");
@@ -232,6 +228,21 @@ public class MultipleAliasEditor extends Editor<List<Alias>>
setModified(false);
}
private void refreshIcons()
{
if(mIconCombo != null)
{
EventQueue.invokeLater(new Runnable()
{
@Override
public void run()
{
mIconCombo.setModel(new DefaultComboBoxModel<>(mIconManager.getIcons()));
}
});
}
}
@Override
public void setItem(List<Alias> item)
{
@@ -356,7 +367,7 @@ public class MultipleAliasEditor extends Editor<List<Alias>>
{
if (mIconCombo.getSelectedItem() != null)
{
alias.setIconName(((MapIcon) mIconCombo.getSelectedItem()).getName());
alias.setIconName(((Icon)mIconCombo.getSelectedItem()).getName());
}
else
{

View File

@@ -1,131 +1,148 @@
/*******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2017 Dennis Sheirer
*
* 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 gui.editor;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.*;
/**
* Generic editor with change detection, save and reset functions.
*
*
* This editor supports hierarchical nesting of sub-component editors where changes are detected
* at the lowest editor in the tree and percolated up to the top-level editor for managing the
* configuration set as a whole.
*
* at the lowest editor in the tree and percolated up to the top-level editor for managing the
* configuration set as a whole.
*
* To configure this editor as a collective, register each parent editor as a saveRequestListener
* on each child editor. If no save request listener is registered, the editor will simply invoke
* save when a change is detected and the user opts to save the contents.
*
*
* The top-level editor can override the saveRequest() method to perform custom save operations
* and validation.
*/
public abstract class Editor<T> extends JPanel
{
private static final long serialVersionUID = 1L;
protected T mItem;
protected boolean mModified = false;
protected Editor<?> mSaveRequestListener;
private static final long serialVersionUID = 1L;
public Editor()
{
}
protected T mItem;
protected boolean mModified = false;
protected Editor<?> mSaveRequestListener;
/**
* Requests to save the contents of this editor.
*
* If a save request listener is registered, the listener is notified that a save is requested,
* otherwise the save is request is processed by the instance.
*
* This allows for a save event to be percolated up the hierarchical set of editors so that
* a top-level editor can invoke custom operations such as configuration validation.
*/
protected void saveRequest()
{
if( mSaveRequestListener != null )
{
mSaveRequestListener.saveRequest();
}
else
{
save();
}
}
public Editor()
{
}
/**
* Registers the editor to be notified when this editor contents have been saved.
*/
public void setSaveRequestListener( Editor<?> listener )
{
mSaveRequestListener = listener;
}
/**
* Sets the object to be edited. If the contents from the previous object have changed, this
* prompts the user to save these changes. A saveRequest() is issued and either this editor
* or the parent editor will respond to the save request and invoke the save() method.
*/
public void setItem( T item )
{
if( isModified() )
{
int option = JOptionPane.showConfirmDialog(
Editor.this,
"This item has changed. Do you want to save these changes?",
"Save Changes?",
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE );
if( option == JOptionPane.YES_OPTION )
{
saveRequest();
}
setModified( false );
}
mItem = item;
}
/**
* Requests to save the contents of this editor.
*
* If a save request listener is registered, the listener is notified that a save is requested,
* otherwise the save is request is processed by the instance.
*
* This allows for a save event to be percolated up the hierarchical set of editors so that
* a top-level editor can invoke custom operations such as configuration validation.
*/
protected void saveRequest()
{
if(mSaveRequestListener != null)
{
mSaveRequestListener.saveRequest();
}
else
{
save();
}
}
/**
* Current editing item
*/
public T getItem()
{
return mItem;
}
public boolean hasItem()
{
return mItem != null;
}
/**
* Registers the editor to be notified when this editor contents have been saved.
*/
public void setSaveRequestListener(Editor<?> listener)
{
mSaveRequestListener = listener;
}
/**
* Sets the contents modified flag
*/
public void setModified( boolean modified )
{
mModified = modified;
}
/**
* Indicates if this editor contents have been modified
*/
public boolean isModified()
{
return mModified;
}
/**
* Sets the object to be edited. If the contents from the previous object have changed, this
* prompts the user to save these changes. A saveRequest() is issued and either this editor
* or the parent editor will respond to the save request and invoke the save() method.
*/
public void setItem(T item)
{
if(isModified())
{
int option = JOptionPane.showConfirmDialog(
Editor.this,
"This item has changed. Do you want to save these changes?",
"Save Changes?",
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE);
/**
* Save the contents of the editor
*/
public abstract void save();
if(option == JOptionPane.YES_OPTION)
{
saveRequest();
}
/**
* Reset the contents of the editor without saving any changes
*/
public void reset()
{
mModified = false;
setItem( mItem );
}
setModified(false);
}
mItem = item;
}
/**
* Current editing item
*/
public T getItem()
{
return mItem;
}
public boolean hasItem()
{
return mItem != null;
}
/**
* Sets the contents modified flag
*/
public void setModified(boolean modified)
{
mModified = modified;
}
/**
* Indicates if this editor contents have been modified
*/
public boolean isModified()
{
return mModified;
}
/**
* Save the contents of the editor
*/
public abstract void save();
/**
* Reset the contents of the editor without saving any changes
*/
public void reset()
{
mModified = false;
setItem(mItem);
}
}

View File

@@ -29,10 +29,10 @@ import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class IconViewer extends JFrame implements ActionListener
public class IconEditor extends JFrame implements ActionListener
{
private static final long serialVersionUID = 1L;
private static final Logger mLog = LoggerFactory.getLogger(IconViewer.class);
private static final Logger mLog = LoggerFactory.getLogger(IconEditor.class);
private static final String ADD = "Add";
private static final String DEFAULT = "Set Default";
private static final String DELETE = "Delete";
@@ -40,10 +40,10 @@ public class IconViewer extends JFrame implements ActionListener
private JButton mAddButton;
private JButton mDeleteButton;
private JButton mDefaultButton;
private JList<Icon> mIconList;
private JTable mIconTable;
private IconManager mIconManager;
public IconViewer(IconManager model)
public IconEditor(IconManager model)
{
mIconManager = model;
@@ -52,7 +52,7 @@ public class IconViewer extends JFrame implements ActionListener
private void init()
{
setTitle("Icon Viewer");
setTitle("Icon Manager");
setSize(400, 400);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setLayout(new MigLayout("", "[grow,fill]", "[grow,fill]"));
@@ -63,11 +63,13 @@ public class IconViewer extends JFrame implements ActionListener
JPanel editorPanel = new JPanel();
editorPanel.setLayout(new MigLayout("insets 1 1 1 1", "[grow,fill][grow,fill][grow,fill]", "[grow,fill][]"));
mIconList = new JList<>(mIconManager.getModel());
IconCellRenderer renderer = new IconCellRenderer(mIconManager);
renderer.setPreferredSize(new Dimension(200, 30));
mIconList.setCellRenderer(renderer);
mIconList.addListSelectionListener(new ListSelectionListener()
mIconTable = new JTable(mIconManager.getModel());
IconTableCellRenderer renderer = new IconTableCellRenderer(mIconManager);
mIconTable.getColumnModel().getColumn(IconTableModel.COLUMN_IMAGE_ICON).setCellRenderer(renderer);
mIconTable.setAutoCreateRowSorter(true);
mIconTable.getRowSorter().toggleSortOrder(IconTableModel.COLUMN_ICON_NAME);
mIconTable.setRowHeight(36);
mIconTable.getSelectionModel().addListSelectionListener(new ListSelectionListener()
{
@Override
public void valueChanged(ListSelectionEvent e)
@@ -75,7 +77,7 @@ public class IconViewer extends JFrame implements ActionListener
checkButtons();
}
});
editorPanel.add(new JScrollPane(mIconList), "span");
editorPanel.add(new JScrollPane(mIconTable), "span");
mAddButton = new JButton(ADD);
mAddButton.addActionListener(this);
@@ -96,15 +98,32 @@ public class IconViewer extends JFrame implements ActionListener
private void checkButtons()
{
Icon selected = mIconList.getSelectedValue();
Icon selected = getSelectedIcon();
mDefaultButton.setEnabled(selected != null && selected != mIconManager.getModel().getDefaultIcon());
mDeleteButton.setEnabled(selected != null && selected != mIconManager.getModel().getDefaultIcon());
}
private Icon getSelectedIcon()
{
int selectedViewRow = mIconTable.getSelectedRow();
if(selectedViewRow >= 0)
{
int selectedModelRow = mIconTable.convertRowIndexToModel(mIconTable.getSelectedRow());
if(selectedModelRow >= 0)
{
return mIconManager.getModel().get(selectedModelRow);
}
}
return null;
}
public void actionPerformed(ActionEvent e)
{
Icon selected = mIconList.getSelectedValue();
Icon selected = getSelectedIcon();
switch(e.getActionCommand())
{
@@ -115,12 +134,12 @@ public class IconViewer extends JFrame implements ActionListener
case DELETE:
if(selected != null)
{
int choice = JOptionPane.showConfirmDialog(IconViewer.this,
int choice = JOptionPane.showConfirmDialog(IconEditor.this,
"Are you sure you want to delete this icon?", "Delete Icon?", JOptionPane.YES_NO_OPTION);
if(choice == JOptionPane.YES_OPTION)
{
mIconManager.getModel().removeElement(selected);
mIconManager.getModel().remove(selected);
}
}
break;

View File

@@ -21,13 +21,13 @@ package icon;
import javax.swing.*;
import java.awt.*;
public class IconCellRenderer extends JLabel implements ListCellRenderer<Icon>
public class IconListCellRenderer extends JLabel implements ListCellRenderer<Icon>
{
private static final long serialVersionUID = 1L;
private IconManager mIconManager;
public IconCellRenderer(IconManager iconManager)
public IconListCellRenderer(IconManager iconManager)
{
mIconManager = iconManager;
setOpaque(true);
@@ -37,15 +37,16 @@ public class IconCellRenderer extends JLabel implements ListCellRenderer<Icon>
public Component getListCellRendererComponent(JList<? extends Icon> list, Icon icon, int index,
boolean isSelected, boolean cellHasFocus)
{
//Get a scaled version of the icon
setIcon(mIconManager.getIcon(icon.getName(), 24));
if(icon == mIconManager.getModel().getDefaultIcon())
if(mIconManager.getModel().isDefaultIcon(icon))
{
setText(icon.toString() + " (default)");
setText(icon.getName() + " (default)");
}
else
{
setText(icon.toString());
setText(icon.getName());
}
if(isSelected)

View File

@@ -26,6 +26,8 @@ import properties.SystemProperties;
import javax.swing.*;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
@@ -53,8 +55,8 @@ public class IconManager
private Path mIconLockFilePath;
private ThreadPoolManager mThreadPoolManager;
private IconViewer mIconViewer;
private IconModel mIconModel;
private IconEditor mIconEditor;
private IconTableModel mIconTableModel;
private AtomicBoolean mSavingIcons = new AtomicBoolean();
private Map<String, ImageIcon> mResizedIcons = new HashMap<>();
@@ -71,32 +73,33 @@ public class IconManager
*/
public void showEditor(Component centerOnComponent)
{
if(mIconViewer == null)
if(mIconEditor == null)
{
mIconViewer = new IconViewer(this);
mIconViewer.setLocationRelativeTo(centerOnComponent);
mIconEditor = new IconEditor(this);
}
if(mIconViewer.isVisible())
mIconEditor.setLocationRelativeTo(centerOnComponent);
if(mIconEditor.isVisible())
{
mIconEditor.requestFocus();
}
else
{
EventQueue.invokeLater(new Runnable()
{
mIconViewer.requestFocus();
}
else
{
EventQueue.invokeLater(new Runnable()
@Override
public void run()
{
@Override
public void run()
{
mIconViewer.setVisible(true);
}
});
}
mIconEditor.setVisible(true);
}
});
}
}
public IconModel getModel()
public IconTableModel getModel()
{
if(mIconModel == null)
if(mIconTableModel == null)
{
IconSet loadedIcons = load();
@@ -108,23 +111,11 @@ public class IconManager
saveRequired = true;
}
mIconModel = new IconModel(loadedIcons);
mIconModel.addListDataListener(new ListDataListener()
mIconTableModel = new IconTableModel(loadedIcons);
mIconTableModel.addTableModelListener(new TableModelListener()
{
@Override
public void intervalAdded(ListDataEvent e)
{
scheduleSave();
}
@Override
public void intervalRemoved(ListDataEvent e)
{
scheduleSave();
}
@Override
public void contentsChanged(ListDataEvent e)
public void tableChanged(TableModelEvent e)
{
scheduleSave();
}
@@ -136,7 +127,7 @@ public class IconManager
}
}
return mIconModel;
return mIconTableModel;
}
/**
@@ -389,7 +380,7 @@ public class IconManager
{
IconSet iconSet = new IconSet();
Icon defaultIcon = new Icon(IconModel.DEFAULT_ICON, "images/no_icon.png");
Icon defaultIcon = new Icon(IconTableModel.DEFAULT_ICON, "images/no_icon.png");
iconSet.add(defaultIcon);
iconSet.setDefaultIcon(defaultIcon.getName());

View File

@@ -1,150 +0,0 @@
/*******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2017 Dennis Sheirer
*
* 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 icon;
import javax.swing.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class IconModel extends DefaultListModel<Icon>
{
public static final String DEFAULT_ICON = "No Icon";
private Icon mDefaultIcon;
private Map<String, Icon> mIconMap = new HashMap<>();
public IconModel(IconSet iconSet)
{
for(Icon icon : iconSet.getIcons())
{
this.addElement(icon);
}
String defaultIconName = iconSet.getDefaultIcon();
if(defaultIconName == null)
{
defaultIconName = DEFAULT_ICON;
}
Icon defaultIcon = mIconMap.get(defaultIconName);
if(defaultIcon != null)
{
mDefaultIcon = defaultIcon;
}
else
{
mDefaultIcon = new Icon(DEFAULT_ICON, "images/no_icon.png");
}
}
/**
* Icons in an array - suitable for use in a JComboBox
*/
public Icon[] getIconsAsArray()
{
List<Icon> icons = new ArrayList<>(mIconMap.values());
Collections.sort(icons);
return icons.toArray(new Icon[icons.size()]);
}
public Icon getDefaultIcon()
{
return mDefaultIcon;
}
/**
* Indicates if this model contains an icon with the specified name
*
* @param name to check
* @return true if name is not null and not empty and the internal map contains an icon matching name
*/
public boolean hasIcon(String name)
{
return name != null && !name.isEmpty() && mIconMap.containsKey(name);
}
public void setDefaultIcon(Icon icon)
{
if(icon != null)
{
mDefaultIcon = icon;
int index = indexOf(icon);
fireContentsChanged(icon, index, index);
}
}
/**
* Returns the named icon or the default icon if the named icon does not exist
*/
public Icon getIcon(String name)
{
if(name == null)
{
return mDefaultIcon;
}
Icon icon = mIconMap.get(name);
if(icon == null)
{
icon = mDefaultIcon;
}
return icon;
}
@Override
public void addElement(Icon icon)
{
super.addElement(icon);
mIconMap.put(icon.getName(), icon);
}
@Override
public boolean removeElement(Object object)
{
if(object instanceof Icon)
{
mIconMap.remove(((Icon) object).getName());
}
return super.removeElement(object);
}
/**
* Creates a new icon set from a snapshot of the icons contained in this model
*/
public IconSet getIconSet()
{
IconSet iconSet = new IconSet();
iconSet.setIcons(new ArrayList<Icon>(mIconMap.values()));
iconSet.setDefaultIcon(getDefaultIcon().getName());
return iconSet;
}
}

View File

@@ -19,8 +19,6 @@
package icon;
import net.miginfocom.swing.MigLayout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
@@ -32,7 +30,7 @@ import java.io.File;
public class IconSelector extends JDialog implements DocumentListener
{
private IconModel mIconModel;
private IconTableModel mIconTableModel;
private JTextField mNameText;
private JTextField mFileLabel;
private JButton mFileChooserButton;
@@ -43,13 +41,13 @@ public class IconSelector extends JDialog implements DocumentListener
* Window for selecting an Icon to add to the Icon Model
*
* @param owner for this modal dialog
* @param iconModel to receive the added/selected icon
* @param iconTableModel to receive the added/selected icon
*/
public IconSelector(Frame owner, IconModel iconModel)
public IconSelector(Frame owner, IconTableModel iconTableModel)
{
super(owner, "Add Icon", true);
mIconModel = iconModel;
mIconTableModel = iconTableModel;
init();
@@ -122,7 +120,7 @@ public class IconSelector extends JDialog implements DocumentListener
String path = mFileLabel.getText();
Icon icon = new Icon(name, path);
mIconModel.addElement(icon);
mIconTableModel.add(icon);
IconSelector.this.dispose();
}
@@ -151,7 +149,7 @@ public class IconSelector extends JDialog implements DocumentListener
String name = mNameText.getText();
String path = mFileLabel.getText();
mOKButton.setEnabled(name != null && path != null && !path.isEmpty() && !mIconModel.hasIcon(name));
mOKButton.setEnabled(name != null && path != null && !path.isEmpty() && !mIconTableModel.hasIcon(name));
}
@Override

View File

@@ -0,0 +1,71 @@
/*******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2017 Dennis Sheirer
*
* 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 icon;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.swing.*;
import javax.swing.table.TableCellRenderer;
import java.awt.*;
public class IconTableCellRenderer extends JLabel implements TableCellRenderer
{
private final static Logger mLog = LoggerFactory.getLogger(IconTableCellRenderer.class);
private static final long serialVersionUID = 1L;
private IconManager mIconManager;
public IconTableCellRenderer(IconManager iconManager)
{
mIconManager = iconManager;
setOpaque(true);
setHorizontalAlignment(JLabel.CENTER);
setPreferredSize(new Dimension(40,34));
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int column)
{
if(value instanceof ImageIcon)
{
//Get a scaled version of the icon
setIcon(mIconManager.getScaledIcon((ImageIcon)value, 24));
}
else
{
setIcon(null);
}
if(isSelected)
{
setBackground(table.getSelectionBackground());
setForeground(table.getSelectionForeground());
}
else
{
setBackground(table.getBackground());
setForeground(table.getForeground());
}
return this;
}
}

View File

@@ -0,0 +1,270 @@
/*******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2017 Dennis Sheirer
*
* 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 icon;
import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class IconTableModel extends AbstractTableModel
{
public static final String DEFAULT_ICON = "No Icon";
public static final int COLUMN_IMAGE_ICON = 0;
public static final int COLUMN_ICON_NAME = 1;
private Icon mDefaultIcon;
private Map<String, Icon> mIconMap = new HashMap<>();
private List<Icon> mIcons = new ArrayList<>();
public IconTableModel()
{
setDefaultIcon(DEFAULT_ICON);
}
public IconTableModel(IconSet iconSet)
{
mIconMap.clear();
mIcons.clear();
fireTableDataChanged();
for(Icon icon: iconSet.getIcons())
{
add(icon);
}
setDefaultIcon(iconSet.getDefaultIcon());
}
/**
* Adds the icon to the model
*/
public void add(Icon icon)
{
if(icon != null)
{
mIcons.add(icon);
mIconMap.put(icon.getName(), icon);
int index = mIcons.indexOf(icon);
fireTableRowsInserted(index, index);
}
}
/**
* Removes the icon from the model
*/
public void remove(Icon icon)
{
if(icon != null && mIcons.contains(icon))
{
int index = mIcons.indexOf(icon);
mIcons.remove(icon);
mIconMap.remove(icon.getName());
fireTableRowsDeleted(index, index);
}
}
public Icon get(int row)
{
if(row < mIcons.size())
{
return mIcons.get(row);
}
return null;
}
@Override
public int getRowCount()
{
return mIcons.size();
}
@Override
public int getColumnCount()
{
return 2;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex)
{
if(rowIndex < mIcons.size() && columnIndex < getColumnCount())
{
Icon icon = get(rowIndex);
switch(columnIndex)
{
case COLUMN_IMAGE_ICON:
return icon.getIcon();
case COLUMN_ICON_NAME:
if(rowIndex == mIcons.indexOf(getDefaultIcon()))
{
return icon.getName() + " (default)";
}
else
{
return icon.getName();
}
}
}
return null;
}
@Override
public String getColumnName(int column)
{
if(column == COLUMN_ICON_NAME)
{
return "Name";
}
return null;
}
@Override
public Class<?> getColumnClass(int columnIndex)
{
if(columnIndex == COLUMN_IMAGE_ICON)
{
return ImageIcon.class;
}
return String.class;
}
/**
* Icons in an array - suitable for use in a JComboBox
*/
public Icon[] getIconsAsArray()
{
List<Icon> icons = new ArrayList<>(mIconMap.values());
Collections.sort(icons);
return icons.toArray(new Icon[icons.size()]);
}
/**
* Returns the current default icon
*/
public Icon getDefaultIcon()
{
return mDefaultIcon;
}
/**
* Indicates if the icon argument is the current default icon
*/
public boolean isDefaultIcon(Icon icon)
{
return icon == getDefaultIcon();
}
/**
* Indicates if this model contains an icon with the specified name
*
* @param name to check
* @return true if name is not null and not empty and the internal map contains an icon matching name
*/
public boolean hasIcon(String name)
{
return name != null && !name.isEmpty() && mIconMap.containsKey(name);
}
public void setDefaultIcon(Icon icon)
{
if(icon != null)
{
int currentIndex = mIcons.indexOf(getDefaultIcon());
mDefaultIcon = icon;
int newIndex = mIcons.indexOf(icon);
fireTableCellUpdated(currentIndex, COLUMN_ICON_NAME);
fireTableCellUpdated(newIndex, COLUMN_ICON_NAME);
}
}
/**
* Sets the default icon to the icon with the specified name, or to a default icon of the named icon does not exist
*/
public void setDefaultIcon(String name)
{
if(name == null)
{
name = DEFAULT_ICON;
}
Icon defaultIcon = mIconMap.get(name);
if(defaultIcon != null)
{
setDefaultIcon(defaultIcon);
}
else
{
defaultIcon = new Icon(DEFAULT_ICON, "images/no_icon.png");
add(defaultIcon);
setDefaultIcon(defaultIcon);
}
}
/**
* Returns the named icon or the default icon if the named icon does not exist
*/
public Icon getIcon(String name)
{
if(name == null || name.isEmpty())
{
return mDefaultIcon;
}
Icon icon = mIconMap.get(name);
if(icon == null)
{
icon = mDefaultIcon;
}
return icon;
}
/**
* Creates a new icon set from a snapshot of the icons contained in this model
*/
public IconSet getIconSet()
{
IconSet iconSet = new IconSet();
iconSet.setIcons(new ArrayList<Icon>(mIconMap.values()));
iconSet.setDefaultIcon(getDefaultIcon().getName());
return iconSet;
}
}