有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java使用Swing显示文件状态的好方法是什么

我想做以下几点,我需要一些关于什么是最好的方法的建议

我有一个JList,它显示用户通过单击add(+)按钮添加的文件,并在用户单击remove(-)按钮时删除文件。对于每个添加的文件,我想关联一个图标,它应该指示文件的状态。例如,如果用户只添加了文件而没有运行该文件(我有另一个JButton用于运行带有所选文件的应用程序),那么这个图标应该是红色的,一旦用户运行它,这个图标应该变为绿色。此外,如果用户通过单击(-)按钮删除文件,它也应该删除与该特定文件关联的图标。下面是我想要的图片

我正在考虑将图像图标与每个添加的文件相关联,但我不确定如何更改其外观以显示状态。我也不确定删除文件时如何删除ImageIcon。除了ImageIcon,还有其他方法吗?欢迎提供任何帮助/建议

enter image description here


共 (1) 个答案

  1. # 1 楼答案

    在编程中,数据为王。数据的表示方式不应考虑到数据,这是UI/视图层的域/职责

    这通常由model-view-controller pattern表示

    在您的示例中,有两条(基本)信息。一个文件和一个状态(未运行、运行、删除),您希望将这些信息合并为“数据”。在Java中,这通常意味着一个普通的旧Java对象(或Pojo)

    由于状态的可能性有限,我们可以使用enum来表示它,从而限制有效值

    public enum FileStatus {
        NOT_RUN, RUN, DELETED;
    }
    

    然后我们可以创建自己的pojo

    public class FileOperation {
        private File file;
        private FileStatus status;
    
        public FileOperation(File file, FileStatus status) {
            this.file = file;
            this.status = status;
        }
    
        public FileOperation(File file) {
            this(file, FileStatus.NOT_RUN);
        }
    
        public File getFile() {
            return file;
        }
    
        public FileStatus getStatus() {
            return status;
        }
    
        public void setStatus(FileStatus newStatus) {
            if (status == newStatus) {
                return;
            }
            this.status = newStatus;
        }
    
    }
    

    现在,当我们想知道文件的状态时,我们知道从哪里获取它

    但是JList呢?问得好。我们真正想要的是,当任何FileOperation对象的状态发生变化时,可以通过某种方式通知JList

    现在,你可以在ListModel上迭代,但这不是一个非常干净的解决方案,更好的解决方案是允许FileOperation在它发生变化时生成事件,让ListModel监听它们并采取自己的行动

    这是observer patternƒ的一个基本概念

    有很多方法可以做到这一点,但我很懒,所以我只打算使用可用的属性更改API

    public class FileOperation {
        private File file;
        private FileStatus status;
    
        private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
    
        public FileOperation(File file, FileStatus status) {
            this.file = file;
            this.status = status;
        }
    
        public FileOperation(File file) {
            this(file, FileStatus.NOT_RUN);
        }
    
        public File getFile() {
            return file;
        }
    
        public FileStatus getStatus() {
            return status;
        }
    
        public void setStatus(FileStatus newStatus) {
            if (status == newStatus) {
                return;
            }
            FileStatus oldStatus = status;
            status = newStatus;
            propertyChangeSupport.firePropertyChange("status", oldStatus, status);
        }
    
        public void addPropertyChangeListener(PropertyChangeListener listener) {
            propertyChangeSupport.addPropertyChangeListener(listener);
        }
    
        public void removePropertyChangeListener(PropertyChangeListener listener) {
            propertyChangeSupport.removePropertyChangeListener(listener);
        }
    }
    

    现在我们需要一个ListModel能对它做出反应

    public class FileOperationListModel extends AbstractListModel<FileOperation> {
    
        private List<FileOperation> items = new ArrayList<FileOperation>(25);
        private PropertyChangeListener handler = new PropertyChangeHandler();
    
        public void add(FileOperation fo) {
            fo.addPropertyChangeListener(handler);
            int size = items.size();
            items.add(fo);
            fireIntervalAdded(this, size, size);
        }
    
        public void remove(FileOperation fo) {
            int index = items.indexOf(fo);
            if (index < 0) {
                return;
            }
            fo.removePropertyChangeListener(handler);
            items.remove(fo);
            fireIntervalRemoved(this, index, index);
        }
    
        @Override
        public int getSize() {
            return items.size();
        }
    
        @Override
        public FileOperation getElementAt(int index) {
            return items.get(index);
        }
    
        public class PropertyChangeHandler implements PropertyChangeListener {
    
            @Override
            public void propertyChange(PropertyChangeEvent evt) {
                if (!(evt.getSource() instanceof FileOperation)) {
                    return;
                }
                FileOperation fo = (FileOperation) evt.getSource();
                int index = items.indexOf(fo);
                fireContentsChanged(FileOperationListModel.this, index, index);
            }
    
        }
    
    }
    

    现在,谜题的最后一部分是,你需要一个定制的ListCellRenderer,它可以显示你想要的信息

    为此,你必须从阅读How to use listsWriting a Custom Cell Renderer开始