package com.bytezone.diskbrowser.gui; import java.awt.event.ActionEvent; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; import java.net.URL; import java.util.ArrayList; import java.util.EventListener; import java.util.EventObject; import java.util.List; import javax.swing.*; import javax.swing.event.EventListenerList; // -----------------------------------------------------------------------------------// class RedoHandler implements FileSelectionListener, DiskSelectionListener, SectorSelectionListener, FileNodeSelectionListener // -----------------------------------------------------------------------------------// { private static final String base = "/com/bytezone/diskbrowser/icons/"; EventListenerList listenerList = new EventListenerList (); Action leftAction = new LeftAction (); Action rightAction = new RightAction (); RedoData redoData = new RedoData (leftAction, rightAction); static int id = 0; // ---------------------------------------------------------------------------------// public RedoHandler (JRootPane jRootPane, JToolBar toolBar) // ---------------------------------------------------------------------------------// { // This code works as long as the toolBar arrows have focus first InputMap inputMap = jRootPane.getInputMap (JComponent.WHEN_IN_FOCUSED_WINDOW); ActionMap actionMap = jRootPane.getActionMap (); inputMap.put (KeyStroke.getKeyStroke (KeyEvent.VK_LEFT, InputEvent.ALT_DOWN_MASK), "LeftAction"); actionMap.put ("LeftAction", leftAction); inputMap.put (KeyStroke.getKeyStroke (KeyEvent.VK_RIGHT, InputEvent.ALT_DOWN_MASK), "RightAction"); actionMap.put ("RightAction", rightAction); toolBar.add (leftAction); toolBar.add (rightAction); } // ---------------------------------------------------------------------------------// public RedoData createData () // ---------------------------------------------------------------------------------// { RedoData data = new RedoData (leftAction, rightAction); this.redoData = data; // doesn't fire an event this way return data; } // ---------------------------------------------------------------------------------// public void setCurrentData (RedoData data) // ---------------------------------------------------------------------------------// { this.redoData = data; RedoEvent event = redoData.getCurrentEvent (); if (event != null) fireRedoEvent (event); } // ---------------------------------------------------------------------------------// private void fireRedoEvent (RedoEvent event) // ---------------------------------------------------------------------------------// { RedoListener[] listeners = (listenerList.getListeners (RedoListener.class)); for (RedoListener listener : listeners) listener.redo (event); } // ---------------------------------------------------------------------------------// public void addRedoListener (RedoListener listener) // ---------------------------------------------------------------------------------// { listenerList.add (RedoListener.class, listener); } // ---------------------------------------------------------------------------------// public void removeRedoListener (RedoListener listener) // ---------------------------------------------------------------------------------// { listenerList.remove (RedoListener.class, listener); } // ---------------------------------------------------------------------------------// @Override public void diskSelected (DiskSelectedEvent event) // ---------------------------------------------------------------------------------// { if (!event.redo) // it's an event we just caused addEvent (new RedoEvent ("DiskEvent", event)); } // ---------------------------------------------------------------------------------// @Override public void fileNodeSelected (FileNodeSelectedEvent event) // ---------------------------------------------------------------------------------// { if (!event.redo) // it's an event we just caused addEvent (new RedoEvent ("FileNodeEvent", event)); } // ---------------------------------------------------------------------------------// @Override public void fileSelected (FileSelectedEvent event) // ---------------------------------------------------------------------------------// { if (!event.redo) // it's an event we just caused addEvent (new RedoEvent ("FileEvent", event)); } // ---------------------------------------------------------------------------------// @Override public void sectorSelected (SectorSelectedEvent event) // ---------------------------------------------------------------------------------// { if (!event.redo) // it's an event we just caused addEvent (new RedoEvent ("SectorEvent", event)); } // ---------------------------------------------------------------------------------// private void addEvent (RedoEvent event) // ---------------------------------------------------------------------------------// { redoData.addEvent (event); } // ---------------------------------------------------------------------------------// public class RedoEvent extends EventObject // ---------------------------------------------------------------------------------// { String type; EventObject value; // -------------------------------------------------------------------------------// public RedoEvent (String type, EventObject value) // -------------------------------------------------------------------------------// { super (RedoHandler.this); this.type = type; this.value = value; } // -------------------------------------------------------------------------------// @Override public String toString () // -------------------------------------------------------------------------------// { return ("[type=" + type + ", value=" + value + "]"); } } // ---------------------------------------------------------------------------------// public interface RedoListener extends EventListener // ---------------------------------------------------------------------------------// { void redo (RedoEvent event); } // ---------------------------------------------------------------------------------// class LeftAction extends AbstractAction // ---------------------------------------------------------------------------------// { // -------------------------------------------------------------------------------// public LeftAction () // -------------------------------------------------------------------------------// { super ("Back"); putValue (Action.SHORT_DESCRIPTION, "Undo selection"); URL url = getClass ().getResource (base + "Symbol-Left-32.png"); if (url != null) putValue (Action.LARGE_ICON_KEY, new ImageIcon (url)); } // -------------------------------------------------------------------------------// @Override public void actionPerformed (ActionEvent e) // -------------------------------------------------------------------------------// { fireRedoEvent (redoData.getPreviousEvent ()); } } // ---------------------------------------------------------------------------------// class RightAction extends AbstractAction // ---------------------------------------------------------------------------------// { // -------------------------------------------------------------------------------// public RightAction () // -------------------------------------------------------------------------------// { super ("Forward"); putValue (Action.SHORT_DESCRIPTION, "Redo selection"); URL url = getClass ().getResource (base + "Symbol-Right-32.png"); if (url != null) putValue (Action.LARGE_ICON_KEY, new ImageIcon (url)); } // -------------------------------------------------------------------------------// @Override public void actionPerformed (ActionEvent e) // -------------------------------------------------------------------------------// { fireRedoEvent (redoData.getNextEvent ()); } } // ---------------------------------------------------------------------------------// class RedoData // ---------------------------------------------------------------------------------// { List events = new ArrayList<> (); int currentEvent = -1; Action leftAction; Action rightAction; final int seq = id++; // -------------------------------------------------------------------------------// public RedoData (Action left, Action right) // -------------------------------------------------------------------------------// { leftAction = left; rightAction = right; setArrows (); } // -------------------------------------------------------------------------------// RedoEvent getCurrentEvent () // -------------------------------------------------------------------------------// { if (currentEvent < 0) return null; setArrows (); return events.get (currentEvent); } // -------------------------------------------------------------------------------// RedoEvent getNextEvent () // -------------------------------------------------------------------------------// { RedoEvent event = events.get (++currentEvent); setArrows (); return event; } // -------------------------------------------------------------------------------// RedoEvent getPreviousEvent () // -------------------------------------------------------------------------------// { RedoEvent event = events.get (--currentEvent); setArrows (); return event; } // -------------------------------------------------------------------------------// void addEvent (RedoEvent event) // -------------------------------------------------------------------------------// { while (currentEvent < events.size () - 1) events.remove (events.size () - 1); ++currentEvent; events.add (event); setArrows (); } // -------------------------------------------------------------------------------// private void setArrows () // -------------------------------------------------------------------------------// { rightAction.setEnabled (currentEvent < events.size () - 1); leftAction.setEnabled (currentEvent > 0); } // -------------------------------------------------------------------------------// @Override public String toString () // -------------------------------------------------------------------------------// { StringBuilder text = new StringBuilder (); text.append ("Current event (" + seq + ") : " + currentEvent + "\n"); for (RedoEvent event : events) text.append (" - " + event + "\n"); return text.toString (); } } }