Updates pull request from Roman Tsypuk to convert the build system from

ant to gradle.  Removes linux and windows application launch scripts and
produces an executable jar with all resources included.
This commit is contained in:
Denny
2017-12-17 07:28:03 -05:00
parent a1535c4157
commit 9316599dec
981 changed files with 8368 additions and 9049 deletions

View File

@@ -0,0 +1,99 @@
/*******************************************************************************
* 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 io.github.dsheirer.icon;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.swing.*;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
@XmlRootElement(name = "icon")
public class Icon implements Comparable<Icon>
{
private final static Logger mLog = LoggerFactory.getLogger(Icon.class);
protected String mName;
private String mPath;
private ImageIcon mImageIcon;
public Icon()
{
//No-arg JAXB constructor
}
public Icon(String name, String path)
{
mName = name;
mPath = path;
}
@XmlAttribute(name = "name")
public String getName()
{
return mName;
}
public void setName(String name)
{
mName = name;
}
public String toString()
{
return mName;
}
@XmlAttribute(name = "path")
public String getPath()
{
return mPath;
}
public void setPath(String path)
{
mPath = path;
}
@XmlTransient
public ImageIcon getIcon()
{
if(mImageIcon == null && mPath != null)
{
try
{
mImageIcon = new ImageIcon(mPath);
}
catch(Exception e)
{
mLog.error("Error loading Icon [" + mPath + "]", e);
}
}
return mImageIcon;
}
@Override
public int compareTo(Icon otherIcon)
{
return getName().compareTo(otherIcon.getName());
}
}

View File

@@ -0,0 +1,155 @@
/*******************************************************************************
* 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 io.github.dsheirer.icon;
import net.miginfocom.swing.MigLayout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class IconEditor extends JFrame implements ActionListener
{
private static final long serialVersionUID = 1L;
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";
private JButton mAddButton;
private JButton mDeleteButton;
private JButton mDefaultButton;
private JTable mIconTable;
private IconManager mIconManager;
public IconEditor(IconManager model)
{
mIconManager = model;
init();
}
private void init()
{
setTitle("Icon Manager");
setSize(400, 400);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setLayout(new MigLayout("", "[grow,fill]", "[grow,fill]"));
/**
* Editor Panel
*/
JPanel editorPanel = new JPanel();
editorPanel.setLayout(new MigLayout("insets 1 1 1 1", "[grow,fill][grow,fill][grow,fill]", "[grow,fill][]"));
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)
{
checkButtons();
}
});
editorPanel.add(new JScrollPane(mIconTable), "span");
mAddButton = new JButton(ADD);
mAddButton.addActionListener(this);
editorPanel.add(mAddButton);
mDeleteButton = new JButton(DELETE);
mDeleteButton.addActionListener(this);
mDeleteButton.setEnabled(false);
editorPanel.add(mDeleteButton);
mDefaultButton = new JButton(DEFAULT);
mDefaultButton.addActionListener(this);
mDefaultButton.setEnabled(false);
editorPanel.add(mDefaultButton, "wrap");
add(editorPanel);
}
private void checkButtons()
{
io.github.dsheirer.icon.Icon selected = getSelectedIcon();
mDefaultButton.setEnabled(selected != null && selected != mIconManager.getModel().getDefaultIcon());
mDeleteButton.setEnabled(selected != null && selected != mIconManager.getModel().getDefaultIcon());
}
private io.github.dsheirer.icon.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)
{
io.github.dsheirer.icon.Icon selected = getSelectedIcon();
switch(e.getActionCommand())
{
case ADD:
IconSelector iconSelector = new IconSelector(this, mIconManager.getModel());
iconSelector.setVisible(true);
break;
case DELETE:
if(selected != null)
{
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().remove(selected);
}
}
break;
case DEFAULT:
if(selected != null)
{
mIconManager.getModel().setDefaultIcon(selected);
}
break;
}
checkButtons();
}
}

View File

