You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NatTable单元格内可点击文本功能求助:点击跳转至指定行

Solution for Clickable Text in NatTable Cells to Jump to Corresponding Rows

Hey there! Awesome to hear NatTable's performance is treating you well—it's such a solid tool for large datasets. Let's walk through how to add those clickable links in cells that jump to target rows, I've built something similar before.

Core Approach

NatTable doesn't have built-in support for segmented clickable text in cells, so we'll need to:

  • Create a custom cell renderer that draws each link as a separate, trackable element
  • Add a mouse listener to detect clicks on those links and trigger row selection/scroll

Step 1: Prepare Your Data Model

First, make sure your row data includes the information needed to map link text to target rows. For example, if each row has related names, store either the target row indices or a reference to the related data objects:

public class YourDataRow {
    private String rowId;
    private String name;
    private List<String> relatedNames; // e.g., ["Name 2", "Name 3"] for Row 1
    // Getters and setters
}

This renderer will draw each link with trackable bounds, so we can detect which link was clicked later. Extend NatTable's TextPainter for consistency:

import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
import org.eclipse.nebula.widgets.nattable.layer.cell.ILayerCell;
import org.eclipse.nebula.widgets.nattable.painter.cell.TextPainter;
import org.eclipse.swt.graphics.*;
import java.util.ArrayList;
import java.util.List;

public class ClickableLinksRenderer extends TextPainter {
    private List<LinkMetadata> linkMetadataList = new ArrayList<>();
    private YourDataModel dataModel; // Inject your data model here

    @Override
    public void paintCell(ILayerCell cell, GC gc, Rectangle bounds, IConfigRegistry configRegistry) {
        linkMetadataList.clear(); // Reset for each cell paint
        YourDataRow rowData = (YourDataRow) cell.getDataValue();
        List<String> relatedNames = rowData.getRelatedNames();
        if (relatedNames == null || relatedNames.isEmpty()) {
            super.paintCell(cell, gc, bounds, configRegistry);
            return;
        }

        // Configure styles
        Font cellFont = configRegistry.getConfigAttribute(
                CellConfigAttributes.CELL_FONT, DisplayMode.NORMAL, cell.getConfigLabels());
        Color linkColor = configRegistry.getConfigAttribute(
                CellConfigAttributes.FOREGROUND_COLOR, DisplayMode.SELECT, cell.getConfigLabels());
        Color defaultColor = configRegistry.getConfigAttribute(
                CellConfigAttributes.FOREGROUND_COLOR, DisplayMode.NORMAL, cell.getConfigLabels());
        gc.setFont(cellFont);

        int currentX = bounds.x + getHorizontalPadding();
        int currentY = bounds.y + getVerticalPadding();
        int spacing = 8; // Space between links

        for (String linkText : relatedNames) {
            Point textSize = gc.textExtent(linkText);
            Rectangle linkBounds = new Rectangle(currentX, currentY, textSize.x, textSize.y);
            
            // Find target row index from your data model
            int targetRowIndex = findTargetRowIndex(linkText);
            if (targetRowIndex != -1) {
                linkMetadataList.add(new LinkMetadata(linkText, targetRowIndex, linkBounds));
            }

            // Draw link with highlight color
            gc.setForeground(linkColor);
            gc.drawText(linkText, currentX, currentY, true);
            
            currentX += textSize.x + spacing;
        }
    }

    // Check if a click point hits any link, return target row index if so
    public Integer getTargetRowFromClick(ILayerCell cell, Point globalClickPoint) {
        Rectangle cellBounds = cell.getBounds();
        Point localClick = new Point(
                globalClickPoint.x - cellBounds.x,
                globalClickPoint.y - cellBounds.y);
        
        for (LinkMetadata metadata : linkMetadataList) {
            if (metadata.linkBounds.contains(localClick)) {
                return metadata.targetRowIndex;
            }
        }
        return null;
    }

    // Helper: Find row index by name from your data model
    private int findTargetRowIndex(String linkText) {
        for (int i = 0; i < dataModel.getRowCount(); i++) {
            if (dataModel.getRow(i).getName().equals(linkText)) {
                return i;
            }
        }
        return -1;
    }

    // Inner class to store link details
    private static class LinkMetadata {
        String linkText;
        int targetRowIndex;
        Rectangle linkBounds;

        LinkMetadata(String linkText, int targetRowIndex, Rectangle linkBounds) {
            this.linkText = linkText;
            this.targetRowIndex = targetRowIndex;
            this.linkBounds = linkBounds;
        }
    }
}

Step 3: Register the Renderer to Your Column

Tell NatTable to use your custom renderer for the "Related links" column. First, assign a unique label to the column (e.g., RELATED_LINKS_COLUMN), then register the renderer:

// Assuming you have a column configuration for your NatTable
configRegistry.registerConfigAttribute(
        CellConfigAttributes.CELL_PAINTER,
        new ClickableLinksRenderer(yourDataModel), // Inject your data model
        DisplayMode.NORMAL,
        new LabelStack("RELATED_LINKS_COLUMN"));

Step 4: Add Mouse Listener to Handle Clicks

Finally, add a mouse listener to your NatTable to detect link clicks and trigger row selection/scroll:

natTable.addMouseListener(new MouseAdapter() {
    @Override
    public void mouseUp(MouseEvent e) {
        if (e.button == SWT.BUTTON1) { // Only handle left clicks
            Point clickPoint = new Point(e.x, e.y);
            ILayerCell clickedCell = natTable.getCellByPosition(clickPoint);
            
            if (clickedCell != null && clickedCell.getConfigLabels().hasLabel("RELATED_LINKS_COLUMN")) {
                ClickableLinksRenderer renderer = (ClickableLinksRenderer) configRegistry.getConfigAttribute(
                        CellConfigAttributes.CELL_PAINTER,
                        DisplayMode.NORMAL,
                        clickedCell.getConfigLabels());
                
                Integer targetRow = renderer.getTargetRowFromClick(clickedCell, clickPoint);
                if (targetRow != null && targetRow >= 0) {
                    // Select the target row
                    natTable.doCommand(new SelectRowsCommand(
                            natTable, targetRow, targetRow, false, false));
                    // Scroll the row into view if it's not visible
                    natTable.doCommand(new ShowRowInViewportCommand(natTable, targetRow));
                }
            }
        }
    }
});

Bonus: Add Hover Effects

To make it more user-friendly, add a mouse move listener to change the cursor when hovering over a link:

natTable.addMouseMoveListener(new MouseMoveListener() {
    @Override
    public void mouseMove(MouseEvent e) {
        Point clickPoint = new Point(e.x, e.y);
        ILayerCell cell = natTable.getCellByPosition(clickPoint);
        
        if (cell != null && cell.getConfigLabels().hasLabel("RELATED_LINKS_COLUMN")) {
            ClickableLinksRenderer renderer = (ClickableLinksRenderer) configRegistry.getConfigAttribute(
                    CellConfigAttributes.CELL_PAINTER,
                    DisplayMode.NORMAL,
                    cell.getConfigLabels());
            
            Integer targetRow = renderer.getTargetRowFromClick(cell, clickPoint);
            natTable.setCursor(targetRow != null ? SWT.CURSOR_HAND : SWT.CURSOR_ARROW);
        } else {
            natTable.setCursor(SWT.CURSOR_ARROW);
        }
    }
});

That should do it! This setup will let users click on names in the "Related links" column to jump straight to the corresponding row. Let me know if you run into any issues with edge cases like long text wrapping or dynamic data updates.

内容的提问来源于stack exchange,提问作者Kalyan Rajpoot

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:29:00