我如何在Java中的JList中包装内容
问题描述:
现在我只有一个显示文件列表(带图标)的JList。我使用DefaultListCellRenderer来完成此操作。但是,我只希望它显示3列,但它显示更多。我不希望用户必须垂直滚动才能滚动。我怎样才能做到这一点?我对Java相当陌生。这是到目前为止我的代码:我如何在Java中的JList中包装内容
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.io.File;
import java.io.FileFilter;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.border.EmptyBorder;
import javax.swing.filechooser.FileSystemView;
public class StartMeUpBaby extends JFrame {
public StartMeUpBaby() {
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setTitle("TESTING");
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new GridBagLayout());
File f = new File(System.getProperty("user.home"));
JList<File> results = new JList<File>(f.listFiles(new FileFilter() {
public boolean accept(File file) {
String name = file.getName().toLowerCase();
return name.length() < 20;
}
}));
results.setCellRenderer(new DefaultListCellRenderer() {
public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
Component component = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
JLabel label = (JLabel)component;
File file = (File)value;
label.setText(file.getName());
label.setIcon(FileSystemView.getFileSystemView().getSystemIcon(file));
label.setBorder(new EmptyBorder(3, 3, 3, 3));
return label;
}
});
results.setLayoutOrientation(JList.HORIZONTAL_WRAP);
JScrollPane scrollPane = new JScrollPane(results, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane.setPreferredSize(new Dimension(408, 100));
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 3;
gbc.gridheight = 2;
gbc.weightx = 100;
gbc.weighty = 100;
gbc.anchor = GridBagConstraints.WEST;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(5, 5, 5, 5);
mainPanel.add(scrollPane, gbc);
this.add(mainPanel);
this.pack();
this.setVisible(true);
}
public static void main(String[] args) {
new StartMeUpBaby();
}
}
注:我首选大小设置为只显示3列,但是如果你调整窗口(使它更大),你可以看到,柱继续。
答
在通过Java文档进行了一些研究之后,我发现了它。
我所要做的就是加入这一行:
results.setVisibleRowCount(-1);
答
从documentation of JList.setLayoutOrientation:
HORIZONTAL_WRAP
- 细胞水平布局,包裹在必要时新行。如果visibleRowCount
属性小于或等于零,则换行由列表的宽度决定;否则包装会以确保列表中的visibleRowCount
行的方式完成。
因此,您可以通过添加这种解决您的问题:
results.setVisibleRowCount(0);
但是,你JScrollPane的大小(setPreferredSize(new Dimension(488, 100))
)是任意的。显示三列所需的大小取决于所显示的文件名以及JList字体等可视属性。如果即使只有一个相当长的文件名,单元格也会变宽,而且你的尺寸可能不够。
要完全健壮,则需要根据每个文件的渲染计算首选大小:
File f = new File(System.getProperty("user.home"));
File[] files = f.listFiles(new FileFilter() {
public boolean accept(File file) {
String name = file.getName().toLowerCase();
return name.length() < 20;
}
});
JList<File> results = new JList<File>(files) {
private Dimension maxCellSize = new Dimension();
@Override
public void addNotify() {
super.addNotify();
recomputeMaxCellSize();
}
private void recomputeMaxCellSize() {
ListCellRenderer<? super File> renderer = getCellRenderer();
if (renderer == null) {
return;
}
int fixedWidth = getFixedCellWidth();
int fixedHeight = getFixedCellHeight();
Rectangle maxCellBounds = new Rectangle();
for (int i = getModel().getSize() - 1; i >= 0; i--) {
Component c =
renderer.getListCellRendererComponent(this,
getModel().getElementAt(i), i, false, false);
Dimension cellSize = c.getPreferredSize();
maxCellBounds.add(
fixedWidth >= 0 ? fixedWidth : cellSize.width,
fixedHeight >= 0 ? fixedHeight : cellSize.height);
}
maxCellSize = maxCellBounds.getSize();
}
@Override
public Dimension getPreferredSize() {
int count = getModel().getSize();
int rows = count/3 + (count % 3 == 0 ? 0 : 1);
return new Dimension(maxCellSize.width * 3,
maxCellSize.height * rows);
}
@Override
public Dimension getPreferredScrollableViewportSize() {
int rows = getVisibleRowCount();
if (rows <= 0) {
rows = 4;
}
return new Dimension(maxCellSize.width * 3,
maxCellSize.height * rows);
}
private final ListDataListener modelListener = new ListDataListener() {
@Override
public void intervalAdded(ListDataEvent event) {
recomputeMaxCellSize();
}
@Override
public void intervalRemoved(ListDataEvent event) {
recomputeMaxCellSize();
}
@Override
public void contentsChanged(ListDataEvent event) {
recomputeMaxCellSize();
}
};
@Override
public void setModel(ListModel<File> newModel) {
getModel().removeListDataListener(modelListener);
newModel.addListDataListener(modelListener);
super.setModel(newModel);
recomputeMaxCellSize();
}
@Override
public void setCellRenderer(ListCellRenderer<? super File> renderer) {
super.setCellRenderer(renderer);
recomputeMaxCellSize();
}
@Override
public void setFont(Font font) {
super.setFont(font);
recomputeMaxCellSize();
}
@Override
public void setFixedCellWidth(int width) {
super.setFixedCellWidth(width);
recomputeMaxCellSize();
}
@Override
public void setFixedCellHeight(int height) {
super.setFixedCellHeight(height);
recomputeMaxCellSize();
}
};
results.setVisibleRowCount(0);