# Class ChatView

java.lang.Object
com.codename1.ui.Component
com.codename1.ui.Container
com.codename1.components.ChatView

All Implemented Interfaces:
  `Animation, Editable, StyleListener, Iterable<Component>`

public class ChatView extends Container

A scrollable, theme-aware chat surface.

`ChatView` is a pure UI component -- it has no knowledge of LLMs or any specific chat backend. It accepts `ChatMessage` instances (the same data envelope the AI client uses, but equally usable for peer-to-peer messaging) and renders them as styled bubbles. Routing the user's input to a backend and piping responses back into the view is the caller's job. For LLM use there's a ready-made binding -- see `com.codename1.ai.LlmChatBinding` -- but the same surface trivially supports a WhatsApp-style peer chat:

    ChatView view = new ChatView();
    view.setOnSend(evt -> {
        String text = view.getInput().getText();
        view.getInput().clear();
        view.addMessage(ChatMessage.user(text));          // outgoing
        chatService.send(text, peerReply -> {
            // peer responses render as "assistant" bubbles
            view.addMessage(ChatMessage.assistant(peerReply));
        });
    });
    // System / "X joined the chat" notices use ChatMessage.system.

The `USER` / `ASSISTANT` / `SYSTEM` roles map naturally to self / peer / system-notice in a peer chat; rename via CSS (the bubble UIIDs are `ChatBubbleUser`, `ChatBubbleAssistant`, `ChatBubbleSystem`) if the visual treatment needs to differ. Apps that need a totally different message data type can subclass and override `createBubble(ChatMessage)` to render however they like while still using `ChatMessage` as the transport.

##### Default UIIDs

`ChatView`, `ChatViewMessages`, `ChatBubbleUser`, `ChatBubbleAssistant`, `ChatBubbleSystem`, `ChatBubbleText`, `ChatTypingIndicator`, `ChatInput`, `ChatInputField`, `ChatSendButton`, `ChatAttachButton`, `ChatVoiceButton`.

- ## Field Summary

  ### Fields inherited from class Component

  `BASELINE, BOTTOM, BRB_CENTER_OFFSET, BRB_CONSTANT_ASCENT, BRB_CONSTANT_DESCENT, BRB_OTHER, CENTER, CROSSHAIR_CURSOR, DEFAULT_CURSOR, DRAG_REGION_IMMEDIATELY_DRAG_X, DRAG_REGION_IMMEDIATELY_DRAG_XY, DRAG_REGION_IMMEDIATELY_DRAG_Y, DRAG_REGION_LIKELY_DRAG_X, DRAG_REGION_LIKELY_DRAG_XY, DRAG_REGION_LIKELY_DRAG_Y, DRAG_REGION_NOT_DRAGGABLE, DRAG_REGION_POSSIBLE_DRAG_X, DRAG_REGION_POSSIBLE_DRAG_XY, DRAG_REGION_POSSIBLE_DRAG_Y, E_RESIZE_CURSOR, HAND_CURSOR, LEFT, MOVE_CURSOR, N_RESIZE_CURSOR, NE_RESIZE_CURSOR, NW_RESIZE_CURSOR, RIGHT, S_RESIZE_CURSOR, SE_RESIZE_CURSOR, SW_RESIZE_CURSOR, TEXT_CURSOR, TOP, W_RESIZE_CURSOR, WAIT_CURSOR`

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `ChatView()`

