mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-12 08:37:25 -05:00
#82 WIP - reorganizing icon management and extracting icon model from the settings manager.
This commit is contained in:
@@ -1,369 +1,356 @@
|
||||
package alias;
|
||||
|
||||
import audio.broadcast.BroadcastModel;
|
||||
import com.jidesoft.swing.JideSplitPane;
|
||||
import gui.editor.Editor;
|
||||
import icon.IconManager;
|
||||
import net.coderazzi.filters.gui.AutoChoices;
|
||||
import net.coderazzi.filters.gui.TableFilterHeader;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Rectangle;
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
import javax.swing.table.DefaultTableCellRenderer;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.ListSelectionModel;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
import javax.swing.table.DefaultTableCellRenderer;
|
||||
|
||||
import net.coderazzi.filters.gui.AutoChoices;
|
||||
import net.coderazzi.filters.gui.TableFilterHeader;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import settings.SettingsManager;
|
||||
|
||||
import com.jidesoft.swing.JideSplitPane;
|
||||
|
||||
public class AliasController extends JPanel
|
||||
implements ActionListener, ListSelectionListener
|
||||
public class AliasController extends JPanel
|
||||
implements ActionListener, ListSelectionListener
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private AliasModel mAliasModel;
|
||||
private JTable mAliasTable;
|
||||
private TableFilterHeader mTableFilterHeader;
|
||||
private AliasEditor mAliasEditor;
|
||||
private MultipleAliasEditor mMultipleAliasEditor;
|
||||
private JideSplitPane mSplitPane;
|
||||
|
||||
private static final String NEW_ALIAS = "New";
|
||||
private static final String COPY_ALIAS = "Copy";
|
||||
private static final String DELETE_ALIAS = "Delete";
|
||||
|
||||
private JButton mNewButton = new JButton( NEW_ALIAS );
|
||||
private JButton mCopyButton = new JButton( COPY_ALIAS );
|
||||
private JButton mDeleteButton = new JButton( DELETE_ALIAS );
|
||||
|
||||
private IconCellRenderer mIconCellRenderer;
|
||||
private AliasModel mAliasModel;
|
||||
private JTable mAliasTable;
|
||||
private TableFilterHeader mTableFilterHeader;
|
||||
private AliasEditor mAliasEditor;
|
||||
private MultipleAliasEditor mMultipleAliasEditor;
|
||||
private JideSplitPane mSplitPane;
|
||||
|
||||
public AliasController(AliasModel aliasModel, BroadcastModel broadcastModel, SettingsManager settingsManager )
|
||||
{
|
||||
mAliasModel = aliasModel;
|
||||
private static final String NEW_ALIAS = "New";
|
||||
private static final String COPY_ALIAS = "Copy";
|
||||
private static final String DELETE_ALIAS = "Delete";
|
||||
|
||||
mAliasEditor = new AliasEditor( mAliasModel, broadcastModel, settingsManager );
|
||||
mMultipleAliasEditor = new MultipleAliasEditor( mAliasModel, broadcastModel, settingsManager );
|
||||
private JButton mNewButton = new JButton(NEW_ALIAS);
|
||||
private JButton mCopyButton = new JButton(COPY_ALIAS);
|
||||
private JButton mDeleteButton = new JButton(DELETE_ALIAS);
|
||||
|
||||
mIconCellRenderer = new IconCellRenderer( settingsManager );
|
||||
|
||||
init();
|
||||
|
||||
mAliasModel.addListener( mAliasEditor );
|
||||
}
|
||||
|
||||
private void init()
|
||||
{
|
||||
setLayout( new MigLayout( "insets 0 0 0 0",
|
||||
"[grow,fill]",
|
||||
"[grow,fill]") );
|
||||
private IconCellRenderer mIconCellRenderer;
|
||||
|
||||
//System Configuration View and Editor
|
||||
mAliasTable = new JTable( mAliasModel );
|
||||
mAliasTable.setSelectionMode( ListSelectionModel.MULTIPLE_INTERVAL_SELECTION );
|
||||
mAliasTable.getSelectionModel().addListSelectionListener( this );
|
||||
mAliasTable.setAutoCreateRowSorter( true );
|
||||
|
||||
mAliasTable.getColumnModel().getColumn( AliasModel.COLUMN_COLOR )
|
||||
.setCellRenderer( new ColorCellRenderer() );
|
||||
|
||||
mAliasTable.getColumnModel().getColumn( AliasModel.COLUMN_ICON )
|
||||
.setCellRenderer( mIconCellRenderer );
|
||||
public AliasController(AliasModel aliasModel, BroadcastModel broadcastModel, IconManager iconManager)
|
||||
{
|
||||
mAliasModel = aliasModel;
|
||||
|
||||
mTableFilterHeader = new TableFilterHeader( mAliasTable, AutoChoices.ENABLED );
|
||||
mTableFilterHeader.setFilterOnUpdates( true );
|
||||
|
||||
JScrollPane tableScroller = new JScrollPane( mAliasTable );
|
||||
mAliasEditor = new AliasEditor(mAliasModel, broadcastModel, iconManager);
|
||||
mMultipleAliasEditor = new MultipleAliasEditor(mAliasModel, broadcastModel, iconManager);
|
||||
|
||||
JPanel buttonsPanel = new JPanel();
|
||||
|
||||
buttonsPanel.setLayout(
|
||||
new MigLayout( "insets 0 0 0 0", "[grow,fill][grow,fill][grow,fill]", "[]") );
|
||||
mIconCellRenderer = new IconCellRenderer(iconManager);
|
||||
|
||||
mNewButton.addActionListener( this );
|
||||
mNewButton.setToolTipText( "Adds a new alias" );
|
||||
buttonsPanel.add( mNewButton );
|
||||
|
||||
mCopyButton.addActionListener( this );
|
||||
mCopyButton.setEnabled( false );
|
||||
mCopyButton.setToolTipText( "Creates a copy of the currently selected alias and adds it" );
|
||||
buttonsPanel.add( mCopyButton );
|
||||
init();
|
||||
|
||||
mDeleteButton.addActionListener( this );
|
||||
mDeleteButton.setEnabled( false );
|
||||
mDeleteButton.setToolTipText( "Deletes the currently selected alias" );
|
||||
buttonsPanel.add( mDeleteButton );
|
||||
|
||||
JPanel listAndButtonsPanel = new JPanel();
|
||||
mAliasModel.addListener(mAliasEditor);
|
||||
}
|
||||
|
||||
listAndButtonsPanel.setLayout(
|
||||
new MigLayout( "insets 0 0 0 0", "[grow,fill]", "[grow,fill][]") );
|
||||
private void init()
|
||||
{
|
||||
setLayout(new MigLayout("insets 0 0 0 0",
|
||||
"[grow,fill]",
|
||||
"[grow,fill]"));
|
||||
|
||||
listAndButtonsPanel.add( tableScroller, "wrap" );
|
||||
listAndButtonsPanel.add( buttonsPanel );
|
||||
|
||||
mSplitPane = new JideSplitPane( JideSplitPane.HORIZONTAL_SPLIT );
|
||||
mSplitPane.setDividerSize( 5 );
|
||||
mSplitPane.setShowGripper( true );
|
||||
mSplitPane.add( listAndButtonsPanel );
|
||||
mSplitPane.add( mAliasEditor );
|
||||
//System Configuration View and Editor
|
||||
mAliasTable = new JTable(mAliasModel);
|
||||
mAliasTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
|
||||
mAliasTable.getSelectionModel().addListSelectionListener(this);
|
||||
mAliasTable.setAutoCreateRowSorter(true);
|
||||
|
||||
add( mSplitPane );
|
||||
}
|
||||
mAliasTable.getColumnModel().getColumn(AliasModel.COLUMN_COLOR)
|
||||
.setCellRenderer(new ColorCellRenderer());
|
||||
|
||||
/**
|
||||
* Sets the editor argument as the currently visible alias editor
|
||||
*/
|
||||
private void setEditor( Editor<?> editor )
|
||||
{
|
||||
if( mSplitPane.getComponentCount() == 3 )
|
||||
{
|
||||
Component component = mSplitPane.getComponent( 2 );
|
||||
|
||||
if( component instanceof Editor<?> && component != editor )
|
||||
{
|
||||
//Get current divider location so that we can reapply it after
|
||||
//changing out the editors, so that the interface doesn't move
|
||||
int location = mSplitPane.getDividerLocation( 0 );
|
||||
|
||||
((Editor<?>)component).setItem( null );
|
||||
|
||||
mSplitPane.remove( component );
|
||||
editor.setPreferredSize( new Dimension( 100, 100 ) );
|
||||
mSplitPane.add( editor );
|
||||
|
||||
mSplitPane.validate();
|
||||
mSplitPane.setDividerLocation( 0, location );
|
||||
mSplitPane.repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Alias getAlias( int selectedRow )
|
||||
{
|
||||
if( selectedRow >= 0 )
|
||||
{
|
||||
int index = mAliasTable.convertRowIndexToModel( selectedRow );
|
||||
|
||||
return mAliasModel.getAliasAtIndex( index );
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
mAliasTable.getColumnModel().getColumn(AliasModel.COLUMN_ICON)
|
||||
.setCellRenderer(mIconCellRenderer);
|
||||
|
||||
@Override
|
||||
public void valueChanged( ListSelectionEvent event )
|
||||
{
|
||||
//Limits event firing to only when selection is complete
|
||||
if( !event.getValueIsAdjusting() )
|
||||
{
|
||||
int[] selectedRows = mAliasTable.getSelectedRows();
|
||||
mTableFilterHeader = new TableFilterHeader(mAliasTable, AutoChoices.ENABLED);
|
||||
mTableFilterHeader.setFilterOnUpdates(true);
|
||||
|
||||
if( selectedRows.length == 0 )
|
||||
{
|
||||
mAliasEditor.setItem( null );
|
||||
mCopyButton.setEnabled( false );
|
||||
mDeleteButton.setEnabled( false );
|
||||
}
|
||||
else if( selectedRows.length == 1 )
|
||||
{
|
||||
setEditor( mAliasEditor );
|
||||
|
||||
Alias selectedAlias = getAlias( selectedRows[ 0 ] );
|
||||
|
||||
mAliasEditor.setItem( selectedAlias );
|
||||
|
||||
if( selectedAlias != null )
|
||||
{
|
||||
mCopyButton.setEnabled( true );
|
||||
mDeleteButton.setEnabled( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
mCopyButton.setEnabled( false );
|
||||
mDeleteButton.setEnabled( false );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
setEditor( mMultipleAliasEditor );
|
||||
|
||||
mCopyButton.setEnabled( true );
|
||||
mDeleteButton.setEnabled( true );
|
||||
JScrollPane tableScroller = new JScrollPane(mAliasTable);
|
||||
|
||||
List<Alias> selectedAliases = new ArrayList<Alias>();
|
||||
|
||||
for( int selectedRow: selectedRows )
|
||||
{
|
||||
Alias alias = getAlias( selectedRow );
|
||||
JPanel buttonsPanel = new JPanel();
|
||||
|
||||
selectedAliases.add( alias );
|
||||
}
|
||||
|
||||
mMultipleAliasEditor.setItem( selectedAliases );
|
||||
}
|
||||
}
|
||||
}
|
||||
buttonsPanel.setLayout(
|
||||
new MigLayout("insets 0 0 0 0", "[grow,fill][grow,fill][grow,fill]", "[]"));
|
||||
|
||||
/**
|
||||
* Adds the alias to the alias table/model and scrolls the view it
|
||||
*/
|
||||
private void addAlias( Alias alias )
|
||||
{
|
||||
//HACK: when inserting a row to the model, the JTable gets
|
||||
//notified and attempts to tell the coderazzi table filter
|
||||
//adaptive choices filter to refresh before the table filter is
|
||||
//notified of the row additions, causing an index out of bounds
|
||||
//exception. We turn off adaptive choices temporarily, add the
|
||||
//channel, and turn on adaptive choices again.
|
||||
mTableFilterHeader.setAdaptiveChoices( false );
|
||||
|
||||
int index = mAliasModel.addAlias( alias );
|
||||
mNewButton.addActionListener(this);
|
||||
mNewButton.setToolTipText("Adds a new alias");
|
||||
buttonsPanel.add(mNewButton);
|
||||
|
||||
mTableFilterHeader.setAdaptiveChoices( true );
|
||||
mCopyButton.addActionListener(this);
|
||||
mCopyButton.setEnabled(false);
|
||||
mCopyButton.setToolTipText("Creates a copy of the currently selected alias and adds it");
|
||||
buttonsPanel.add(mCopyButton);
|
||||
|
||||
if( index >= 0 )
|
||||
{
|
||||
int translatedIndex = mAliasTable.convertRowIndexToView( index );
|
||||
mAliasTable.setRowSelectionInterval( translatedIndex, translatedIndex );
|
||||
mAliasTable.scrollRectToVisible(
|
||||
new Rectangle( mAliasTable.getCellRect( translatedIndex, 0, true ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
private List<Alias> getSelectedAliases()
|
||||
{
|
||||
List<Alias> selected = new ArrayList<>();
|
||||
|
||||
int[] rows = mAliasTable.getSelectedRows();
|
||||
mDeleteButton.addActionListener(this);
|
||||
mDeleteButton.setEnabled(false);
|
||||
mDeleteButton.setToolTipText("Deletes the currently selected alias");
|
||||
buttonsPanel.add(mDeleteButton);
|
||||
|
||||
for( int row: rows )
|
||||
{
|
||||
if( row >= 0 )
|
||||
{
|
||||
Alias alias = mAliasModel.getAliasAtIndex( mAliasTable.convertRowIndexToModel( row ) );
|
||||
|
||||
if( alias != null )
|
||||
{
|
||||
selected.add( alias );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return selected;
|
||||
}
|
||||
JPanel listAndButtonsPanel = new JPanel();
|
||||
|
||||
/**
|
||||
* Responds to New, Copy and Delete Channel button invocations
|
||||
*/
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent event )
|
||||
{
|
||||
switch( event.getActionCommand() )
|
||||
{
|
||||
case NEW_ALIAS:
|
||||
addAlias( new Alias( "New Alias" ) );
|
||||
break;
|
||||
case COPY_ALIAS:
|
||||
for( Alias alias: getSelectedAliases() )
|
||||
{
|
||||
addAlias( AliasFactory.copyOf( alias ) );
|
||||
}
|
||||
break;
|
||||
case DELETE_ALIAS:
|
||||
List<Alias> toDelete = getSelectedAliases();
|
||||
listAndButtonsPanel.setLayout(
|
||||
new MigLayout("insets 0 0 0 0", "[grow,fill]", "[grow,fill][]"));
|
||||
|
||||
if( toDelete != null && !toDelete.isEmpty() )
|
||||
{
|
||||
String title = toDelete.size() == 1 ? "Delete Alias?" : "Delete Aliases?";
|
||||
String prompt = toDelete.size() == 1 ? "Do you want to delete this alias?" :
|
||||
"Do you want to delete these " + toDelete.size() + " aliases?";
|
||||
|
||||
int choice = JOptionPane.showConfirmDialog( AliasController.this,
|
||||
prompt, title, JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE );
|
||||
|
||||
if( choice == JOptionPane.YES_OPTION )
|
||||
{
|
||||
for( Alias alias: toDelete )
|
||||
{
|
||||
mAliasModel.removeAlias( alias );
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
listAndButtonsPanel.add(tableScroller, "wrap");
|
||||
listAndButtonsPanel.add(buttonsPanel);
|
||||
|
||||
/**
|
||||
* Colorizes the cell based on the cell's integer value
|
||||
*/
|
||||
public class ColorCellRenderer extends DefaultTableCellRenderer
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
mSplitPane = new JideSplitPane(JideSplitPane.HORIZONTAL_SPLIT);
|
||||
mSplitPane.setDividerSize(5);
|
||||
mSplitPane.setShowGripper(true);
|
||||
mSplitPane.add(listAndButtonsPanel);
|
||||
mSplitPane.add(mAliasEditor);
|
||||
|
||||
@Override
|
||||
public Component getTableCellRendererComponent( JTable table,
|
||||
Object value, boolean isSelected, boolean hasFocus, int row,
|
||||
int column )
|
||||
{
|
||||
JLabel label = (JLabel)super.getTableCellRendererComponent( table,
|
||||
value, isSelected, hasFocus, row, column );
|
||||
add(mSplitPane);
|
||||
}
|
||||
|
||||
label.setBackground( new Color( (int)value ) );
|
||||
|
||||
label.setText( "" );
|
||||
|
||||
return label;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays cell's icon and name
|
||||
*/
|
||||
public class IconCellRenderer extends DefaultTableCellRenderer
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private SettingsManager mSettingsManager;
|
||||
|
||||
public IconCellRenderer( SettingsManager settingsManager )
|
||||
{
|
||||
mSettingsManager = settingsManager;
|
||||
}
|
||||
/**
|
||||
* Sets the editor argument as the currently visible alias editor
|
||||
*/
|
||||
private void setEditor(Editor<?> editor)
|
||||
{
|
||||
if(mSplitPane.getComponentCount() == 3)
|
||||
{
|
||||
Component component = mSplitPane.getComponent(2);
|
||||
|
||||
@Override
|
||||
public Component getTableCellRendererComponent( JTable table,
|
||||
Object value, boolean isSelected, boolean hasFocus, int row,
|
||||
int column )
|
||||
{
|
||||
JLabel label = (JLabel)super.getTableCellRendererComponent( table,
|
||||
value, isSelected, hasFocus, row, column );
|
||||
if(component instanceof Editor<?> && component != editor)
|
||||
{
|
||||
//Get current divider location so that we can reapply it after
|
||||
//changing out the editors, so that the interface doesn't move
|
||||
int location = mSplitPane.getDividerLocation(0);
|
||||
|
||||
ImageIcon icon = mSettingsManager.getImageIcon( label.getText(), 12 );
|
||||
((Editor<?>) component).setItem(null);
|
||||
|
||||
if( icon != null )
|
||||
{
|
||||
label.setIcon( icon );
|
||||
}
|
||||
|
||||
return label;
|
||||
}
|
||||
}
|
||||
mSplitPane.remove(component);
|
||||
editor.setPreferredSize(new Dimension(100, 100));
|
||||
mSplitPane.add(editor);
|
||||
|
||||
mSplitPane.validate();
|
||||
mSplitPane.setDividerLocation(0, location);
|
||||
mSplitPane.repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Alias getAlias(int selectedRow)
|
||||
{
|
||||
if(selectedRow >= 0)
|
||||
{
|
||||
int index = mAliasTable.convertRowIndexToModel(selectedRow);
|
||||
|
||||
return mAliasModel.getAliasAtIndex(index);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void valueChanged(ListSelectionEvent event)
|
||||
{
|
||||
//Limits event firing to only when selection is complete
|
||||
if(!event.getValueIsAdjusting())
|
||||
{
|
||||
int[] selectedRows = mAliasTable.getSelectedRows();
|
||||
|
||||
if(selectedRows.length == 0)
|
||||
{
|
||||
mAliasEditor.setItem(null);
|
||||
mCopyButton.setEnabled(false);
|
||||
mDeleteButton.setEnabled(false);
|
||||
}
|
||||
else if(selectedRows.length == 1)
|
||||
{
|
||||
setEditor(mAliasEditor);
|
||||
|
||||
Alias selectedAlias = getAlias(selectedRows[0]);
|
||||
|
||||
mAliasEditor.setItem(selectedAlias);
|
||||
|
||||
if(selectedAlias != null)
|
||||
{
|
||||
mCopyButton.setEnabled(true);
|
||||
mDeleteButton.setEnabled(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
mCopyButton.setEnabled(false);
|
||||
mDeleteButton.setEnabled(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
setEditor(mMultipleAliasEditor);
|
||||
|
||||
mCopyButton.setEnabled(true);
|
||||
mDeleteButton.setEnabled(true);
|
||||
|
||||
List<Alias> selectedAliases = new ArrayList<Alias>();
|
||||
|
||||
for(int selectedRow : selectedRows)
|
||||
{
|
||||
Alias alias = getAlias(selectedRow);
|
||||
|
||||
selectedAliases.add(alias);
|
||||
}
|
||||
|
||||
mMultipleAliasEditor.setItem(selectedAliases);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the alias to the alias table/model and scrolls the view it
|
||||
*/
|
||||
private void addAlias(Alias alias)
|
||||
{
|
||||
//HACK: when inserting a row to the model, the JTable gets
|
||||
//notified and attempts to tell the coderazzi table filter
|
||||
//adaptive choices filter to refresh before the table filter is
|
||||
//notified of the row additions, causing an index out of bounds
|
||||
//exception. We turn off adaptive choices temporarily, add the
|
||||
//channel, and turn on adaptive choices again.
|
||||
mTableFilterHeader.setAdaptiveChoices(false);
|
||||
|
||||
int index = mAliasModel.addAlias(alias);
|
||||
|
||||
mTableFilterHeader.setAdaptiveChoices(true);
|
||||
|
||||
if(index >= 0)
|
||||
{
|
||||
int translatedIndex = mAliasTable.convertRowIndexToView(index);
|
||||
mAliasTable.setRowSelectionInterval(translatedIndex, translatedIndex);
|
||||
mAliasTable.scrollRectToVisible(
|
||||
new Rectangle(mAliasTable.getCellRect(translatedIndex, 0, true)));
|
||||
}
|
||||
}
|
||||
|
||||
private List<Alias> getSelectedAliases()
|
||||
{
|
||||
List<Alias> selected = new ArrayList<>();
|
||||
|
||||
int[] rows = mAliasTable.getSelectedRows();
|
||||
|
||||
for(int row : rows)
|
||||
{
|
||||
if(row >= 0)
|
||||
{
|
||||
Alias alias = mAliasModel.getAliasAtIndex(mAliasTable.convertRowIndexToModel(row));
|
||||
|
||||
if(alias != null)
|
||||
{
|
||||
selected.add(alias);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return selected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Responds to New, Copy and Delete Channel button invocations
|
||||
*/
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent event)
|
||||
{
|
||||
switch(event.getActionCommand())
|
||||
{
|
||||
case NEW_ALIAS:
|
||||
addAlias(new Alias("New Alias"));
|
||||
break;
|
||||
case COPY_ALIAS:
|
||||
for(Alias alias : getSelectedAliases())
|
||||
{
|
||||
addAlias(AliasFactory.copyOf(alias));
|
||||
}
|
||||
break;
|
||||
case DELETE_ALIAS:
|
||||
List<Alias> toDelete = getSelectedAliases();
|
||||
|
||||
if(toDelete != null && !toDelete.isEmpty())
|
||||
{
|
||||
String title = toDelete.size() == 1 ? "Delete Alias?" : "Delete Aliases?";
|
||||
String prompt = toDelete.size() == 1 ? "Do you want to delete this alias?" :
|
||||
"Do you want to delete these " + toDelete.size() + " aliases?";
|
||||
|
||||
int choice = JOptionPane.showConfirmDialog(AliasController.this,
|
||||
prompt, title, JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
|
||||
|
||||
if(choice == JOptionPane.YES_OPTION)
|
||||
{
|
||||
for(Alias alias : toDelete)
|
||||
{
|
||||
mAliasModel.removeAlias(alias);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Colorizes the cell based on the cell's integer value
|
||||
*/
|
||||
public class ColorCellRenderer extends DefaultTableCellRenderer
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public Component getTableCellRendererComponent(JTable table,
|
||||
Object value, boolean isSelected, boolean hasFocus, int row,
|
||||
int column)
|
||||
{
|
||||
JLabel label = (JLabel) super.getTableCellRendererComponent(table,
|
||||
value, isSelected, hasFocus, row, column);
|
||||
|
||||
label.setBackground(new Color((int) value));
|
||||
|
||||
label.setText("");
|
||||
|
||||
return label;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays cell's icon and name
|
||||
*/
|
||||
public class IconCellRenderer extends DefaultTableCellRenderer
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private IconManager mIconManager;
|
||||
|
||||
public IconCellRenderer(IconManager iconManager)
|
||||
{
|
||||
mIconManager = iconManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getTableCellRendererComponent(JTable table,
|
||||
Object value, boolean isSelected, boolean hasFocus, int row,
|
||||
int column)
|
||||
{
|
||||
JLabel label = (JLabel) super.getTableCellRendererComponent(table,
|
||||
value, isSelected, hasFocus, row, column);
|
||||
|
||||
ImageIcon icon = mIconManager.getIcon(label.getText(), 12);
|
||||
|
||||
if(icon != null)
|
||||
{
|
||||
label.setIcon(icon);
|
||||
}
|
||||
|
||||
return label;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import javax.swing.JButton;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JSeparator;
|
||||
|
||||
import icon.IconManager;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import sample.Listener;
|
||||
import settings.SettingsManager;
|
||||
@@ -50,10 +51,10 @@ public class AliasEditor extends Editor<Alias>
|
||||
private AliasIdentifierEditor mAliasIdentifierEditor;
|
||||
private AliasActionEditor mAliasActionEditor;
|
||||
|
||||
public AliasEditor(AliasModel aliasModel, BroadcastModel broadcastModel, SettingsManager settingsManager )
|
||||
public AliasEditor(AliasModel aliasModel, BroadcastModel broadcastModel, IconManager iconManager )
|
||||
{
|
||||
mAliasModel = aliasModel;
|
||||
mAliasNameEditor = new AliasNameEditor( mAliasModel, settingsManager );
|
||||
mAliasNameEditor = new AliasNameEditor( mAliasModel, iconManager );
|
||||
mAliasIdentifierEditor = new AliasIdentifierEditor( aliasModel, broadcastModel );
|
||||
mAliasActionEditor = new AliasActionEditor( aliasModel );
|
||||
|
||||
|
||||
@@ -1,291 +1,278 @@
|
||||
package alias;
|
||||
|
||||
import alias.AliasEvent.Event;
|
||||
import gui.editor.Editor;
|
||||
import icon.Icon;
|
||||
import icon.IconCellRenderer;
|
||||
import icon.IconManager;
|
||||
import map.MapIcon;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import settings.SettingsManager;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.EventQueue;
|
||||
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.util.List;
|
||||
|
||||
import javax.swing.ComboBoxModel;
|
||||
import javax.swing.DefaultComboBoxModel;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JColorChooser;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
|
||||
import map.IconManager;
|
||||
import map.MapIcon;
|
||||
import map.MapIconListCellRenderer;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import settings.SettingsManager;
|
||||
import alias.AliasEvent.Event;
|
||||
|
||||
public class AliasNameEditor extends Editor<Alias>
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static ComboBoxModel<String> EMPTY_MODEL = new DefaultComboBoxModel<>();
|
||||
private static ComboBoxModel<String> EMPTY_MODEL = new DefaultComboBoxModel<>();
|
||||
|
||||
private JComboBox<String> mListCombo = new JComboBox<>( EMPTY_MODEL );
|
||||
private JComboBox<String> mGroupCombo = new JComboBox<>( EMPTY_MODEL );
|
||||
private JComboBox<MapIcon> mMapIconCombo;
|
||||
private JComboBox<String> mListCombo = new JComboBox<>(EMPTY_MODEL);
|
||||
private JComboBox<String> mGroupCombo = new JComboBox<>(EMPTY_MODEL);
|
||||
private JComboBox<Icon> mIconCombo;
|
||||
private JTextField mName;
|
||||
private JButton mButtonColor;
|
||||
private JButton mBtnIconManager;
|
||||
|
||||
|
||||
private AliasModel mAliasModel;
|
||||
private SettingsManager mSettingsManager;
|
||||
|
||||
public AliasNameEditor( AliasModel aliasModel, SettingsManager settingsManager )
|
||||
{
|
||||
mAliasModel = aliasModel;
|
||||
mSettingsManager = settingsManager;
|
||||
init();
|
||||
}
|
||||
|
||||
private void init()
|
||||
{
|
||||
setLayout( new MigLayout( "fill,wrap 2", "[right][grow,fill]",
|
||||
"[][][][][][][grow]" ) );
|
||||
private IconManager mIconManager;
|
||||
|
||||
add( new JLabel( "Name:" ) );
|
||||
mName = new JTextField();
|
||||
mName.getDocument().addDocumentListener( new DocumentListener()
|
||||
{
|
||||
@Override
|
||||
public void removeUpdate( DocumentEvent e )
|
||||
{
|
||||
setModified( true );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertUpdate( DocumentEvent e )
|
||||
{
|
||||
setModified( true );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changedUpdate( DocumentEvent e ){}
|
||||
} );
|
||||
add( mName, "wrap" );
|
||||
public AliasNameEditor(AliasModel aliasModel, IconManager iconManager)
|
||||
{
|
||||
mAliasModel = aliasModel;
|
||||
mIconManager = iconManager;
|
||||
|
||||
add( new JLabel( "List:" ) );
|
||||
mListCombo.setEditable( true );
|
||||
mListCombo.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
if( mListCombo.getSelectedItem() != null )
|
||||
{
|
||||
List<String> groups = mAliasModel
|
||||
.getGroupNames( (String)mListCombo.getSelectedItem() );
|
||||
|
||||
if( groups.isEmpty() )
|
||||
{
|
||||
mGroupCombo.setModel( EMPTY_MODEL );
|
||||
}
|
||||
else
|
||||
{
|
||||
mGroupCombo.setModel( new DefaultComboBoxModel<String>(
|
||||
groups.toArray( new String[ groups.size() ] ) ) );;
|
||||
}
|
||||
}
|
||||
|
||||
setModified( true );
|
||||
}
|
||||
} );
|
||||
add( mListCombo, "wrap" );
|
||||
init();
|
||||
}
|
||||
|
||||
add( new JLabel( "Group:" ) );
|
||||
mGroupCombo.setEditable( true );
|
||||
mGroupCombo.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
setModified( true );
|
||||
}
|
||||
} );
|
||||
add( mGroupCombo, "wrap" );
|
||||
private void init()
|
||||
{
|
||||
setLayout(new MigLayout("fill,wrap 2", "[right][grow,fill]",
|
||||
"[][][][][][][grow]"));
|
||||
|
||||
add( new JLabel( "Color:" ) );
|
||||
|
||||
mButtonColor = new JButton( "Select ..." );
|
||||
mButtonColor.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
add(new JLabel("Name:"));
|
||||
mName = new JTextField();
|
||||
mName.getDocument().addDocumentListener(new DocumentListener()
|
||||
{
|
||||
@Override
|
||||
public void removeUpdate(DocumentEvent e)
|
||||
{
|
||||
Color newColor = JColorChooser.showDialog(
|
||||
AliasNameEditor.this,
|
||||
"Choose color for this alias",
|
||||
( hasItem() ? getItem().getMapColor() : null ) );
|
||||
|
||||
if( newColor != null )
|
||||
{
|
||||
mButtonColor.setForeground( newColor );
|
||||
mButtonColor.setBackground( newColor );
|
||||
|
||||
setModified( true );
|
||||
}
|
||||
setModified(true);
|
||||
}
|
||||
} );
|
||||
add( mButtonColor, "wrap" );
|
||||
|
||||
add( new JLabel( "Icon:" ) );
|
||||
|
||||
mMapIconCombo = new JComboBox<MapIcon>( mSettingsManager.getMapIcons() );
|
||||
|
||||
MapIconListCellRenderer renderer = new MapIconListCellRenderer();
|
||||
renderer.setPreferredSize( new Dimension( 200, 30 ) );
|
||||
mMapIconCombo.setRenderer( renderer );
|
||||
mMapIconCombo.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
setModified( true );
|
||||
}
|
||||
} );
|
||||
|
||||
add( mMapIconCombo, "wrap" );
|
||||
|
||||
//Dummy place holder
|
||||
add( new JLabel() );
|
||||
|
||||
mBtnIconManager = new JButton( "Icon Manager" );
|
||||
mBtnIconManager.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent arg0 )
|
||||
@Override
|
||||
public void insertUpdate(DocumentEvent e)
|
||||
{
|
||||
final IconManager iconManager =
|
||||
new IconManager( mSettingsManager, AliasNameEditor.this );
|
||||
|
||||
EventQueue.invokeLater( new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
iconManager.setVisible( true );
|
||||
}
|
||||
} );
|
||||
setModified(true);
|
||||
}
|
||||
} );
|
||||
|
||||
add( mBtnIconManager, "span 2,wrap" );
|
||||
|
||||
setModified( false );
|
||||
}
|
||||
@Override
|
||||
public void changedUpdate(DocumentEvent e)
|
||||
{
|
||||
}
|
||||
});
|
||||
add(mName, "wrap");
|
||||
|
||||
@Override
|
||||
public void setItem( Alias alias )
|
||||
{
|
||||
super.setItem( alias );
|
||||
|
||||
if( hasItem() )
|
||||
{
|
||||
mName.setText( alias.getName() );
|
||||
|
||||
List<String> listNames = mAliasModel.getListNames();
|
||||
|
||||
if( listNames.isEmpty() )
|
||||
{
|
||||
mListCombo.setModel( EMPTY_MODEL );
|
||||
}
|
||||
else
|
||||
{
|
||||
mListCombo.setModel( new DefaultComboBoxModel<String>(
|
||||
listNames.toArray( new String[ listNames.size() ] ) ) );;
|
||||
}
|
||||
|
||||
mListCombo.setSelectedItem( alias.getList() );
|
||||
|
||||
List<String> groupNames = mAliasModel.getGroupNames( alias.getList() );
|
||||
|
||||
if( groupNames.isEmpty() )
|
||||
{
|
||||
mGroupCombo.setModel( EMPTY_MODEL );
|
||||
}
|
||||
else
|
||||
{
|
||||
mGroupCombo.setModel( new DefaultComboBoxModel<String>(
|
||||
groupNames.toArray( new String[ groupNames.size() ] ) ) );;
|
||||
}
|
||||
|
||||
mGroupCombo.setSelectedItem( alias.getGroup() );
|
||||
|
||||
Color color = alias.getMapColor();
|
||||
|
||||
mButtonColor.setBackground( color );
|
||||
mButtonColor.setForeground( color );
|
||||
|
||||
String iconName = alias.getIconName();
|
||||
|
||||
if( iconName == null )
|
||||
{
|
||||
iconName = SettingsManager.DEFAULT_ICON;
|
||||
}
|
||||
|
||||
MapIcon savedIcon = mSettingsManager.getMapIcon( iconName );
|
||||
|
||||
if( savedIcon != null )
|
||||
{
|
||||
mMapIconCombo.setSelectedItem( savedIcon );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mListCombo.setModel( EMPTY_MODEL );
|
||||
mGroupCombo.setModel( EMPTY_MODEL );
|
||||
mName.setText( null );
|
||||
|
||||
mButtonColor.setBackground( getBackground() );
|
||||
mButtonColor.setForeground( getForeground() );
|
||||
}
|
||||
|
||||
repaint();
|
||||
|
||||
setModified( false );
|
||||
}
|
||||
add(new JLabel("List:"));
|
||||
mListCombo.setEditable(true);
|
||||
mListCombo.addActionListener(new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
if(mListCombo.getSelectedItem() != null)
|
||||
{
|
||||
List<String> groups = mAliasModel
|
||||
.getGroupNames((String) mListCombo.getSelectedItem());
|
||||
|
||||
@Override
|
||||
public void save()
|
||||
{
|
||||
if( hasItem() && isModified() )
|
||||
{
|
||||
Alias alias = getItem();
|
||||
|
||||
if( mListCombo.getSelectedItem() != null )
|
||||
{
|
||||
alias.setList( (String)mListCombo.getSelectedItem() );
|
||||
}
|
||||
|
||||
if( mGroupCombo.getSelectedItem() != null )
|
||||
{
|
||||
alias.setGroup( (String)mGroupCombo.getSelectedItem() );
|
||||
}
|
||||
if(groups.isEmpty())
|
||||
{
|
||||
mGroupCombo.setModel(EMPTY_MODEL);
|
||||
}
|
||||
else
|
||||
{
|
||||
mGroupCombo.setModel(new DefaultComboBoxModel<String>(
|
||||
groups.toArray(new String[groups.size()])));
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
alias.setName( mName.getText() );
|
||||
setModified(true);
|
||||
}
|
||||
});
|
||||
add(mListCombo, "wrap");
|
||||
|
||||
alias.setColor( mButtonColor.getBackground().getRGB() );
|
||||
add(new JLabel("Group:"));
|
||||
mGroupCombo.setEditable(true);
|
||||
mGroupCombo.addActionListener(new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
setModified(true);
|
||||
}
|
||||
});
|
||||
add(mGroupCombo, "wrap");
|
||||
|
||||
if( mMapIconCombo.getSelectedItem() != null )
|
||||
{
|
||||
alias.setIconName( ((MapIcon)mMapIconCombo.getSelectedItem()).getName() );
|
||||
}
|
||||
|
||||
setModified( false );
|
||||
add(new JLabel("Color:"));
|
||||
|
||||
//Broadcast an alias change event to save the updates
|
||||
mAliasModel.broadcast( new AliasEvent( getItem(), Event.CHANGE ) );
|
||||
}
|
||||
}
|
||||
mButtonColor = new JButton("Select ...");
|
||||
mButtonColor.addActionListener(new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
Color newColor = JColorChooser.showDialog(
|
||||
AliasNameEditor.this,
|
||||
"Choose color for this alias",
|
||||
(hasItem() ? getItem().getMapColor() : null));
|
||||
|
||||
if(newColor != null)
|
||||
{
|
||||
mButtonColor.setForeground(newColor);
|
||||
mButtonColor.setBackground(newColor);
|
||||
|
||||
setModified(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
add(mButtonColor, "wrap");
|
||||
|
||||
add(new JLabel("Icon:"));
|
||||
|
||||
mIconCombo = new JComboBox<Icon>(mIconManager.getIcons());
|
||||
|
||||
IconCellRenderer renderer = new IconCellRenderer(mIconManager);
|
||||
renderer.setPreferredSize(new Dimension(200, 30));
|
||||
mIconCombo.setRenderer( renderer );
|
||||
mIconCombo.addActionListener(new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
setModified(true);
|
||||
}
|
||||
});
|
||||
|
||||
add(mIconCombo, "wrap");
|
||||
|
||||
//Dummy place holder
|
||||
add(new JLabel());
|
||||
|
||||
mBtnIconManager = new JButton("Icon Manager");
|
||||
mBtnIconManager.addActionListener(new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent arg0)
|
||||
{
|
||||
mIconManager.showEditor(AliasNameEditor.this);
|
||||
}
|
||||
});
|
||||
|
||||
add(mBtnIconManager, "span 2,wrap");
|
||||
|
||||
setModified(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItem(Alias alias)
|
||||
{
|
||||
super.setItem(alias);
|
||||
|
||||
if(hasItem())
|
||||
{
|
||||
mName.setText(alias.getName());
|
||||
|
||||
List<String> listNames = mAliasModel.getListNames();
|
||||
|
||||
if(listNames.isEmpty())
|
||||
{
|
||||
mListCombo.setModel(EMPTY_MODEL);
|
||||
}
|
||||
else
|
||||
{
|
||||
mListCombo.setModel(new DefaultComboBoxModel<String>(
|
||||
listNames.toArray(new String[listNames.size()])));
|
||||
;
|
||||
}
|
||||
|
||||
mListCombo.setSelectedItem(alias.getList());
|
||||
|
||||
List<String> groupNames = mAliasModel.getGroupNames(alias.getList());
|
||||
|
||||
if(groupNames.isEmpty())
|
||||
{
|
||||
mGroupCombo.setModel(EMPTY_MODEL);
|
||||
}
|
||||
else
|
||||
{
|
||||
mGroupCombo.setModel(new DefaultComboBoxModel<String>(
|
||||
groupNames.toArray(new String[groupNames.size()])));
|
||||
;
|
||||
}
|
||||
|
||||
mGroupCombo.setSelectedItem(alias.getGroup());
|
||||
|
||||
Color color = alias.getMapColor();
|
||||
|
||||
mButtonColor.setBackground(color);
|
||||
mButtonColor.setForeground(color);
|
||||
|
||||
String iconName = alias.getIconName();
|
||||
|
||||
if(iconName == null)
|
||||
{
|
||||
iconName = SettingsManager.DEFAULT_ICON;
|
||||
}
|
||||
|
||||
Icon savedIcon = mIconManager.getModel().getIcon(iconName);
|
||||
|
||||
if(savedIcon != null)
|
||||
{
|
||||
mIconCombo.setSelectedItem(savedIcon);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mListCombo.setModel(EMPTY_MODEL);
|
||||
mGroupCombo.setModel(EMPTY_MODEL);
|
||||
mName.setText(null);
|
||||
|
||||
mButtonColor.setBackground(getBackground());
|
||||
mButtonColor.setForeground(getForeground());
|
||||
}
|
||||
|
||||
repaint();
|
||||
|
||||
setModified(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save()
|
||||
{
|
||||
if(hasItem() && isModified())
|
||||
{
|
||||
Alias alias = getItem();
|
||||
|
||||
if(mListCombo.getSelectedItem() != null)
|
||||
{
|
||||
alias.setList((String) mListCombo.getSelectedItem());
|
||||
}
|
||||
|
||||
if(mGroupCombo.getSelectedItem() != null)
|
||||
{
|
||||
alias.setGroup((String) mGroupCombo.getSelectedItem());
|
||||
}
|
||||
|
||||
alias.setName(mName.getText());
|
||||
|
||||
alias.setColor(mButtonColor.getBackground().getRGB());
|
||||
|
||||
if(mIconCombo.getSelectedItem() != null)
|
||||
{
|
||||
alias.setIconName(((MapIcon) mIconCombo.getSelectedItem()).getName());
|
||||
}
|
||||
|
||||
setModified(false);
|
||||
|
||||
//Broadcast an alias change event to save the updates
|
||||
mAliasModel.broadcast(new AliasEvent(getItem(), Event.CHANGE));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,14 +3,13 @@ package alias;
|
||||
import alias.id.AliasIDType;
|
||||
import alias.id.broadcast.BroadcastChannel;
|
||||
import audio.broadcast.BroadcastModel;
|
||||
import com.sun.org.apache.xpath.internal.operations.Mult;
|
||||
import gui.editor.Editor;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.DefaultComboBoxModel;
|
||||
@@ -24,16 +23,16 @@ import javax.swing.JSlider;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
|
||||
import map.IconManager;
|
||||
import icon.Icon;
|
||||
import icon.IconManager;
|
||||
import map.MapIcon;
|
||||
import map.MapIconListCellRenderer;
|
||||
import icon.IconCellRenderer;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import sample.Listener;
|
||||
import settings.SettingsManager;
|
||||
import alias.AliasEvent.Event;
|
||||
import alias.id.priority.Priority;
|
||||
|
||||
@@ -54,7 +53,7 @@ public class MultipleAliasEditor extends Editor<List<Alias>>
|
||||
private JCheckBox mGroupCheckBox = new JCheckBox("Group");
|
||||
private JComboBox<String> mGroupCombo = new JComboBox<>();
|
||||
private JCheckBox mIconCheckBox = new JCheckBox("Icon");
|
||||
private JComboBox<MapIcon> mMapIconCombo;
|
||||
private JComboBox<Icon> mIconCombo;
|
||||
private JCheckBox mColorCheckBox = new JCheckBox("Color");
|
||||
private JButton mButtonColor;
|
||||
private JButton mBtnIconManager;
|
||||
@@ -68,13 +67,13 @@ public class MultipleAliasEditor extends Editor<List<Alias>>
|
||||
|
||||
private AliasModel mAliasModel;
|
||||
private BroadcastModel mBroadcastModel;
|
||||
private SettingsManager mSettingsManager;
|
||||
private IconManager mIconManager;
|
||||
|
||||
public MultipleAliasEditor(AliasModel aliasModel, BroadcastModel broadcastModel, SettingsManager settingsManager)
|
||||
public MultipleAliasEditor(AliasModel aliasModel, BroadcastModel broadcastModel, IconManager iconManager)
|
||||
{
|
||||
mAliasModel = aliasModel;
|
||||
mBroadcastModel = broadcastModel;
|
||||
mSettingsManager = settingsManager;
|
||||
mIconManager = iconManager;
|
||||
|
||||
mAliasModel.addListener(this);
|
||||
|
||||
@@ -139,12 +138,12 @@ public class MultipleAliasEditor extends Editor<List<Alias>>
|
||||
|
||||
add(mIconCheckBox);
|
||||
|
||||
mMapIconCombo = new JComboBox<MapIcon>(mSettingsManager.getMapIcons());
|
||||
mIconCombo = new JComboBox<Icon>(mIconManager.getIcons());
|
||||
|
||||
MapIconListCellRenderer renderer = new MapIconListCellRenderer();
|
||||
IconCellRenderer renderer = new IconCellRenderer(mIconManager);
|
||||
renderer.setPreferredSize(new Dimension(200, 30));
|
||||
mMapIconCombo.setRenderer(renderer);
|
||||
add(mMapIconCombo, "wrap");
|
||||
mIconCombo.setRenderer(renderer);
|
||||
add(mIconCombo, "wrap");
|
||||
|
||||
//Dummy place holder
|
||||
add(new JLabel());
|
||||
@@ -155,17 +154,7 @@ public class MultipleAliasEditor extends Editor<List<Alias>>
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent arg0)
|
||||
{
|
||||
final IconManager iconManager =
|
||||
new IconManager(mSettingsManager, MultipleAliasEditor.this);
|
||||
|
||||
EventQueue.invokeLater(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
iconManager.setVisible(true);
|
||||
}
|
||||
});
|
||||
mIconManager.showEditor(MultipleAliasEditor.this);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -363,9 +352,9 @@ public class MultipleAliasEditor extends Editor<List<Alias>>
|
||||
|
||||
if (mIconCheckBox.isSelected())
|
||||
{
|
||||
if (mMapIconCombo.getSelectedItem() != null)
|
||||
if (mIconCombo.getSelectedItem() != null)
|
||||
{
|
||||
alias.setIconName(((MapIcon) mMapIconCombo.getSelectedItem()).getName());
|
||||
alias.setIconName(((MapIcon) mIconCombo.getSelectedItem()).getName());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -29,6 +29,7 @@ import javax.swing.event.ChangeListener;
|
||||
|
||||
import audio.broadcast.BroadcastModel;
|
||||
import audio.broadcast.BroadcastPanel;
|
||||
import icon.IconManager;
|
||||
import map.MapPanel;
|
||||
import map.MapService;
|
||||
import module.decode.event.CallEventPanel;
|
||||
@@ -78,6 +79,7 @@ public class ControllerPanel extends JPanel
|
||||
ChannelModel channelModel,
|
||||
ChannelMapModel channelMapModel,
|
||||
ChannelProcessingManager channelProcessingManager,
|
||||
IconManager iconManager,
|
||||
MapService mapService,
|
||||
SettingsManager settingsManager,
|
||||
SourceManager sourceManager,
|
||||
@@ -104,8 +106,7 @@ public class ControllerPanel extends JPanel
|
||||
mChannelController = new ChannelController(channelModel, channelMapModel,
|
||||
sourceManager, aliasModel);
|
||||
|
||||
mAliasController = new AliasController(aliasModel, broadcastModel, settingsManager);
|
||||
|
||||
mAliasController = new AliasController(aliasModel, broadcastModel, iconManager);
|
||||
mTunerManagerPanel = new TunerViewPanel(tunerModel);
|
||||
|
||||
init();
|
||||
|
||||
@@ -30,7 +30,7 @@ import controller.channel.ChannelModel;
|
||||
import controller.channel.ChannelProcessingManager;
|
||||
import controller.channel.ChannelSelectionManager;
|
||||
import controller.channel.map.ChannelMapModel;
|
||||
import map.IconManager;
|
||||
import icon.IconManager;
|
||||
import map.MapService;
|
||||
import module.log.EventLogManager;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
@@ -66,6 +66,7 @@ public class SDRTrunk implements Listener<TunerEvent>
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger(SDRTrunk.class);
|
||||
|
||||
private IconManager mIconManager;
|
||||
private ControllerPanel mControllerPanel;
|
||||
private SettingsManager mSettingsManager;
|
||||
private SpectralDisplayPanel mSpectralPanel;
|
||||
@@ -105,6 +106,8 @@ public class SDRTrunk implements Listener<TunerEvent>
|
||||
|
||||
ThreadPoolManager threadPoolManager = new ThreadPoolManager();
|
||||
|
||||
mIconManager = new IconManager(threadPoolManager);
|
||||
|
||||
mSettingsManager = new SettingsManager(threadPoolManager, tunerConfigurationModel);
|
||||
|
||||
AliasModel aliasModel = new AliasModel();
|
||||
@@ -144,7 +147,7 @@ public class SDRTrunk implements Listener<TunerEvent>
|
||||
channelProcessingManager.addMessageListener(mapService);
|
||||
|
||||
mControllerPanel = new ControllerPanel(audioManager, aliasModel, broadcastModel,
|
||||
channelModel, channelMapModel, channelProcessingManager,
|
||||
channelModel, channelMapModel, channelProcessingManager, mIconManager,
|
||||
mapService, mSettingsManager, sourceManager, tunerModel);
|
||||
|
||||
mSpectralPanel = new SpectralDisplayPanel(channelModel,
|
||||
@@ -268,16 +271,7 @@ public class SDRTrunk implements Listener<TunerEvent>
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent arg0)
|
||||
{
|
||||
final IconManager iconManager = new IconManager(mSettingsManager, mMainGui);
|
||||
|
||||
EventQueue.invokeLater(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
iconManager.setVisible(true);
|
||||
}
|
||||
});
|
||||
mIconManager.showEditor(mMainGui);
|
||||
}
|
||||
});
|
||||
fileMenu.add(settingsMenu);
|
||||
|
||||
99
src/icon/Icon.java
Normal file
99
src/icon/Icon.java
Normal 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 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());
|
||||
}
|
||||
}
|
||||
64
src/icon/IconCellRenderer.java
Normal file
64
src/icon/IconCellRenderer.java
Normal file
@@ -0,0 +1,64 @@
|
||||
/*******************************************************************************
|
||||
* 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.awt.*;
|
||||
|
||||
public class IconCellRenderer extends JLabel implements ListCellRenderer<Icon>
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private IconManager mIconManager;
|
||||
|
||||
public IconCellRenderer(IconManager iconManager)
|
||||
{
|
||||
mIconManager = iconManager;
|
||||
setOpaque(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getListCellRendererComponent(JList<? extends Icon> list, Icon icon, int index,
|
||||
boolean isSelected, boolean cellHasFocus)
|
||||
{
|
||||
setIcon(mIconManager.getIcon(icon.getName(), 24));
|
||||
|
||||
if(icon == mIconManager.getModel().getDefaultIcon())
|
||||
{
|
||||
setText(icon.toString() + " (default)");
|
||||
}
|
||||
else
|
||||
{
|
||||
setText(icon.toString());
|
||||
}
|
||||
|
||||
if(isSelected)
|
||||
{
|
||||
setBackground(list.getSelectionBackground());
|
||||
setForeground(list.getSelectionForeground());
|
||||
}
|
||||
else
|
||||
{
|
||||
setBackground(list.getBackground());
|
||||
setForeground(list.getForeground());
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
432
src/icon/IconManager.java
Normal file
432
src/icon/IconManager.java
Normal file
@@ -0,0 +1,432 @@
|
||||
/*******************************************************************************
|
||||
* 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 controller.ThreadPoolManager;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import properties.SystemProperties;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ListDataEvent;
|
||||
import javax.swing.event.ListDataListener;
|
||||
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);
|
||||
|
||||
private Path mIconFolderPath;
|
||||
private Path mIconFilePath;
|
||||
private Path mIconBackupFilePath;
|
||||
private Path mIconLockFilePath;
|
||||
|
||||
private ThreadPoolManager mThreadPoolManager;
|
||||
private IconViewer mIconViewer;
|
||||
private IconModel mIconModel;
|
||||
private AtomicBoolean mSavingIcons = new AtomicBoolean();
|
||||
|
||||
private Map<String, ImageIcon> mResizedIcons = new HashMap<>();
|
||||
|
||||
public IconManager(ThreadPoolManager threadPoolManager)
|
||||
{
|
||||
mThreadPoolManager = threadPoolManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the icon editor centered over the specified component.
|
||||
*
|
||||
* @param centerOnComponent to center the editor
|
||||
*/
|
||||
public void showEditor(Component centerOnComponent)
|
||||
{
|
||||
if(mIconViewer == null)
|
||||
{
|
||||
mIconViewer = new IconViewer(this);
|
||||
mIconViewer.setLocationRelativeTo(centerOnComponent);
|
||||
|
||||
if(mIconViewer.isVisible())
|
||||
{
|
||||
mIconViewer.requestFocus();
|
||||
}
|
||||
else
|
||||
{
|
||||
EventQueue.invokeLater(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
mIconViewer.setVisible(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IconModel getModel()
|
||||
{
|
||||
if(mIconModel == null)
|
||||
{
|
||||
IconSet loadedIcons = load();
|
||||
|
||||
mIconModel = new IconModel(loadedIcons);
|
||||
mIconModel.addListDataListener(new ListDataListener()
|
||||
{
|
||||
@Override
|
||||
public void intervalAdded(ListDataEvent e)
|
||||
{
|
||||
scheduleSave();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void intervalRemoved(ListDataEvent e)
|
||||
{
|
||||
scheduleSave();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contentsChanged(ListDataEvent e)
|
||||
{
|
||||
scheduleSave();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return mIconModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* All icons in a sorted array
|
||||
*/
|
||||
public 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);
|
||||
}
|
||||
|
||||
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
|
||||
*/
|
||||
private 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() + "]");
|
||||
}
|
||||
|
||||
if(iconSet == null)
|
||||
{
|
||||
iconSet = getDefaultIconSet();
|
||||
}
|
||||
|
||||
return iconSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a default icon set
|
||||
*/
|
||||
private IconSet getDefaultIconSet()
|
||||
{
|
||||
IconSet iconSet = new IconSet();
|
||||
|
||||
Icon defaultIcon = new Icon(IconModel.DEFAULT_ICON, "images/no_icon.png");
|
||||
iconSet.add(defaultIcon);
|
||||
iconSet.setDefaultIcon(defaultIcon.getName());
|
||||
|
||||
iconSet.add(new Icon("Ambulance", "images/ambulance.png"));
|
||||
iconSet.add(new Icon("Block Truck", "images/concrete_block_truck.png"));
|
||||
iconSet.add(new Icon("CWID", "images/cwid.png"));
|
||||
iconSet.add(new Icon("Dispatcher", "images/dispatcher.png"));
|
||||
iconSet.add(new Icon("Dump Truck", "images/dump_truck_red.png"));
|
||||
iconSet.add(new Icon("Fire Truck", "images/fire_truck.png"));
|
||||
iconSet.add(new Icon("Garbage Truck", "images/garbage_truck.png"));
|
||||
iconSet.add(new Icon("Loader", "images/loader.png"));
|
||||
iconSet.add(new Icon("Police", "images/police.png"));
|
||||
iconSet.add(new Icon("Propane Truck", "images/propane_truck.png"));
|
||||
iconSet.add(new Icon("Rescue Truck", "images/rescue_truck.png"));
|
||||
iconSet.add(new Icon("School Bus", "images/school_bus.png"));
|
||||
iconSet.add(new Icon("Taxi", "images/taxi.png"));
|
||||
iconSet.add(new Icon("Train", "images/train.png"));
|
||||
iconSet.add(new Icon("Transport Bus", "images/opt_bus.png"));
|
||||
iconSet.add(new 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))
|
||||
{
|
||||
mThreadPoolManager.scheduleOnce(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);
|
||||
}
|
||||
}
|
||||
}
|
||||
150
src/icon/IconModel.java
Normal file
150
src/icon/IconModel.java
Normal file
@@ -0,0 +1,150 @@
|
||||
/*******************************************************************************
|
||||
* 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.Collection;
|
||||
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;
|
||||
}
|
||||
}
|
||||
175
src/icon/IconSelector.java
Normal file
175
src/icon/IconSelector.java
Normal file
@@ -0,0 +1,175 @@
|
||||
/*******************************************************************************
|
||||
* 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 net.miginfocom.swing.MigLayout;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
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 IconModel mIconModel;
|
||||
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 iconModel to receive the added/selected icon
|
||||
*/
|
||||
public IconSelector(Frame owner, IconModel iconModel)
|
||||
{
|
||||
super(owner, "Add Icon", true);
|
||||
|
||||
mIconModel = iconModel;
|
||||
|
||||
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();
|
||||
|
||||
Icon icon = new Icon(name, path);
|
||||
mIconModel.addElement(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() && !mIconModel.hasIcon(name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertUpdate(DocumentEvent e)
|
||||
{
|
||||
checkButtons();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeUpdate(DocumentEvent e)
|
||||
{
|
||||
checkButtons();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changedUpdate(DocumentEvent e)
|
||||
{
|
||||
checkButtons();
|
||||
}
|
||||
}
|
||||
|
||||
76
src/icon/IconSet.java
Normal file
76
src/icon/IconSet.java
Normal file
@@ -0,0 +1,76 @@
|
||||
/*******************************************************************************
|
||||
* 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.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlElementWrapper;
|
||||
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);
|
||||
}
|
||||
|
||||
@XmlElementWrapper(name="icons")
|
||||
@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;
|
||||
}
|
||||
}
|
||||
137
src/icon/IconViewer.java
Normal file
137
src/icon/IconViewer.java
Normal file
@@ -0,0 +1,137 @@
|
||||
/*******************************************************************************
|
||||
* 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 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.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
public class IconViewer extends JFrame implements ActionListener
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Logger mLog = LoggerFactory.getLogger(IconViewer.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 JList<Icon> mIconList;
|
||||
private IconManager mIconManager;
|
||||
|
||||
public IconViewer(IconManager model)
|
||||
{
|
||||
mIconManager = model;
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
private void init()
|
||||
{
|
||||
setTitle("Icon Viewer");
|
||||
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][]"));
|
||||
|
||||
mIconList = new JList<>(mIconManager.getModel());
|
||||
IconCellRenderer renderer = new IconCellRenderer(mIconManager);
|
||||
renderer.setPreferredSize(new Dimension(200, 30));
|
||||
mIconList.setCellRenderer(renderer);
|
||||
mIconList.addListSelectionListener(new ListSelectionListener()
|
||||
{
|
||||
@Override
|
||||
public void valueChanged(ListSelectionEvent e)
|
||||
{
|
||||
checkButtons();
|
||||
}
|
||||
});
|
||||
editorPanel.add(new JScrollPane(mIconList), "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()
|
||||
{
|
||||
Icon selected = mIconList.getSelectedValue();
|
||||
|
||||
mDefaultButton.setEnabled(selected != null && selected != mIconManager.getModel().getDefaultIcon());
|
||||
mDeleteButton.setEnabled(selected != null && selected != mIconManager.getModel().getDefaultIcon());
|
||||
}
|
||||
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
Icon selected = mIconList.getSelectedValue();
|
||||
|
||||
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(IconViewer.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);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DEFAULT:
|
||||
if(selected != null)
|
||||
{
|
||||
mIconManager.getModel().setDefaultIcon(selected);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
checkButtons();
|
||||
}
|
||||
}
|
||||
74
src/icon/ImageFilter.java
Normal file
74
src/icon/ImageFilter.java
Normal 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 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;
|
||||
}
|
||||
}
|
||||
@@ -1,495 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 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 map;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JSplitPane;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
import javax.swing.filechooser.FileFilter;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import settings.Setting;
|
||||
import settings.SettingChangeListener;
|
||||
import settings.SettingsManager;
|
||||
|
||||
public class IconManager extends JFrame
|
||||
implements ActionListener, SettingChangeListener
|
||||
|
||||
{
|
||||
public enum Mode { NORMAL, NEW, EDIT }
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final static Logger mLog =
|
||||
LoggerFactory.getLogger( IconManager.class );
|
||||
|
||||
private static final String sMSG_NEW = "Type a name for the new icon, "
|
||||
+ "select the file, and click Save,\nor Cancel to reset";
|
||||
private static final String sMSG_EDIT = "Change the name for the selected \n"
|
||||
+ "icon and/or the file, and click Save\nto update, or Cancel to reset";
|
||||
private static final String sMSG_NORMAL = "Select an icon to edit, or \n"
|
||||
+ "click New to add an icon";
|
||||
|
||||
private JTextField mIconName;
|
||||
private JTextField mIconPath;
|
||||
private JButton mButtonLeft = new JButton( "New" );
|
||||
private JButton mButtonRight = new JButton( "Edit" );
|
||||
private JButton mButtonFile = new JButton( "File" );
|
||||
private JTextArea mInstructionLabel = new JTextArea();
|
||||
private JList<MapIcon> mIconList;
|
||||
private JFileChooser mFileChooser;
|
||||
private Mode mMode = Mode.NORMAL;
|
||||
|
||||
private SettingsManager mSettingsManager;
|
||||
|
||||
public IconManager( SettingsManager settingsManager, Component displayOver )
|
||||
{
|
||||
mSettingsManager = settingsManager;
|
||||
|
||||
init( displayOver );
|
||||
}
|
||||
|
||||
private void init( Component displayOver )
|
||||
{
|
||||
setTitle( "Icon Manager" );
|
||||
setLocationRelativeTo( displayOver );
|
||||
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( "", "", "[][][][grow,fill]" ) );
|
||||
|
||||
mButtonFile.addActionListener( this );
|
||||
editorPanel.add( mButtonFile, "align right" );
|
||||
|
||||
mIconPath = new JTextField();
|
||||
editorPanel.add( mIconPath, "grow,wrap" );
|
||||
|
||||
editorPanel.add( new JLabel( "Name:" ), "align right" );
|
||||
|
||||
mIconName = new JTextField();
|
||||
editorPanel.add( mIconName, "grow,wrap" );
|
||||
|
||||
mButtonLeft.addActionListener( this );
|
||||
editorPanel.add( mButtonLeft );
|
||||
|
||||
mButtonRight.addActionListener( this );
|
||||
mButtonRight.setEnabled( false );
|
||||
editorPanel.add( mButtonRight, "wrap" );
|
||||
|
||||
mInstructionLabel.setText( sMSG_NORMAL );
|
||||
mInstructionLabel.setRows( 3 );
|
||||
mInstructionLabel.setBackground( getBackground() );
|
||||
editorPanel.add( mInstructionLabel, "span,grow,wrap" );
|
||||
|
||||
/**
|
||||
* MapIcon list
|
||||
*/
|
||||
MapIcon[] icons = mSettingsManager.getMapIcons();
|
||||
Arrays.sort( icons );
|
||||
|
||||
mIconList = new JList<MapIcon>( icons );
|
||||
|
||||
MapIconListCellRenderer renderer = new MapIconListCellRenderer();
|
||||
renderer.setPreferredSize( new Dimension( 200, 30 ) );
|
||||
mIconList.setCellRenderer( renderer );
|
||||
|
||||
mIconList.addListSelectionListener( new ListSelectionListener()
|
||||
{
|
||||
@Override
|
||||
public void valueChanged( ListSelectionEvent event )
|
||||
{
|
||||
/**
|
||||
* Refresh the display by setting the mode to normal. If we
|
||||
* were in editing or new mode, and the user clicks in the list
|
||||
* throw away the changes and set the mode to normal
|
||||
*/
|
||||
setMode( Mode.NORMAL );
|
||||
}
|
||||
} );
|
||||
|
||||
mIconList.addMouseListener( new MouseListener()
|
||||
{
|
||||
@Override
|
||||
public void mouseClicked( MouseEvent event )
|
||||
{
|
||||
if( event.getButton() == MouseEvent.BUTTON3 )
|
||||
{
|
||||
//Select the item
|
||||
mIconList.setSelectedIndex(
|
||||
mIconList.locationToIndex( event.getPoint() ) );
|
||||
|
||||
//Determine if it can be deleted
|
||||
final MapIcon icon = mIconList.getSelectedValue();
|
||||
|
||||
if( icon != null )
|
||||
{
|
||||
JPopupMenu context = new JPopupMenu();
|
||||
|
||||
JMenuItem setDefault = new JMenuItem( "Set As Default" );
|
||||
|
||||
setDefault.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
mSettingsManager.setDefaultIcon( icon );
|
||||
|
||||
refreshList();
|
||||
}
|
||||
} );
|
||||
|
||||
context.add( setDefault );
|
||||
|
||||
if( icon.isEditable() )
|
||||
{
|
||||
JMenuItem deleteItem = new JMenuItem( "Delete Icon" );
|
||||
deleteItem.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent arg0 )
|
||||
{
|
||||
mSettingsManager.deleteMapIcon( icon );
|
||||
}
|
||||
} );
|
||||
|
||||
context.add( deleteItem );
|
||||
}
|
||||
|
||||
context.show( mIconList, event.getX(), event.getY() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Unused
|
||||
public void mouseEntered( MouseEvent arg0 ) {}
|
||||
public void mouseExited( MouseEvent arg0 ) {}
|
||||
public void mousePressed( MouseEvent arg0 ) {}
|
||||
public void mouseReleased( MouseEvent arg0 ) {}
|
||||
} );
|
||||
|
||||
JScrollPane scroller = new JScrollPane( mIconList );
|
||||
|
||||
/**
|
||||
* Splitpane to hold editor and icon list
|
||||
*/
|
||||
JSplitPane splitPane = new JSplitPane( JSplitPane.VERTICAL_SPLIT,
|
||||
scroller,
|
||||
editorPanel );
|
||||
splitPane.setResizeWeight( 0.7D );
|
||||
|
||||
add( splitPane );
|
||||
}
|
||||
|
||||
private void setMode( Mode mode )
|
||||
{
|
||||
MapIcon selected = mIconList.getSelectedValue();
|
||||
|
||||
switch( mode )
|
||||
{
|
||||
case NORMAL:
|
||||
setTitle( "Icon Manager" );
|
||||
mButtonLeft.setText( "New" );
|
||||
mButtonRight.setText( "Edit" );
|
||||
|
||||
if( selected != null )
|
||||
{
|
||||
if( selected.isEditable() )
|
||||
{
|
||||
mButtonRight.setEnabled( true );
|
||||
mIconName.setText( selected.getName() );
|
||||
mIconPath.setText( selected.getPath() );
|
||||
}
|
||||
else
|
||||
{
|
||||
mButtonRight.setEnabled( false );
|
||||
mIconName.setText( selected.getName() + " [NO EDIT]" );
|
||||
mIconPath.setText( null );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mButtonRight.setEnabled( false );
|
||||
mIconName.setText( null );
|
||||
mIconPath.setText( null );
|
||||
}
|
||||
mInstructionLabel.setText( sMSG_NORMAL );
|
||||
break;
|
||||
case EDIT:
|
||||
if( selected != null )
|
||||
{
|
||||
setTitle( "Icon Manager - editing [" + selected.getName() + "]" );
|
||||
}
|
||||
else
|
||||
{
|
||||
setTitle( "Icon Manager - edit [*]" );
|
||||
}
|
||||
mButtonLeft.setText( "Save" );
|
||||
mButtonRight.setText( "Cancel" );
|
||||
mButtonRight.setEnabled( true );
|
||||
mInstructionLabel.setText( sMSG_EDIT );
|
||||
break;
|
||||
case NEW:
|
||||
setTitle( "Icon Manager - add new icon" );
|
||||
mButtonLeft.setText( "Save" );
|
||||
mButtonRight.setText( "Cancel" );
|
||||
mButtonRight.setEnabled( true );
|
||||
mIconName.setText( null );
|
||||
mIconPath.setText( null );
|
||||
mInstructionLabel.setText( sMSG_NEW );
|
||||
break;
|
||||
}
|
||||
|
||||
mMode = mode;
|
||||
|
||||
repaint();
|
||||
}
|
||||
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
if( e.getSource() == mButtonFile )
|
||||
{
|
||||
if ( mFileChooser == null )
|
||||
{
|
||||
mFileChooser = new JFileChooser();
|
||||
|
||||
//Add a custom file filter and disable the default
|
||||
mFileChooser.addChoosableFileFilter( new ImageFilter() );
|
||||
mFileChooser.setAcceptAllFileFilterUsed( false );
|
||||
}
|
||||
|
||||
int returnVal = mFileChooser.showDialog( this, "Select" );
|
||||
|
||||
if ( returnVal == JFileChooser.APPROVE_OPTION )
|
||||
{
|
||||
File file = mFileChooser.getSelectedFile();
|
||||
|
||||
if( file != null )
|
||||
{
|
||||
mIconPath.setText( file.getAbsolutePath() );
|
||||
}
|
||||
}
|
||||
|
||||
//Reset the file chooser for the next time it's shown.
|
||||
mFileChooser.setSelectedFile( null );
|
||||
}
|
||||
else if( e.getSource() == mButtonLeft )
|
||||
{
|
||||
switch( mMode )
|
||||
{
|
||||
case EDIT: //Save
|
||||
save();
|
||||
break;
|
||||
case NEW: //Save
|
||||
save();
|
||||
break;
|
||||
case NORMAL:
|
||||
setMode( Mode.NEW );
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if( e.getSource() == mButtonRight )
|
||||
{
|
||||
switch( mMode )
|
||||
{
|
||||
case EDIT: //Cancel
|
||||
case NEW: //Cancel
|
||||
setMode( Mode.NORMAL );
|
||||
break;
|
||||
case NORMAL: //Edit
|
||||
setMode( Mode.EDIT );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void refreshList()
|
||||
{
|
||||
MapIcon[] icons = mSettingsManager.getMapIcons();
|
||||
|
||||
Arrays.sort( icons );
|
||||
|
||||
mIconList.setListData( icons );
|
||||
|
||||
repaint();
|
||||
}
|
||||
|
||||
private void save()
|
||||
{
|
||||
String name = mIconName.getText();
|
||||
String path = mIconPath.getText();
|
||||
|
||||
switch( mMode )
|
||||
{
|
||||
case NEW:
|
||||
if( name != null && !name.isEmpty() )
|
||||
{
|
||||
if( path != null && !path.isEmpty() )
|
||||
{
|
||||
mSettingsManager.addMapIcon( new MapIcon( name, path, true ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
JOptionPane.showMessageDialog( this,
|
||||
"Please select an image file",
|
||||
"Filename and path missing",
|
||||
JOptionPane.ERROR_MESSAGE );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
JOptionPane.showMessageDialog( this,
|
||||
"Please type a name for the new icon",
|
||||
"Name missing",
|
||||
JOptionPane.ERROR_MESSAGE );
|
||||
}
|
||||
break;
|
||||
|
||||
case EDIT:
|
||||
MapIcon selected = mIconList.getSelectedValue();
|
||||
|
||||
if( name != null && !name.isEmpty() )
|
||||
{
|
||||
if( path != null && !path.isEmpty() )
|
||||
{
|
||||
selected.setName( name );
|
||||
selected.setPath( path );
|
||||
mSettingsManager.updatMapIcon( selected, name, path );
|
||||
}
|
||||
else
|
||||
{
|
||||
JOptionPane.showMessageDialog( this,
|
||||
"Please select an image file",
|
||||
"Filename and path missing",
|
||||
JOptionPane.ERROR_MESSAGE );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
JOptionPane.showMessageDialog( this,
|
||||
"Please type a name for the new icon",
|
||||
"Name missing",
|
||||
JOptionPane.ERROR_MESSAGE );
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void settingChanged( Setting setting )
|
||||
{
|
||||
if( setting instanceof MapIcon )
|
||||
{
|
||||
refreshList();
|
||||
setMode( Mode.NORMAL );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void settingDeleted( Setting setting )
|
||||
{
|
||||
if( setting instanceof MapIcon )
|
||||
{
|
||||
refreshList();
|
||||
setMode( Mode.NORMAL );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 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 map;
|
||||
|
||||
import java.awt.Component;
|
||||
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.ListCellRenderer;
|
||||
|
||||
public class MapIconListCellRenderer extends JLabel
|
||||
implements ListCellRenderer<MapIcon>
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public MapIconListCellRenderer()
|
||||
{
|
||||
setOpaque( true );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getListCellRendererComponent(
|
||||
JList<? extends MapIcon> list, MapIcon value, int index,
|
||||
boolean isSelected, boolean cellHasFocus )
|
||||
{
|
||||
setIcon( value.getImageIcon() );
|
||||
setText( value.toString() );
|
||||
|
||||
if ( isSelected )
|
||||
{
|
||||
setBackground( list.getSelectionBackground() );
|
||||
setForeground( list.getSelectionForeground() );
|
||||
}
|
||||
else
|
||||
{
|
||||
setBackground( list.getBackground() );
|
||||
setForeground( list.getForeground() );
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -432,9 +432,9 @@ public class PlaylistManager implements ChannelEventListener
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
mPlaylistSavePending.set(false);
|
||||
|
||||
save();
|
||||
|
||||
mPlaylistSavePending.set(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user