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