@@ -0,0 +1,65 @@
/*******************************************************************************
* 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 io.github.dsheirer.icon;
import javax.swing.*;
import java.awt.*;
public class IconListCellRenderer extends JLabel implements ListCellRenderer<io.github.dsheirer.icon.Icon>
{
private static final long serialVersionUID = 1L;
private IconManager mIconManager;
public IconListCellRenderer(IconManager iconManager)
{
mIconManager = iconManager;
setOpaque(true);
}
@Override
public Component getListCellRendererComponent(JList<? extends io.github.dsheirer.icon.Icon> list, io.github.dsheirer.icon.Icon icon, int index,
boolean isSelected, boolean cellHasFocus)
{
//Get a scaled version of the icon
setIcon(mIconManager.getIcon(icon.getName(), 24));
if(mIconManager.getModel().isDefaultIcon(icon))
{
setText(icon.getName() + " (default)");
}
else
{
setText(icon.getName());
}
if(isSelected)
{
setBackground(list.getSelectionBackground());
setForeground(list.getSelectionForeground());
}
else
{
setBackground(list.getBackground());
setForeground(list.getForeground());
}
return this;
}
}

View File

@@ -0,0 +1,428 @@
/*******************************************************************************
* 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 io.github.dsheirer.icon;
import io.github.dsheirer.properties.SystemProperties;
import io.github.dsheirer.util.ThreadPool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.swing.*;
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;
import javax.xml.bind.Unmarshaller;
import java.awt.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
public class IconManager
{
private final static Logger mLog = LoggerFactory.getLogger(IconManager.class);
public static final int DEFAULT_ICON_SIZE = 12;
private Path mIconFolderPath;
private Path mIconFilePath;
private Path mIconBackupFilePath;
private Path mIconLockFilePath;
private IconEditor mIconEditor;
private IconTableModel mIconTableModel;
private AtomicBoolean mSavingIcons = new AtomicBoolean();
private Map<String,ImageIcon> mResizedIcons = new HashMap<>();
public IconManager()
{
}
/**
* Display the icon editor centered over the specified component.
*
* @param centerOnComponent to center the editor
*/
public void showEditor(Component centerOnComponent)
{
if(mIconEditor == null)
{
mIconEditor = new IconEditor(this);
}
mIconEditor.setLocationRelativeTo(centerOnComponent);
if(mIconEditor.isVisible())
{
mIconEditor.requestFocus();
}
else
{
EventQueue.invokeLater(new Runnable()
{
@Override
public void run()
{
mIconEditor.setVisible(true);
}
});
}
}
public IconTableModel getModel()
{
if(mIconTableModel == null)
{
IconSet loadedIcons = load();
boolean saveRequired = false;
if(loadedIcons == null)
{
loadedIcons = getDefaultIconSet();
saveRequired = true;
}
mIconTableModel = new IconTableModel(loadedIcons);
mIconTableModel.addTableModelListener(new TableModelListener()
{
@Override
public void tableChanged(TableModelEvent e)
{
scheduleSave();
}
});
if(saveRequired)
{
scheduleSave();
}
}
return mIconTableModel;
}
/**
* All icons in a sorted array
*/
public io.github.dsheirer.icon.Icon[] getIcons()
{
return getModel().getIconsAsArray();
}
/**
* Returns named icon scaled to the specified height. Utilizes an internal map to retain scaled icons so that they
* are only scaled/generated once.
*
* @param name - name of icon
* @param height - height of icon in pixels
* @return - scaled named icon (if it exists) or a scaled version of the default icon
*/
public ImageIcon getIcon(String name, int height)
{
if(name == null)
{
name = getModel().getDefaultIcon().getName();
}
String scaledIconName = name + height;
if(mResizedIcons.containsKey(scaledIconName))
{
return mResizedIcons.get(scaledIconName);
}
io.github.dsheirer.icon.Icon icon = getModel().getIcon(name);
ImageIcon scaledIcon = getScaledIcon(icon.getIcon(), height);
mResizedIcons.put(scaledIconName, scaledIcon);
return scaledIcon;
}
/**
* Scales the icon to the new pixel height value
*
* @param original image icon
* @param height new height to scale the image (width will be scaled accordingly)
* @return
*/
public static ImageIcon getScaledIcon(ImageIcon original, int height)
{
double scale = (double) original.getIconHeight() / (double) height;
int scaledWidth = (int) ((double) original.getIconWidth() / scale);
Image scaledImage = original.getImage().getScaledInstance(scaledWidth,
height, java.awt.Image.SCALE_SMOOTH);
return new ImageIcon(scaledImage);
}
/**
* Folder where icon, backup and lock files are stored
*/
private Path getIconFolderPath()
{
if(mIconFolderPath == null)
{
SystemProperties props = SystemProperties.getInstance();
mIconFolderPath = props.getApplicationFolder("settings");
}
return mIconFolderPath;
}
/**
* Path to current icon file
*/
private Path getIconFilePath()
{
if(mIconFilePath == null)
{
mIconFilePath = getIconFolderPath().resolve("icons.xml");
}
return mIconFilePath;
}
/**
* Path to most recent playlist backup
*/
private Path getIconBackupFilePath()
{
if(mIconBackupFilePath == null)
{
mIconBackupFilePath = getIconFolderPath().resolve("icons.backup");
}
return mIconBackupFilePath;
}
/**
* Path to playlist lock file that is created prior to saving a playlist and removed immediately thereafter.
* Presence of a lock file indicates an incomplete or corrupt playlist file on startup.
*/
private Path getIconLockFilePath()
{
if(mIconLockFilePath == null)
{
mIconLockFilePath = getIconFolderPath().resolve("icons.lock");
}
return mIconLockFilePath;
}
/**
* Saves the current playlist
*/
private void save()
{
IconSet iconSet = getModel().getIconSet();
JAXBContext context = null;
//Create a backup copy of the current playlist
if(Files.exists(getIconFilePath()))
{
try
{
Files.copy(getIconFilePath(), getIconBackupFilePath(), StandardCopyOption.REPLACE_EXISTING);
}
catch(Exception e)
{
mLog.error("Error creating backup copy of current icons prior to saving updates [" +
getIconFilePath().toString() + "]", e);
}
}
//Create a temporary lock file to signify that we're in the process of updating the playlist
if(!Files.exists(getIconLockFilePath()))
{
try
{
Files.createFile(getIconLockFilePath());
}
catch(IOException e)
{
mLog.error("Error creating temporary lock file prior to saving icons [" +
getIconLockFilePath().toString() + "]", e);
}
}
try(OutputStream out = Files.newOutputStream(getIconFilePath()))
{
context = JAXBContext.newInstance(IconSet.class);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
m.marshal(iconSet, out);
out.flush();
//Remove the playlist lock file to indicate that we successfully saved the file
if(Files.exists(getIconLockFilePath()))
{
Files.delete(getIconLockFilePath());
}
}
catch(JAXBException je)
{
mLog.error("JAXB exception while serializing icons to a file [" + getIconFilePath().toString() + "]", je);
}
catch(IOException ioe)
{
mLog.error("IO error while writing icons to a file [" + getIconFilePath().toString() + "]", ioe);
}
catch(Exception e)
{
mLog.error("Error while saving icons [" + getIconFilePath().toString() + "]", e);
}
}
/**
* Loads icons from file or creates a default set of icons
*/
public IconSet load()
{
mLog.info("loading icons file [" + getIconFilePath().toString() + "]");
IconSet iconSet = null;
//Check for a lock file that indicates the previous save attempt was incomplete or had an error
if(Files.exists(getIconLockFilePath()))
{
try
{
//Remove the previous icons file
Files.delete(getIconFilePath());
//Copy the backup file to restore the previous icons file
if(Files.exists(getIconBackupFilePath()))
{
Files.copy(getIconBackupFilePath(), getIconFilePath());
}
//Remove the lock file
Files.delete(getIconLockFilePath());
}
catch(IOException ioe)
{
mLog.error("Previous icons save attempt was incomplete and there was an error restoring the " +
"icons backup file", ioe);
}
}
if(Files.exists(getIconFilePath()))
{
JAXBContext context = null;
try(InputStream in = Files.newInputStream(getIconFilePath()))
{
context = JAXBContext.newInstance(IconSet.class);
Unmarshaller m = context.createUnmarshaller();
iconSet = (IconSet) m.unmarshal(in);
}
catch(JAXBException je)
{
mLog.error("JAXB exception while loading/unmarshalling icons", je);
}
catch(IOException ioe)
{
mLog.error("IO error while reading icons file", ioe);
}
}
else
{
mLog.info("Icons file not found at [" + getIconFilePath().toString() + "]");
}
return iconSet;
}
/**
* Creates a default icon set
*/
private IconSet getDefaultIconSet()
{
IconSet iconSet = new IconSet();
io.github.dsheirer.icon.Icon defaultIcon = new io.github.dsheirer.icon.Icon(IconTableModel.DEFAULT_ICON, "images/no_icon.png");
iconSet.add(defaultIcon);
iconSet.setDefaultIcon(defaultIcon.getName());
iconSet.add(new io.github.dsheirer.icon.Icon("Ambulance", "images/ambulance.png"));
iconSet.add(new io.github.dsheirer.icon.Icon("Block Truck", "images/concrete_block_truck.png"));
iconSet.add(new io.github.dsheirer.icon.Icon("CWID", "images/cwid.png"));
iconSet.add(new io.github.dsheirer.icon.Icon("Dispatcher", "images/dispatcher.png"));
iconSet.add(new io.github.dsheirer.icon.Icon("Dump Truck", "images/dump_truck_red.png"));
iconSet.add(new io.github.dsheirer.icon.Icon("Fire Truck", "images/fire_truck.png"));
iconSet.add(new io.github.dsheirer.icon.Icon("Garbage Truck", "images/garbage_truck.png"));
iconSet.add(new io.github.dsheirer.icon.Icon("Loader", "images/loader.png"));
iconSet.add(new io.github.dsheirer.icon.Icon("Police", "images/police.png"));
iconSet.add(new io.github.dsheirer.icon.Icon("Propane Truck", "images/propane_truck.png"));
iconSet.add(new io.github.dsheirer.icon.Icon("Rescue Truck", "images/rescue_truck.png"));
iconSet.add(new io.github.dsheirer.icon.Icon("School Bus", "images/school_bus.png"));
iconSet.add(new io.github.dsheirer.icon.Icon("Taxi", "images/taxi.png"));
iconSet.add(new io.github.dsheirer.icon.Icon("Train", "images/train.png"));
iconSet.add(new io.github.dsheirer.icon.Icon("Transport Bus", "images/opt_bus.png"));
iconSet.add(new io.github.dsheirer.icon.Icon("Van", "images/van.png"));
return iconSet;
}
/**
* Schedules an icon file save task. Subsequent calls to this method will be ignored until the save event occurs,
* thus limiting repetitive saving to a minimum.
*/
private void scheduleSave()
{
if(mSavingIcons.compareAndSet(false, true))
{
ThreadPool.SCHEDULED.schedule(new IconSaveTask(), 2, TimeUnit.SECONDS);
}
}
/**
* Resets the playlist save pending flag to false and proceeds to save the playlist.
*/
public class IconSaveTask implements Runnable
{
@Override
public void run()
{
save();
mSavingIcons.set(false);
}
}
}

