From e8fd4f363a7ffce8c94886bb02db3c4d6f9579a1 Mon Sep 17 00:00:00 2001 From: denny Date: Sat, 5 Mar 2016 04:30:21 -0500 Subject: [PATCH] wip: alias multi-select editor feature --- src/alias/AliasController.java | 102 +++++++-- src/alias/AliasEditor.java | 8 +- src/alias/AliasModel.java | 22 +- src/alias/AliasNameEditor.java | 4 +- src/alias/MultipleAliasEditor.java | 329 +++++++++++++++++++++++++++++ src/gui/editor/Editor.java | 1 + 6 files changed, 439 insertions(+), 27 deletions(-) create mode 100644 src/alias/MultipleAliasEditor.java diff --git a/src/alias/AliasController.java b/src/alias/AliasController.java index 77fa19c9..cf47664e 100644 --- a/src/alias/AliasController.java +++ b/src/alias/AliasController.java @@ -1,10 +1,15 @@ package alias; +import gui.editor.Editor; + import java.awt.Color; import java.awt.Component; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import javax.swing.ImageIcon; import javax.swing.JButton; @@ -38,7 +43,9 @@ public class AliasController extends JPanel private AliasModel mAliasModel; private JTable mAliasTable; private TableFilterHeader mTableFilterHeader; - private AliasEditor mEditor; + private AliasEditor mAliasEditor; + private MultipleAliasEditor mMultipleAliasEditor; + private JideSplitPane mSplitPane; private static final String NEW_ALIAS = "New"; private static final String COPY_ALIAS = "Copy"; @@ -54,13 +61,14 @@ public class AliasController extends JPanel { mAliasModel = aliasModel; - mEditor = new AliasEditor( mAliasModel, settingsManager ); + mAliasEditor = new AliasEditor( mAliasModel, settingsManager ); + mMultipleAliasEditor = new MultipleAliasEditor( mAliasModel, settingsManager ); mIconCellRenderer = new IconCellRenderer( settingsManager ); init(); - mAliasModel.addListener( mEditor ); + mAliasModel.addListener( mAliasEditor ); } private void init() @@ -71,7 +79,7 @@ public class AliasController extends JPanel //System Configuration View and Editor mAliasTable = new JTable( mAliasModel ); - mAliasTable.setSelectionMode( ListSelectionModel.SINGLE_SELECTION ); + mAliasTable.setSelectionMode( ListSelectionModel.MULTIPLE_INTERVAL_SELECTION ); mAliasTable.getSelectionModel().addListSelectionListener( this ); mAliasTable.setAutoCreateRowSorter( true ); @@ -113,13 +121,52 @@ public class AliasController extends JPanel listAndButtonsPanel.add( tableScroller, "wrap" ); listAndButtonsPanel.add( buttonsPanel ); - JideSplitPane splitPane = new JideSplitPane( JideSplitPane.HORIZONTAL_SPLIT ); - splitPane.setDividerSize( 5 ); - splitPane.setShowGripper( true ); - splitPane.add( listAndButtonsPanel ); - splitPane.add( mEditor ); + mSplitPane = new JideSplitPane( JideSplitPane.HORIZONTAL_SPLIT ); + mSplitPane.setDividerSize( 5 ); + mSplitPane.setShowGripper( true ); + mSplitPane.add( listAndButtonsPanel ); + mSplitPane.add( mAliasEditor ); - add( splitPane ); + add( mSplitPane ); + } + + /** + * 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 ); + mSplitPane.add( editor ); + + mSplitPane.validate(); + mSplitPane.setDividerLocation( 0, location ); + mSplitPane.repaint(); + } + } + } + + private Alias getAlias( int selectedRow ) + { + if( selectedRow >= 0 ) + { + int index = mAliasTable.convertRowIndexToModel( mAliasTable.getSelectedRow() ); + + return mAliasModel.getAliasAtIndex( index ); + } + + return null; } @Override @@ -128,26 +175,43 @@ public class AliasController extends JPanel //Limits event firing to only when selection is complete if( !event.getValueIsAdjusting() ) { - int selectedRow = mAliasTable.getSelectedRow(); + int[] selectedRows = mAliasTable.getSelectedRows(); - if( selectedRow != -1 ) + if( selectedRows.length <= 1 ) { - int index = mAliasTable.convertRowIndexToModel( mAliasTable.getSelectedRow() ); + setEditor( mAliasEditor ); - Alias alias = mAliasModel.getAliasAtIndex( index ); + Alias selectedAlias = getAlias( selectedRows[ 0 ] ); - if( alias != null ) + mAliasEditor.setItem( selectedAlias ); + + if( selectedAlias != null ) { - mEditor.setItem( alias ); mCopyButton.setEnabled( true ); mDeleteButton.setEnabled( true ); } + else + { + mCopyButton.setEnabled( false ); + mDeleteButton.setEnabled( false ); + } } else { - mEditor.setItem( null ); - mCopyButton.setEnabled( false ); - mDeleteButton.setEnabled( false ); + setEditor( mMultipleAliasEditor ); + + mCopyButton.setEnabled( true ); + mDeleteButton.setEnabled( true ); + + List selectedAliases = new ArrayList(); + + for( int selectedRow: selectedRows ) + { + selectedAliases.add( getAlias( selectedRow ) ); + } + + mLog.debug( "Selection changed - setting selected aliases" ); + mMultipleAliasEditor.setItem( selectedAliases ); } } } diff --git a/src/alias/AliasEditor.java b/src/alias/AliasEditor.java index 75c176e4..66d8ce5b 100644 --- a/src/alias/AliasEditor.java +++ b/src/alias/AliasEditor.java @@ -34,13 +34,13 @@ import org.slf4j.LoggerFactory; import sample.Listener; import settings.SettingsManager; -import alias.AliasEvent.Event; import alias.action.AliasActionEditor; import alias.id.AliasIdentifierEditor; import com.jidesoft.swing.JideTabbedPane; -public class AliasEditor extends Editor implements ActionListener, Listener +public class AliasEditor extends Editor + implements ActionListener, Listener { private static final long serialVersionUID = 1L; @@ -64,7 +64,7 @@ public class AliasEditor extends Editor implements ActionListener, Listen mAliasModel.addListener( this ); - initGUI(); + init(); } @@ -87,7 +87,7 @@ public class AliasEditor extends Editor implements ActionListener, Listen mAliasActionEditor.setItem( alias ); } - private void initGUI() + private void init() { setLayout( new MigLayout( "fill,wrap 2", "[grow,fill][grow,fill]", "[][][][][][grow,fill]" ) ); diff --git a/src/alias/AliasModel.java b/src/alias/AliasModel.java index f248ded6..d9b3dbfa 100644 --- a/src/alias/AliasModel.java +++ b/src/alias/AliasModel.java @@ -22,8 +22,6 @@ import java.util.Collections; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; -import javax.swing.event.TableModelEvent; -import javax.swing.event.TableModelListener; import javax.swing.table.AbstractTableModel; import org.slf4j.Logger; @@ -93,6 +91,26 @@ public class AliasModel extends AbstractTableModel return listNames; } + /** + * Returns a list of alias group names for all aliases + */ + public List getGroupNames() + { + List groupNames = new ArrayList<>(); + + for( Alias alias: mAliases ) + { + if( alias.hasGroup() && !groupNames.contains( alias.getGroup() ) ) + { + groupNames.add( alias.getGroup() ); + } + } + + Collections.sort( groupNames ); + + return groupNames; + } + /** * Returns a list of alias group names for all aliases that have a matching * list name value diff --git a/src/alias/AliasNameEditor.java b/src/alias/AliasNameEditor.java index 3a99e098..10124091 100644 --- a/src/alias/AliasNameEditor.java +++ b/src/alias/AliasNameEditor.java @@ -284,10 +284,10 @@ public class AliasNameEditor extends Editor alias.setIconName( ((MapIcon)mMapIconCombo.getSelectedItem()).getName() ); } + setModified( false ); + //Broadcast an alias change event to save the updates mAliasModel.broadcast( new AliasEvent( getItem(), Event.CHANGE ) ); } - - setModified( false ); } } diff --git a/src/alias/MultipleAliasEditor.java b/src/alias/MultipleAliasEditor.java new file mode 100644 index 00000000..94a367ae --- /dev/null +++ b/src/alias/MultipleAliasEditor.java @@ -0,0 +1,329 @@ +package alias; + +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.ComboBoxModel; +import javax.swing.DefaultComboBoxModel; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JColorChooser; +import javax.swing.JComboBox; +import javax.swing.JLabel; +import javax.swing.JSeparator; +import javax.swing.JTextField; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import alias.AliasEvent.Event; +import map.IconManager; +import map.MapIcon; +import map.MapIconListCellRenderer; +import net.miginfocom.swing.MigLayout; +import sample.Listener; +import settings.SettingsManager; + +public class MultipleAliasEditor extends Editor> + implements Listener +{ + private static final long serialVersionUID = 1L; + private final static Logger mLog = LoggerFactory.getLogger( MultipleAliasEditor.class ); + + private static String HELP_TEXT = + "Select attributes below to change for all selected aliases"; + + private JLabel mAliasCountLabel; + private JLabel mAliasCount; + + private JCheckBox mListCheckBox = new JCheckBox( "List" ); + private JComboBox mListCombo = new JComboBox<>(); + private JCheckBox mGroupCheckBox = new JCheckBox( "Group" ); + private JComboBox mGroupCombo = new JComboBox<>(); + private JCheckBox mIconCheckBox = new JCheckBox( "Icon" ); + private JComboBox mMapIconCombo; + private JCheckBox mColorCheckBox = new JCheckBox( "Color" ); + private JButton mButtonColor; + private JButton mBtnIconManager; + + private AliasModel mAliasModel; + private SettingsManager mSettingsManager; + + public MultipleAliasEditor( AliasModel aliasModel, SettingsManager settingsManager ) + { + mAliasModel = aliasModel; + mAliasModel.addListener( this ); + + mSettingsManager = settingsManager; + + init(); + } + + public List getAliases() + { + if( hasItem() ) + { + return (List)getItem(); + } + + return null; + } + + public void init() + { + setLayout( new MigLayout( "fill,wrap 2", "[grow,fill][grow,fill]", + "[][][][][][][][][][grow,fill]" ) ); + + mAliasCountLabel = new JLabel( "Alias:" ); + add( mAliasCountLabel ); + + mAliasCount = new JLabel( "Multiple" ); + add( mAliasCount, "span" ); + + add( new JSeparator(), "span" ); + + add( new JLabel( HELP_TEXT ), "span" ); + + add( mListCheckBox ); + + mListCombo.setEditable( true ); + mListCombo.addActionListener( new ActionListener() + { + @Override + public void actionPerformed( ActionEvent e ) + { + setModified( true ); + } + } ); + add( mListCombo, "wrap" ); + + add( mGroupCheckBox ); + + mGroupCombo.setEditable( true ); + mGroupCombo.addActionListener( new ActionListener() + { + @Override + public void actionPerformed( ActionEvent e ) + { + setModified( true ); + } + } ); + add( mGroupCombo, "wrap" ); + + add( mColorCheckBox ); + + mButtonColor = new JButton( "Select ..." ); + mButtonColor.addActionListener( new ActionListener() + { + @Override + public void actionPerformed( ActionEvent e ) + { + Color newColor = JColorChooser.showDialog( + MultipleAliasEditor.this, + "Choose color for this alias", null ); + + if( newColor != null ) + { + mButtonColor.setForeground( newColor ); + mButtonColor.setBackground( newColor ); + + setModified( true ); + } + } + } ); + add( mButtonColor, "wrap" ); + + add( mIconCheckBox ); + + mMapIconCombo = new JComboBox( 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 ) + { + final IconManager iconManager = + new IconManager( mSettingsManager, MultipleAliasEditor.this ); + + EventQueue.invokeLater( new Runnable() + { + @Override + public void run() + { + iconManager.setVisible( true ); + } + } ); + } + } ); + + add( mBtnIconManager, "span,wrap" ); + + JButton saveButton = new JButton( "Save" ); + saveButton.addActionListener( new ActionListener() + { + @Override + public void actionPerformed( ActionEvent e ) + { + save(); + } + } ); + add( saveButton ); + + JButton resetButton = new JButton( "Reset" ); + resetButton.addActionListener( new ActionListener() + { + @Override + public void actionPerformed( ActionEvent e ) + { + setModified( false ); + setItem( getAliases() ); + } + } ); + add( resetButton ); + + setModified( false ); + } + + @Override + public void setItem( List item ) + { + mLog.debug( "setItem invoked" ); + super.setItem( item ); + + StringBuilder sb = new StringBuilder(); + sb.append( "Multiple [" ); + + if( hasItem() ) + { + sb.append( String.valueOf( getAliases().size() ) ); + + List listNames = mAliasModel.getListNames(); + listNames.add( 0, "" ); + mListCombo.setModel( new DefaultComboBoxModel( + listNames.toArray( new String[ listNames.size() ] ) ) ); + + List groupNames = mAliasModel.getGroupNames(); + groupNames.add( 0, "" ); + mGroupCombo.setModel( new DefaultComboBoxModel( + groupNames.toArray( new String[ groupNames.size() ] ) ) ); + } + else + { + sb.append( "0" ); + } + + sb.append( "]" ); + + mAliasCount.setText( sb.toString() ); + + setModified( false ); + } + + @Override + public void save() + { + if( isModified() && hasItem() ) + { + setModified( false ); + + List aliases = getAliases(); + + for( Alias alias: aliases ) + { + if( mListCheckBox.isSelected() ) + { + String list = null; + + if( mListCombo.getSelectedItem() != null ) + { + list = (String)mListCombo.getSelectedItem(); + } + + alias.setList( list ); + } + + if( mGroupCheckBox.isSelected() ) + { + String group = null; + + if( mGroupCombo.getSelectedItem() != null ) + { + group = (String)mGroupCombo.getSelectedItem(); + } + + mLog.debug( "Group is:" + group ); + alias.setGroup( group ); + } + + if( mColorCheckBox.isSelected() ) + { + alias.setColor( mButtonColor.getForeground().getRGB() ); + } + + if( mIconCheckBox.isSelected() ) + { + if( mMapIconCombo.getSelectedItem() != null ) + { + alias.setIconName( ((MapIcon)mMapIconCombo.getSelectedItem()).getName() ); + } + else + { + alias.setIconName( null ); + } + } + } + + if( mListCheckBox.isSelected() || + mGroupCheckBox.isSelected() || + mColorCheckBox.isSelected() || + mIconCheckBox.isSelected() ) + { + mLog.debug( "Broadcasting change event" ); + + for( Alias alias: aliases ) + { + mLog.debug( "Group:" + alias.getGroup() ); + //Broadcast an alias change event to save the updates + mAliasModel.broadcast( new AliasEvent( alias, Event.CHANGE ) ); + } + } + } + } + + @Override + public void receive( AliasEvent event ) + { + if( event.getEvent() == Event.DELETE && + hasItem() && + getAliases().contains( event.getAlias() ) ) + { + getAliases().remove( event.getAlias() ); + setItem( getAliases() ); + } + } +} diff --git a/src/gui/editor/Editor.java b/src/gui/editor/Editor.java index 258cc3bc..061080c0 100644 --- a/src/gui/editor/Editor.java +++ b/src/gui/editor/Editor.java @@ -31,6 +31,7 @@ public abstract class Editor extends JPanel { if( isModified() ) { + mLog.debug( "Editor that is modified: " + getClass() ); int option = JOptionPane.showConfirmDialog( Editor.this, "This item has changed. Do you want to save these changes?",