我注意到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
,以防出现问题,但这似乎更微妙......
答案 0 :(得分:2)
如果查看JRendererLabel
,您会看到invalidate
,revalidate
,validate
(以及其他一些方法)设置为“否” “操作”,意味着他们不再向布局管理器发出组件应该布局的通知。这样做是为了帮助提高渲染器“压印”到组件(JXList
)的性能。
相反,请使用FixedSecondColumnRendererLabel
中的扩展JPanel
。
每次调用方法时,不应该创建FixedSecondColumnRendererLabel
和JRendererLabel
的新实例,而应该考虑对其进行优化,以便返回相同的实例,但每次执行时都会配置一个实例。被称为。
请记住,在JXList
中为每一行调用此方法,您拥有的越多,调用的次数越多,它将创建的短暂对象就越多......