View File

@@ -0,0 +1,173 @@
/*******************************************************************************
* 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 io.github.dsheirer.icon;
import net.miginfocom.swing.MigLayout;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
public class IconSelector extends JDialog implements DocumentListener
{
private IconTableModel mIconTableModel;
private JTextField mNameText;
private JTextField mFileLabel;
private JButton mFileChooserButton;
private JButton mOKButton;
private JButton mCancelButton;
/**
* Window for selecting an Icon to add to the Icon Model
*
* @param owner for this modal dialog
* @param iconTableModel to receive the added/selected icon
*/
public IconSelector(Frame owner, IconTableModel iconTableModel)
{
super(owner, "Add Icon", true);
mIconTableModel = iconTableModel;
init();
setLocationRelativeTo(owner);
}
private void init()
{
setSize(250, 170);
JPanel contentPanel = new JPanel();
contentPanel.setPreferredSize(new Dimension(250, 170));
contentPanel.setLayout(new MigLayout("insets 1 1 1 1", "[align right][align left,grow,fill]", "[][][][grow,fill][]"));
contentPanel.add(new JLabel("Name"));
mNameText = new JTextField();
mNameText.getDocument().addDocumentListener(this);
contentPanel.add(mNameText, "wrap");
contentPanel.add(new JLabel("File"));
mFileLabel = new JTextField();
mFileLabel.setEnabled(false);
contentPanel.add(mFileLabel, "wrap");
mFileChooserButton = new JButton("Select File ...");
mFileChooserButton.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
JFileChooser fileChooser = new JFileChooser();
// fileChooser.setSelectedFile(null);
//Add a custom file filter and disable the default
fileChooser.addChoosableFileFilter(new ImageFilter());
fileChooser.setAcceptAllFileFilterUsed(false);
int returnVal = fileChooser.showDialog(IconSelector.this, "Select");
if(returnVal == JFileChooser.APPROVE_OPTION)
{
File file = fileChooser.getSelectedFile();
if(file != null)
{
mFileLabel.setText(file.getAbsolutePath());
checkButtons();
}
}
}
});
contentPanel.add(mFileChooserButton, "span,align center");
contentPanel.add(new JLabel(), "wrap");
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new MigLayout("", "[grow,fill][grow,fill]", "[]"));
mOKButton = new JButton("OK");
mOKButton.setEnabled(false);
mOKButton.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
String name = mNameText.getText();
String path = mFileLabel.getText();
io.github.dsheirer.icon.Icon icon = new io.github.dsheirer.icon.Icon(name, path);
mIconTableModel.add(icon);
IconSelector.this.dispose();
}
});
mCancelButton = new JButton("Cancel");
mCancelButton.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
IconSelector.this.dispose();
}
});
buttonPanel.add(mOKButton);
buttonPanel.add(mCancelButton);
contentPanel.add(buttonPanel, "span,grow");
add(contentPanel);
}
private void checkButtons()
{
String name = mNameText.getText();
String path = mFileLabel.getText();
mOKButton.setEnabled(name != null && path != null && !path.isEmpty() && !mIconTableModel.hasIcon(name));
}
@Override
public void insertUpdate(DocumentEvent e)
{
checkButtons();
}
@Override
public void removeUpdate(DocumentEvent e)
{
checkButtons();
}
@Override
public void changedUpdate(DocumentEvent e)
{
checkButtons();
}
}