- ## Method Summary

  Modifier and Type
  Method
  Description
  `ChatBubble`
  `addMessage(ChatMessage message)`
  Renders `message` as a new `ChatBubble` at the bottom of the list and scrolls into view.
  `void`
  `appendToLastMessage(String delta)`
  Append a streaming token delta to the most recently added bubble.
  `ChatBubble`
  `beginAssistantStream()`
  Appends an empty assistant/peer bubble that subsequent `ChatBubble.appendText(String)` calls (or `appendToLastMessage(String)`) can stream tokens into.
  `protected ChatBubble`
  `createBubble(ChatMessage message)`
  Override to swap in a custom bubble renderer (e.g. one that understands markdown, shows avatars, or formats peer messages differently from LLM responses).
  `List<ChatMessage>`
  `getHistory()`
  `ChatInput`
  `getInput()`
  `void`
  `setOnAttach(ActionListener listener)`
  `void`
  `setOnSend(ActionListener listener)`
  `void`
  `setOnVoice(ActionListener listener)`
  `void`
  `setTypingIndicatorVisible(boolean v)`

  ### Methods inherited from class Container

  `add, add, add, add, add, add, addAll, addComponent, addComponent, addComponent, addComponent, animateHierarchy, animateHierarchyAndWait, animateHierarchyFade, animateHierarchyFadeAndWait, animateLayout, animateLayoutAndWait, animateLayoutFade, animateLayoutFadeAndWait, animateUnlayout, animateUnlayoutAndWait, applyRTL, calcPreferredSize, cancelRepaints, clearClientProperties, constrainHeightWhenScrollable, constrainWidthWhenScrollable, contains, createAnimateHierarchy, createAnimateHierarchyFade, createAnimateLayout, createAnimateLayoutFade, createAnimateLayoutFadeAndWait, createAnimateMotion, createAnimateUnlayout, createReplaceTransition, dragInitiated, drop, encloseIn, encloseIn, findDropTargetAt, findFirstFocusable, fireClicked, flushReplace, forceRevalidate, getBottomGap, getChildrenAsList, getClosestComponentTo, getComponentAt, getComponentAt, getComponentCount, getComponentIndex, getGridPosX, getGridPosY, getLayout, getLayoutHeight, getLayoutWidth, getLeadComponent, getLeadParent, getResponderAt, getSafeAreaRoot, getScrollIncrement, getSideGap, getUIManager, initLaf, invalidate, isEnabled, isSafeArea, isSafeAreaRoot, isScrollableX, isScrollableY, isSelectableInteraction, isSurface, iterator, iterator, keyPressed, keyReleased, layoutContainer, morph, morphAndWait, paint, paintComponentBackground, paintGlass, paramString, pointerPressed, refreshTheme, removeAll, removeComponent, replace, replace, replaceAndWait, replaceAndWait, replaceAndWait, revalidate, revalidateLater, revalidateWithAnimationSafety, scrollComponentToVisible, setCellRenderer, setEnabled, setLayout, setLeadComponent, setSafeArea, setSafeAreaRoot, setScrollable, setScrollableX, setScrollableY, setScrollIncrement, setShouldCalcPreferredSize, setShouldLayout, setUIManager, updateTabIndices`

  ### Methods inherited from class Component

  `addDragFinishedListener, addDragOverListener, addDropListener, addFocusListener, addLongPressListener, addPointerDraggedListener, addPointerPressedListener, addPointerReleasedListener, addPullToRefresh, addScrollListener, addStateChangeListener, animate, announceForAccessibility, bindProperty, blocksSideSwipe, calcScrollSize, contains, containsOrOwns, createStyleAnimation, deinitialize, deinitializeCustomStyle, dragEnter, dragExit, dragFinished, draggingOver, drawDraggedImage, focusGained, focusLost, getAbsoluteX, getAbsoluteY, getAccessibilityText, getAllStyles, getAnimationManager, getBaseline, getBaselineResizeBehavior, getBindablePropertyNames, getBindablePropertyTypes, getBorder, getBoundPropertyValue, getBounds, getBounds, getClientProperty, getCloudBoundProperty, getCloudDestinationProperty, getComponentForm, getComponentState, getCursor, getDefaultDragTransparency, getDirtyRegion, getDisabledStyle, getDraggedx, getDraggedy, getDragImage, getDragRegionStatus, getDragSpeed, getDragTransparency, getEditingDelegate, getHeight, getInlineAllStyles, getInlineDisabledStyles, getInlinePressedStyles, getInlineSelectedStyles, getInlineStylesTheme, getInlineUnselectedStyles, getInnerHeight, getInnerPreferredH, getInnerPreferredW, getInnerWidth, getInnerX, getInnerY, getLabelForComponent, getName, getNativeOverlay, getNextFocusDown, getNextFocusLeft, getNextFocusRight, getNextFocusUp, getOuterHeight, getOuterPreferredH, getOuterPreferredW, getOuterWidth, getOuterX, getOuterY, getOwner, getParent, getPreferredH, getPreferredSize, getPreferredSizeStr, getPreferredTabIndex, getPreferredW, getPressedStyle, getPropertyNames, getPropertyTypeNames, getPropertyTypes, getPropertyValue, getSameHeight, getSameWidth, getScrollable, getScrollAnimationSpeed, getScrollDimension, getScrollOpacity, getScrollOpacityChangeSpeed, getScrollX, getScrollY, getSelectCommandText, getSelectedRect, getSelectedStyle, getStyle, getTabIndex, getTensileLength, getTextSelectionSupport, getTooltip, getUIID, getUnselectedStyle, getVisibleBounds, getVisibleBounds, getWidth, getX, getY, growShrink, handlesInput, hasFixedPreferredSize, hasFocus, hideNativeOverlay, initComponent, initCustomStyle, initDisabledStyle, initPressedStyle, initSelectedStyle, initUnselectedStyle, installDefaultPainter, isAlwaysTensile, isBlockLead, isCellRenderer, isChildOf, isDragActivated, isDragAndDropOperation, isDraggable, isDragRegion, isDropTarget, isEditable, isEditing, isFlatten, isFocusable, isGrabsPointerEvents, isHidden, isHidden, isHideInLandscape, isHideInPortrait, isIgnorePointerEvents, isInClippingRegion, isInitialized, isOpaque, isOwnedBy, isPinchBlocksDragAndDrop, isRippleEffect, isRTL, isScrollable, isScrollVisible, isSetCursorSupported, isSmoothScrolling, isSnapToGrid, isStickyDrag, isTactileTouch, isTactileTouch, isTensileDragEnabled, isTraversable, isVisible, keyRepeated, laidOut, longKeyPress, longPointerPress, onScrollX, onScrollY, onSetFocusable, paintBackground, paintBackgrounds, paintBorder, paintBorderBackground, paintComponent, paintComponent, paintIntersectingComponentsAbove, paintLock, paintLockRelease, paintRippleOverlay, paintScrollbars, paintScrollbarX, paintScrollbarY, paintShadows, parsePreferredSize, pinch, pinch, pinchReleased, pointerDragged, pointerDragged, pointerHover, pointerHoverPressed, pointerHoverReleased, pointerPressed, pointerReleased, pointerReleased, putClientProperty, refreshTheme, refreshTheme, remove, removeDragFinishedListener, removeDragOverListener, removeDropListener, removeFocusListener, removeLongPressListener, removePointerDraggedListener, removePointerPressedListener, removePointerReleasedListener, removeScrollListener, removeStateChangeListener, repaint, repaint, requestFocus, resetFocusable, respondsToPointerEvents, scrollRectToVisible, scrollRectToVisible, setAccessibilityText, setAlwaysTensile, setBlockLead, setBoundPropertyValue, setCloudBoundProperty, setCloudDestinationProperty, setComponentState, setCursor, setDefaultDragTransparency, setDirtyRegion, setDisabledStyle, setDraggable, setDragTransparency, setDropTarget, setEditingDelegate, setFlatten, setFocus, setFocusable, setGrabsPointerEvents, setHandlesInput, setHeight, setHidden, setHidden, setHideInLandscape, setHideInPortrait, setHorizontalScrollBounds, setIgnorePointerEvents, setInitialized, setInlineAllStyles, setInlineDisabledStyles, setInlinePressedStyles, setInlineSelectedStyles, setInlineStylesTheme, setInlineUnselectedStyles, setIsScrollVisible, setLabelForComponent, setName, setNextFocusDown, setNextFocusLeft, setNextFocusRight, setNextFocusUp, setOpaque, setOwner, setPinchBlocksDragAndDrop, setPreferredH, setPreferredSize, setPreferredSizeStr, setPreferredTabIndex, setPreferredW, setPressedStyle, setPropertyValue, setPullToRefresh, setRippleEffect, setRTL, setSameHeight, setSameSize, setSameWidth, setScrollAnimationSpeed, setScrollOpacityChangeSpeed, setScrollSize, setScrollVisible, setScrollX, setScrollY, setSelectCommandText, setSelectedStyle, setSize, setSmoothScrolling, setSnapToGrid, setTabIndex, setTactileTouch, setTensileDragEnabled, setTensileLength, setTooltip, setTraversable, setUIID, setUIID, setUIIDFinal, setUnselectedStyle, setVerticalScrollBounds, setVisible, setWidth, setX, setY, shouldBlockSideSwipe, shouldBlockSideSwipeLeft, shouldBlockSideSwipeRight, shouldRenderComponentSelection, showNativeOverlay, startEditingAsync, stopEditing, stripMarginAndPadding, styleChanged, toImage, toString, unbindProperty, updateNativeOverlay, visibleBoundsContains`

  ### Methods inherited from class Object

  `clone, equals, getClass, hashCode, notify, notifyAll, wait, wait, wait`

  ### Methods inherited from interface Iterable

  `forEach`

