Java 如何在JList中包装内容?

Java 如何在JList中包装内容?,java,file,jlist,horizontal-scrolling,Java,File,Jlist,Horizontal Scrolling,我有一个JList,显示文件列表(带有图标)。我正在使用DefaultListCellRenderer来完成此任务 然而,我只希望它显示3列,但它显示更多。我不希望用户必须垂直滚动。我该怎么做?我对Java相当陌生 这是我目前的代码: import java.awt.Component; import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java

我有一个JList,显示文件列表(带有图标)。我正在使用
DefaultListCellRenderer
来完成此任务

然而,我只希望它显示3列,但它显示更多。我不希望用户必须垂直滚动。我该怎么做?我对Java相当陌生

这是我目前的代码:

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();

    }

}
导入java.awt.Component;
导入java.awt.Dimension;
导入java.awt.GridBagConstraints;
导入java.awt.GridBagLayout;
导入java.awt.Insets;
导入java.io.File;
导入java.io.FileFilter;
导入javax.swing.DefaultListCellRenderer;
导入javax.swing.JFrame;
导入javax.swing.JLabel;
导入javax.swing.JList;
导入javax.swing.JPanel;
导入javax.swing.JScrollPane;
导入javax.swing.border.EmptyBorder;
导入javax.swing.filechooser.FileSystemView;
公共类StartMeUpBaby扩展了JFrame{
公共StartMeUpBaby(){
此.setLocationRelativeTo(空);
此.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
本条第2款(“测试”);
JPanel mainPanel=新的JPanel();
setLayout(新的GridBagLayout());
文件f=新文件(System.getProperty(“user.home”);
JList results=new JList(f.listFiles(new FileFilter()){
公共布尔接受(文件){
字符串名称=file.getName().toLowerCase();
返回name.length()<20;
}
}));
results.setCellRenderer(新的DefaultListCellRenderer(){
公共组件getListCellRenderComponent(JList列表、对象值、int索引、布尔isSelected、布尔cellHasFocus){
Component Component=super.getListCellRenderComponent(列表、值、索引、isSelected、cellHasFocus);
JLabel标签=(JLabel)组件;
文件=(文件)值;
label.setText(file.getName());
label.setIcon(FileSystemView.getFileSystemView().getSystemIcon(文件));
标签.新订单(新的空订单(3,3,3,3));
退货标签;
}
});
结果:setLayoutOrientation(JList.HORIZONTAL_WRAP);
JScrollPane scrollPane=新的JScrollPane(结果,JScrollPane.VERTICAL\u SCROLLBAR\u根据需要,JScrollPane.HORIZONTAL\u SCROLLBAR\u从不);
scrollPane.setPreferredSize(新维度(408100));
GridBagConstraints gbc=新的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.插图=新插图(5,5,5,5);
主面板。添加(滚动窗格,gbc);
添加(主面板);
这个包();
此.setVisible(true);
}
公共静态void main(字符串[]args){
新标准meupbaby();
}
}

我将首选大小设置为仅显示3列,但是如果调整窗口(使其更大),您可以看到这些列继续显示。

我通过Java文档进行了一些研究后发现了这一点

我所要做的就是添加这一行:

results.setVisibleRowCount(-1);
从:

水平缠绕
-单元格水平布局,根据需要缠绕到新行。如果
visibleRowCount
属性小于或等于零,则换行由列表的宽度决定;否则,将以确保列表中的行数
visibleRowCount
的方式进行包装

因此,您可以通过添加以下内容来解决问题:

results.setVisibleRowCount(0);
但是,您的JScrollPane大小(
setPreferredSize(新维度(488100))
)是任意的。显示三列所需的大小将取决于显示的文件名以及视觉属性,如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);
File f=新文件(System.getProperty(“user.home”);
File[]files=f.listFiles(新文件过滤器(){
公共布尔接受(文件){
字符串名称=file.getName().toLowerCase();
返回name.length()<20;
}
});
JList结果=新的JList(文件){
私有维度maxCellSize=新维度();
@凌驾
public void addNotify(){
super.addNotify();
重新计算MaxcellSize();
}
私有void重新计算MaxcellSize(){
ListCellRenderer