package org.openautonomousconnection.webclient.ui; import org.openautonomousconnection.oacswing.component.OACButton; import org.openautonomousconnection.oacswing.component.OACPanel; import javax.swing.border.EmptyBorder; import java.awt.*; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.function.Consumer; /** * Favorites bar rendered as compact chips. */ public final class FavChipBar extends OACPanel { private final List favorites = new ArrayList<>(); private Consumer onNavigate = u -> { }; private Runnable onEdit = () -> { }; /** * Creates a chip-based favorites bar. */ public FavChipBar() { super(new BorderLayout()); setOpaque(false); setBorder(new EmptyBorder(4, 8, 6, 8)); rebuild(); } private static String compactLabel(String url) { String s = url; if (s.startsWith("web://")) s = s.substring("web://".length()); if (s.endsWith("/")) s = s.substring(0, s.length() - 1); if (s.isEmpty()) s = url; if (s.length() <= 24) return s; return s.substring(0, 24) + "..."; } /** * Sets navigation callback. * * @param onNavigate callback */ public void setOnNavigate(Consumer onNavigate) { this.onNavigate = Objects.requireNonNull(onNavigate, "onNavigate"); rebuild(); } /** * Sets edit callback. * * @param onEdit callback */ public void setOnEdit(Runnable onEdit) { this.onEdit = Objects.requireNonNull(onEdit, "onEdit"); rebuild(); } /** * Replaces favorites list. * * @param items favorites */ public void setFavorites(List items) { favorites.clear(); if (items != null) favorites.addAll(items); rebuild(); } private void rebuild() { removeAll(); OACPanel chips = new OACPanel(new FlowLayout(FlowLayout.LEFT, 6, 0)); chips.setOpaque(false); for (String url : favorites) { if (url == null || url.isBlank()) continue; String u = url.trim(); OACButton chip = new OACButton(compactLabel("★ " + u)); chip.setToolTipText(u); chip.setMargin(new Insets(3, 10, 3, 10)); chip.setFocusable(false); chip.addActionListener(e -> onNavigate.accept(u)); chips.add(chip); } OACPanel right = new OACPanel(new FlowLayout(FlowLayout.RIGHT, 6, 0)); right.setOpaque(false); add(chips, BorderLayout.CENTER); add(right, BorderLayout.EAST); revalidate(); repaint(); } }