View File

@@ -0,0 +1,74 @@
/*******************************************************************************
* 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 io.github.dsheirer.icon;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.ArrayList;
import java.util.List;
@XmlRootElement(name="iconset")
public class IconSet
{
private String mDefaultIcon;
private List<Icon> mIcons = new ArrayList<>();
public IconSet()
{
//No-arg JAXB constructor
}
public void add(Icon icon)
{
mIcons.add(icon);
}
public void remove(Icon icon)
{
mIcons.remove(icon);
}
@XmlElement(name = "icon")
public List<Icon> getIcons()
{
if(mIcons == null)
{
mIcons = new ArrayList<>();
}
return mIcons;
}
public void setIcons(List<Icon> icons)
{
mIcons = icons;
}
@XmlAttribute(name = "default")
public String getDefaultIcon()
{
return mDefaultIcon;
}
public void setDefaultIcon(String name)
{
mDefaultIcon = name;
}
}

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 io.github.dsheirer.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 io.github.dsheirer.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 io.github.dsheirer.icon.Icon mDefaultIcon;
private Map<String,io.github.dsheirer.icon.Icon> mIconMap = new HashMap<>();
private List<io.github.dsheirer.icon.Icon> mIcons = new ArrayList<>();
public IconTableModel()
{
setDefaultIcon(DEFAULT_ICON);
}
public IconTableModel(IconSet iconSet)
{
mIconMap.clear();
mIcons.clear();
fireTableDataChanged();
for(io.github.dsheirer.icon.Icon icon: iconSet.getIcons())
{
add(icon);
}
setDefaultIcon(iconSet.getDefaultIcon());
}
/**
* Adds the icon to the model
*/
public void add(io.github.dsheirer.icon.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(io.github.dsheirer.icon.Icon icon)
{
if(icon != null && mIcons.contains(icon))
{
int index = mIcons.indexOf(icon);
mIcons.remove(icon);
mIconMap.remove(icon.getName());
fireTableRowsDeleted(index, index);
}
}
public io.github.dsheirer.icon.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())
{
io.github.dsheirer.icon.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 io.github.dsheirer.icon.Icon[] getIconsAsArray()
{
List<io.github.dsheirer.icon.Icon> icons = new ArrayList<>(mIconMap.values());
Collections.sort(icons);
return icons.toArray(new io.github.dsheirer.icon.Icon[icons.size()]);
}
/**
* Returns the current default icon
*/
public io.github.dsheirer.icon.Icon getDefaultIcon()
{
return mDefaultIcon;
}
/**
* Indicates if the icon argument is the current default icon
*/
public boolean isDefaultIcon(io.github.dsheirer.icon.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(io.github.dsheirer.icon.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;
}
io.github.dsheirer.icon.Icon defaultIcon = mIconMap.get(name);
if(defaultIcon != null)
{
setDefaultIcon(defaultIcon);
}
else
{
defaultIcon = new io.github.dsheirer.icon.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 io.github.dsheirer.icon.Icon getIcon(String name)
{
if(name == null || name.isEmpty())
{
return mDefaultIcon;
}
io.github.dsheirer.icon.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<io.github.dsheirer.icon.Icon>(mIconMap.values()));
iconSet.setDefaultIcon(getDefaultIcon().getName());
return iconSet;
}
}

View File

@@ -0,0 +1,74 @@
/*******************************************************************************
* 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 io.github.dsheirer.icon;
import javax.swing.filechooser.FileFilter;
import java.io.File;
public class ImageFilter extends FileFilter
{
//Accept all directories and all gif, jpg, tiff, or png files.
public boolean accept(File f)
{
if(f.isDirectory())
{
return true;
}
String extension = getExtension(f);
if(extension != null)
{
if(extension.equals("tiff") ||
extension.equals("tif") ||
extension.equals("gif") ||
extension.equals("jpeg") ||
extension.equals("jpg") ||
extension.equals("png"))
{
return true;
}
else
{
return false;
}
}
return false;
}
//The description of this filter
public String getDescription()
{
return "Images (*.gif,*.jpg,*.png.";
}
public String getExtension(File f)
{
String ext = null;
String s = f.getName();
int i = s.lastIndexOf('.');
if(i > 0 && i < s.length() - 1)
{
ext = s.substring(i + 1).toLowerCase();
}
return ext;
}
}