好吧,这是一个解决方案。
简而言之,您可以子类JLabel
化以手动绘制突出显示。覆盖该paintComponent
方法以进行实际绘图并用于FontMetrics
计算应在何处绘制突出显示的区域。
这是极其详细的答案:
基本上,您可以创建一个JLabel
可以突出显示内容的子类。我会这样做;您可能想以不同的方式进行操作:
添加一个方法,告诉标签突出显示哪个部分。这可能是这样的,假设您只需要一个突出显示的区域:
public void highlightRegion(int start, int end) {
// Set some field to tell you where the highlight starts and ends...
}
如果您需要多个区域,只需一个 ArrayList 而不是一个简单的字段。一种取消突出显示的方法可能也很有用。
现在,您需要重写paintComponent
. JLabel
在这里,您需要执行几个离散的步骤,您可能希望以不同的方法或其他方式组织这些步骤。为简单起见,我将把它全部放在paint方法中。
@Override
protected void paintComponent(Graphics g) {
...
首先,您需要确定高光的物理尺寸,您可以使用 niceFontMetrics
类来完成。FontMetrics
为Font
您正在使用的类创建类。
FontMetrics metrics = new FontMetrics(getFont());
现在,您可以获得创建将成为突出显示的矩形所需的所有信息。您将需要起始位置、高度和宽度。为此,您需要JLabel
's 文本的两个子字符串,如下所示:
String start = getText().substring(0, startOfHighlight);
String text = getText().substring(startOfHighlight, endOfHighlight);
//You may also need to account for some offsets here:
int startX = metrics.stringWidth(start);
int startY = 0; //You probably have some vertical offset to add here.
int length = metrics.stringWidth(text);
int height = metrics.getHeight();
现在您可以在绘制标签的其余部分之前绘制突出显示的区域:
g.fillRect(startX, startY, length, height);
super.paintComponent(g);
}
当然,如果您希望突出显示跨越多行,那将需要更多的工作。
如果你想知道,实际上我以前写过类似的东西。一时兴起,我决定从 a 编写自己的文本区域类型组件JPanel
,这基本上就是我处理突出显示的方式。在实际项目中重新发明轮子可能是愚蠢的,但它确实教会了你可能有用的随机东西......