Search code examples
javaswingpositiondocumentjtextcomponent

Tracking document position changes


I am using the Document method createPosition to add Positions to an array. These Positions change depending on the user inserting/removing lines.

How do I hook changes in my array? I need to know the new value and the value which it has changed from.


Solution

  • Interface Position has no method to add listener to monitor position change. So you need do it manually using wrapper for Position object.

    public class PositionHolder {
      private int oldPosition;
      private Position position;
      private PropertyChangeSupport propertySupport = new PropertyChangeSupport(this);
      public PositionHolder(Position aPos) {
        position = aPos;
        oldPosition = aPos.getOffset();
      }
      public void addPropertyChangeListener(PropertyChangeListener aListener) {
        propertySupport.addPropertyChangeListener(aListener);
      }
      // same for remove listener
      public void verifyPosition() {
        // no custom if statement required - event is fiered only when old != new
        propertySupport.firePropertyChangeEvent("position", oldPosition, position.getOffset());
        oldPosition = position.getOffset();
      }
      public Position getPosition() {
        return position;
      }
    }
    
    public class PositionUpdater implements DocumentListener {
      private List<PositionHolder> holders;
      public PositionUpdater(List<PositionHolder> someHolders) {
        holders = someHolders;
      }
    
      public void insertUpdate(DocumentEvent e) {
        for (PositionHolder h : holders) {
          h.verifyPosition();
        }
      }
      public void removeUpdate(DocumentEvent e) {
        insertUpdate(e);
      }
      public void changeUpdate(DocumentEvent e) {
        insertUpdate(e);
      }
    }
    
    JTextComponent textComp = // your text component
    List<PositionHolder> holderList = new ArrayList<>(); // your list of positions
    textComp.getDocument().addDocumentListener(new PositionUpdater(holderList));
    

    Now you will get notification when position is changed. You only need to fill the holderList with wrappers for your positions and register your event listener on these wrappers.