Прежде чем кто-либо предложит HTML, я объясню позже, почему это не вариант здесь. У меня есть таблица, которая содержит столбец с текстовыми ячейками в нем. Мне нужно иметь возможность выделить часть текста в каждой ячейке. Так, например, если в ячейке содержится «cat foo dog» ... я мог бы выделить foo.
Мой текущий метод заключается в использовании пользовательского TableCellRenderer, который помещает html в компонент JLabel, который визуализируется, и какое-то время это было хорошо. Затем я заметил, что когда текст в ячейке становится слишком длинным, чтобы поместиться в ширину столбца, он просто обрезает текст без нормального «...», что обычно происходит в этом случае. Таким образом, пользователи не знали, что было больше текста, который они не видели. Другая проблема заключалась в том, что если исходный текст сам содержал HTML, что в моем случае иногда происходит, ячейка отображалась бы неправильно. Я знаю, что могу просто избежать html, но у меня все еще будет существующая проблема.
Если я использую компонент, отличный от jlabel, тогда ячейки моего стола выглядят странно. У кого-нибудь есть предложения? Спасибо
Ну вот и решение.
Короче говоря, вы можете создать подкласс 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
, и это был в основном способ, которым я обрабатывал выделение. Изобретать велосипед в реальном проекте может быть глупо, но он учит вас случайным вещам, которые могут оказаться полезными...