Как я могу использовать Highlighter SwingX для возврата другого компонента рендерера?
Я заметил SwingX Highlighter
Интерфейс позволяет подсветчику возвращать компонент, отличный от того, который передается. На самом деле я не могу найти никаких примеров его использования, но я подумал, что попытаюсь использовать его для создания какого-то фальшивого второго столбца.
Предполагаемый результат заключается в том, что текст в левом столбце должен обрезаться там, где начинается правый столбец, поэтому я не могу просто использовать Painter
, Правый столбец должен отображать одинаковую ширину для всего списка, что является проблемой, которую я еще не выяснил, но которая не кажется сложной.
Что касается сейчас, я обнаружил, что высота строки сжимается до такой степени, что вы не можете видеть текст.
Вот что я имею в виду:
Пример программы:
import java.awt.BorderLayout;
import java.awt.Component;
import javax.swing.DefaultListModel;
import javax.swing.GroupLayout;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.LayoutStyle;
import javax.swing.SwingUtilities;
import org.jdesktop.swingx.JXList;
import org.jdesktop.swingx.decorator.AbstractHighlighter;
import org.jdesktop.swingx.decorator.ComponentAdapter;
import org.jdesktop.swingx.renderer.JRendererLabel;
import org.jdesktop.swingx.renderer.StringValue;
public class RendererTest implements Runnable
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new RendererTest());
}
@Override
public void run()
{
JFrame frame = new JFrame("Highlighter test");
JXList list = new JXList();
DefaultListModel<String> listModel = new DefaultListModel<>();
listModel.addElement("one");
listModel.addElement("two");
listModel.addElement("three");
list.setModel(listModel);
list.setVisibleRowCount(8);
list.setPrototypeCellValue("some string");
list.addHighlighter(new AddSecondColumnHighlighter(v -> ((String) v).toUpperCase()));
JScrollPane listScroll = new JScrollPane(list);
frame.setLayout(new BorderLayout());
frame.add(listScroll, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
private static class AddSecondColumnHighlighter extends AbstractHighlighter
{
private final StringValue secondColumnStringValue;
public AddSecondColumnHighlighter(StringValue secondColumnStringValue)
{
this.secondColumnStringValue = secondColumnStringValue;
}
@Override
protected Component doHighlight(Component component, ComponentAdapter adapter)
{
JRendererLabel rightColumn = new JRendererLabel();
rightColumn.setText(secondColumnStringValue.getString(adapter.getValue()));
return new FixedSecondColumnRendererLabel(component, rightColumn);
}
}
private static class FixedSecondColumnRendererLabel extends JRendererLabel
{
private FixedSecondColumnRendererLabel(Component leadingComponent, Component trailingComponent)
{
GroupLayout layout = new GroupLayout(this);
setLayout(layout);
layout.setHorizontalGroup(layout.createSequentialGroup()
.addComponent(leadingComponent, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
.addComponent(trailingComponent));
layout.setVerticalGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
.addComponent(leadingComponent)
.addComponent(trailingComponent));
}
}
}
Мне интересно, есть ли правильный способ использовать этот бит API. Я намеренно продлил JRendererLabel
в случае, если это было проблемой, но это кажется чем-то более тонким...
1 ответ
Если вы посмотрите на JRendererLabel
, вы увидите, что invalidate
, revalidate
, validate
(и куча других методов) были установлены на "бездействие", что означает, что они больше не отправляют диспетчеру макета уведомления о том, что компонент должен быть размечен. Это сделано для того, чтобы улучшить производительность "штамповки" рендерера на компоненте (JXList
).
Вместо этого используйте расширение FixedSecondColumnRendererLabel
от JPanel
,
Вместо создания нового экземпляра FixedSecondColumnRendererLabel
а также JRendererLabel
каждый раз, когда вызывается метод, вы должны подумать о его оптимизации, чтобы вы возвращали один и тот же экземпляр, но тот, который настраивается при каждом вызове метода.
Помните, этот метод вызывается для КАЖДОЙ строки в вашем JXList
чем больше у вас есть, чем больше он будет вызываться, тем более недолговечные объекты он будет создавать...