The table lists every learned and static entry in one flat block, which is
fine with a handful and unusable with a few hundred: finding out where one
MAC sits, or what a port has learned, meant reading the whole thing.
Make the column headings sort and give each one a filter box. Filters are
substring matches combined with AND, so "port 8 + static" is two keystrokes.
A counter above the table shows matched out of total, so a filter that hides
everything is obvious rather than looking like an empty table.
Sorting keeps the CPU entry from comparing as a number - it sorts last
instead of landing between ports 8 and 9, where a string-vs-number compare
would otherwise put it.
The filter inputs live inside the existing header cells rather than in a
second row: the paint loop addresses data rows as rows[i+1], and a second
header row would have shifted every one of them.