Как выделить часть JLabel?

Прежде чем кто-либо предложит HTML, я объясню позже, почему это не вариант здесь. У меня есть таблица, которая содержит столбец с текстовыми ячейками в нем. Мне нужно иметь возможность выделить часть текста в каждой ячейке. Так, например, если в ячейке содержится «cat foo dog» ... я мог бы выделить foo.

Мой текущий метод заключается в использовании пользовательского TableCellRenderer, который помещает html в компонент JLabel, который визуализируется, и какое-то время это было хорошо. Затем я заметил, что когда текст в ячейке становится слишком длинным, чтобы поместиться в ширину столбца, он просто обрезает текст без нормального «...», что обычно происходит в этом случае. Таким образом, пользователи не знали, что было больше текста, который они не видели. Другая проблема заключалась в том, что если исходный текст сам содержал HTML, что в моем случае иногда происходит, ячейка отображалась бы неправильно. Я знаю, что могу просто избежать html, но у меня все еще будет существующая проблема.

Если я использую компонент, отличный от jlabel, тогда ячейки моего стола выглядят странно. У кого-нибудь есть предложения? Спасибо

7
задан demBones 29 February 2012 в 21:49
поделиться

1 ответ

Ну вот и решение.

Короче говоря, вы можете создать подкласс 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, и это был в основном способ, которым я обрабатывал выделение. Изобретать велосипед в реальном проекте может быть глупо, но он учит вас случайным вещам, которые могут оказаться полезными...

7
ответ дан 6 December 2019 в 22:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: