Ну, вот решение.
Короче говоря, вы можете создать подкласс 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
. Здесь вам нужно сделать несколько отдельных шагов, которые вы можете организовать различными способами или чем-то еще. Для простоты я все изложу в методе рисования.
@Override
protected void paintComponent(Graphics g) {
...
Сначала вам нужно выяснить физические размеры выделения, что вы можете сделать, используя класс FontMetrics
. Создайте класс FontMetrics
для Font
, который вы используете.
FontMetrics metrics = new FontMetrics(getFont());
Теперь вы можете получить всю информацию, необходимую для создания прямоугольника, который будет основным моментом. Вам понадобится начальная позиция, высота и ширина. Чтобы получить это, вам понадобятся две подстроки текста JLabel
следующим образом:
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);
}
Конечно, если вы хотите, чтобы выделение занимало несколько строк, это потребует дополнительной работы.
Если вам интересно, я уже писал что-то подобное раньше. По какой-то причине я решил написать свой собственный компонент типа текстовой области из JPanel
, и именно так я и работал с подсветкой. Изобретать колесо может быть глупо в реальном проекте, но оно учит вас случайным вещам, которые могут оказаться полезными ...