private Interactable findNextUpOrDown(Interactable interactable, boolean isDown) {
        int directionTerm = isDown ? 1 : -1;
        TerminalPosition startPosition = interactable.getCursorLocation();
        if (startPosition == null) {
            // If the currently active interactable component is not showing the cursor, use the top-left position
            // instead if we're going up, or the bottom-left position if we're going down
            if(isDown) {
                startPosition = new TerminalPosition(0, interactable.getSize().getRows() - 1);
            }
            else {
                startPosition = TerminalPosition.TOP_LEFT_CORNER;
            }
        }
        else {
            //Adjust position so that it's at the bottom of the component if we're going down or at the top of the
            //component if we're going right. Otherwise the lookup might product odd results in certain cases.
            if(isDown) {
                startPosition = startPosition.withRow(interactable.getSize().getRows() - 1);
            }
            else {
                startPosition = startPosition.withRow(0);
            }
        }
        startPosition = interactable.toBasePane(startPosition);
        if(startPosition == null) {
            // The structure has changed, our interactable is no longer inside the base pane!
            return null;
        }
        Set<Interactable> disqualified = getDisqualifiedInteractables(startPosition, true);
        TerminalSize size = getSize();
        int maxShiftLeft = interactable.toBasePane(TerminalPosition.TOP_LEFT_CORNER).getColumn();
        maxShiftLeft = Math.max(maxShiftLeft, 0);
        int maxShiftRight = interactable.toBasePane(new TerminalPosition(interactable.getSize().getColumns() - 1, 0)).getColumn();
        maxShiftRight = Math.min(maxShiftRight, size.getColumns() - 1);
        int maxShift = Math.max(startPosition.getColumn() - maxShiftLeft, maxShiftRight - startPosition.getRow());
        for (int searchRow = startPosition.getRow() + directionTerm;
             searchRow >= 0 && searchRow < size.getRows();
             searchRow += directionTerm) {

            for (int xShift = 0; xShift <= maxShift; xShift++) {
                for (int modifier : new int[]{1, -1}) {
                    if (xShift == 0 && modifier == -1) {
                        break;
                    }
                    int searchColumn = startPosition.getColumn() + (xShift * modifier);
                    if (searchColumn < maxShiftLeft || searchColumn > maxShiftRight) {
                        continue;
                    }

                    int index = lookupMap[searchRow][searchColumn];
                    if (index != -1 && !disqualified.contains(interactables.get(index))) {
                        return interactables.get(index);
                    }
                }
            }
        }
        return null;
    }
private Interactable findNextUpOrDown ( Interactable interactable , boolean isDown ) { int directionTerm = isDown ? 1 : - 1 ; TerminalPosition startPosition = interactable . getCursorLocation ( ) ; if ( startPosition == null ) { if ( isDown ) { startPosition = new TerminalPosition ( 0 , interactable . getSize ( ) . getRows ( ) - 1 ) ; } else { startPosition = TerminalPosition . TOP_LEFT_CORNER ; } } else { if ( isDown ) { startPosition = startPosition . withRow ( interactable . getSize ( ) . getRows ( ) - 1 ) ; } else { startPosition = startPosition . withRow ( 0 ) ; } } startPosition = interactable . toBasePane ( startPosition ) ; if ( startPosition == null ) { return null ; } Set < Interactable > disqualified = getDisqualifiedInteractables ( startPosition , true ) ; TerminalSize size = getSize ( ) ; int maxShiftLeft = interactable . toBasePane ( TerminalPosition . TOP_LEFT_CORNER ) . getColumn ( ) ; maxShiftLeft = Math . max ( maxShiftLeft , 0 ) ; int maxShiftRight = interactable . toBasePane ( new TerminalPosition ( interactable . getSize ( ) . getColumns ( ) - 1 , 0 ) ) . getColumn ( ) ; maxShiftRight = Math . min ( maxShiftRight , size . getColumns ( ) - 1 ) ; int maxShift = Math . max ( startPosition . getColumn ( ) - maxShiftLeft , maxShiftRight - startPosition . getRow ( ) ) ; for ( int searchRow = startPosition . getRow ( ) + directionTerm ; searchRow >= 0 && searchRow < size . getRows ( ) ; searchRow += directionTerm ) { for ( int xShift = 0 ; xShift <= maxShift ; xShift ++ ) { for ( int modifier : new int [ ] { 1 , - 1 } ) { if ( xShift == 0 && modifier == - 1 ) { break ; } int searchColumn = startPosition . getColumn ( ) + ( xShift * modifier ) ; if ( searchColumn < maxShiftLeft || searchColumn > maxShiftRight ) { continue ; } int index = lookupMap [ searchRow ] [ searchColumn ] ; if ( index != - 1 && ! disqualified . contains ( interactables . get ( index ) ) ) { return interactables . get ( index ) ; } } } } return null ; }
Avoid code duplication in above two methods