我正在尝试将JList
置于JScrollPane
内,并按字母顺序列出垂直列中的条目,如下所示:
A D G
B E H
C F
但是当JList
空间不足以显示更多条目时,我希望JScrollPane
在垂直方向上滚动 方向。
当我使用VERTICAL_WRAP
时,这是有效的。但是,似乎当我使用垂直换行时,我得到一个水平滚动条,当我使用HORIZONTAL_WRAP
时,我得到了我想要的滚动条,但这些项目按照我不喜欢的顺序放置。我可以吃蛋糕吗?这是我正在尝试做的一个简单例子。
这是我能得到的最接近的,但我希望能够在保持垂直字母顺序的同时垂直滚动。
public class ScrollListExample {
static List<String> stringList = new ArrayList<String>();
static {
for (int i = 0; i < 500; i++) {
stringList.add("test" + i);
}
}
public static void main(final String[] args) {
final JFrame frame = new JFrame();
final Container contentPane = frame.getContentPane();
final JList list = new JList(stringList.toArray());
list.setLayoutOrientation(JList.VERTICAL_WRAP);
list.setVisibleRowCount(0);
final JScrollPane scrollPane = new JScrollPane(list);
contentPane.add(scrollPane);
frame.setPreferredSize(new Dimension(800, 400));
frame.pack();
frame.setVisible(true);
}
}
我的一个解决方案是: 如果已知单元格大小,我可以创建组件侦听器,并侦听resize事件。当触发该事件时,我可以计算所需的行数以防止水平滚动。这看起来像是一个黑客,我不确定它如何适用于可变大小的文本组件。
答案 0 :(得分:2)
我认为你的解决方案很好,而且根本不是黑客攻击。无论如何,任何内置功能都必须做同样的事情。
以下是对您的示例的修改,可以执行您想要的操作。
public class ScrollListExample {
static List<String> stringList = new ArrayList<String>();
static {
for (int i = 0; i < 500; i++) {
stringList.add("test" + i);
}
}
public static void main(final String[] args) {
final JFrame frame = new JFrame();
final Container contentPane = frame.getContentPane();
final JList list = new JList(stringList.toArray());
list.setLayoutOrientation(JList.VERTICAL_WRAP);
final JScrollPane scrollPane = new JScrollPane(list);
contentPane.add(scrollPane);
frame.setPreferredSize(new Dimension(800, 400));
frame.pack();
list.addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
fixRowCountForVisibleColumns(list);
}
});
fixRowCountForVisibleColumns(list);
frame.setVisible(true);
}
private static void fixRowCountForVisibleColumns(JList list) {
int nCols = computeVisibleColumnCount(list);
int nItems = list.getModel().getSize();
// Compute the number of rows that will result in the desired number of
// columns
int nRows = nItems / nCols;
if (nItems % nCols > 0) nRows++;
list.setVisibleRowCount(nRows);
}
private static int computeVisibleColumnCount(JList list) {
// It's assumed here that all cells have the same width. This method
// could be modified if this assumption is false. If there was cell
// padding, it would have to be accounted for here as well.
int cellWidth = list.getCellBounds(0, 0).width;
int width = list.getVisibleRect().width;
return width / cellWidth;
}
}
答案 1 :(得分:0)
这是你想要的吗? (可能需要更改首选尺寸......)
public class ScrollListExample {
static List<String> stringList = new ArrayList<String>();
static {
for (int i = 0; i < 500; i++) {
stringList.add("test" + i);
}
}
public static void main(final String[] args) {
final JFrame frame = new JFrame();
final Container contentPane = frame.getContentPane();
final JList list = new JList(stringList.toArray());
final JScrollPane scrollPane = new JScrollPane(list);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
contentPane.add(scrollPane);
frame.setPreferredSize(new Dimension(200,200));
frame.pack();
frame.setVisible(true);
}
}
答案 2 :(得分:0)
Brilliant Code @Kevin K ...我建议进行一些小修改以避免ArithmeticException(除以零)
private int computeVisibleColumnCount(JList list)
{
int cellWidth = list.getCellBounds(0, 0).width;
int width = list.getVisibleRect().width;
return width == 0 ? 1 : width / cellWidth;
}