- ## Constructor Details

  - ### ChatView

    public ChatView()

- ## Method Details

  - ### addMessage

    public ChatBubble addMessage(ChatMessage message)

    Renders `message` as a new `ChatBubble` at the bottom of the list and scrolls into view. Safe to call from any thread.

    The bubble itself is laid out inside a single-row FlowLayout container whose alignment is driven by the message role: USER -> right, ASSISTANT -> left, SYSTEM -> centre. That keeps the bubble's visible width anchored to its text content rather than stretching across the full chat surface, which is what makes a chat bubble actually look like a bubble.

  - ### beginAssistantStream

    public ChatBubble beginAssistantStream()
    Appends an empty assistant/peer bubble that subsequent `ChatBubble.appendText(String)` calls (or `appendToLastMessage(String)`) can stream tokens into. Returns the bubble so the caller can retain the reference -- the typical pattern is to capture it before opening a streaming network call.

  - ### appendToLastMessage

    public void appendToLastMessage(String delta)
    Append a streaming token delta to the most recently added bubble. Safe to call off-EDT. No-op when there is no bubble yet.

  - ### setTypingIndicatorVisible

    public void setTypingIndicatorVisible(boolean v)

  - ### setOnSend

    public void setOnSend(ActionListener listener)

  - ### setOnAttach

    public void setOnAttach(ActionListener listener)

  - ### setOnVoice

    public void setOnVoice(ActionListener listener)

  - ### getInput

    public ChatInput getInput()

  - ### getHistory

    public List<ChatMessage> getHistory()

  - ### createBubble

    protected ChatBubble createBubble(ChatMessage message)
    Override to swap in a custom bubble renderer (e.g. one that understands markdown, shows avatars, or formats peer messages differently from LLM responses). Default delegates to `ChatBubble`.