使用 Swing 显示文件状态的好方法是什么
What is a good way to display status of a file using Swing
我想执行以下操作,我需要一些建议以了解最佳执行方式。
我有一个 JList,它显示用户通过单击添加 (+) 按钮添加的文件,并在用户单击删除 (-) 按钮时删除文件。对于每个添加的文件,我想关联一个图标来指示文件的状态。例如,如果用户只添加了文件而不是 运行 文件(我有另一个 JButton 用于 运行 使用所选文件连接应用程序),那么这个图标应该是红色的,一旦用户运行好了,这个图标应该变成绿色了。此外,如果用户通过单击 (-) 按钮删除文件,它也应该删除与该特定文件关联的图标。下面是我想要的图形表示。
我正在考虑将一个 ImageIcon 与每个添加的文件相关联,但我不确定如何更改其外观以显示状态。我也不确定在删除文件时如何删除 ImageIcon。还有其他方法(ImageIcon 除外)吗?任何 help/suggestions 都表示赞赏。
在编程中,数据为王。数据的表示方式不应考虑数据,即 UI/view 层的 domain/responsibility。
这通常由 model-view-controller pattern
表示
在您的示例中,您有两条(基本)信息。一个文件和一个状态(不是 运行、运行、已删除),您想将此信息合并为 "data"。在 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
倾听他们的声音并采取自己的行动。
的基本概念
有很多方法可以做到这一点,但我很懒,所以我将使用可用的 属性 更改 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 lists and Writing a Custom Cell Renderer
我想执行以下操作,我需要一些建议以了解最佳执行方式。
我有一个 JList,它显示用户通过单击添加 (+) 按钮添加的文件,并在用户单击删除 (-) 按钮时删除文件。对于每个添加的文件,我想关联一个图标来指示文件的状态。例如,如果用户只添加了文件而不是 运行 文件(我有另一个 JButton 用于 运行 使用所选文件连接应用程序),那么这个图标应该是红色的,一旦用户运行好了,这个图标应该变成绿色了。此外,如果用户通过单击 (-) 按钮删除文件,它也应该删除与该特定文件关联的图标。下面是我想要的图形表示。
我正在考虑将一个 ImageIcon 与每个添加的文件相关联,但我不确定如何更改其外观以显示状态。我也不确定在删除文件时如何删除 ImageIcon。还有其他方法(ImageIcon 除外)吗?任何 help/suggestions 都表示赞赏。
在编程中,数据为王。数据的表示方式不应考虑数据,即 UI/view 层的 domain/responsibility。
这通常由 model-view-controller pattern
表示在您的示例中,您有两条(基本)信息。一个文件和一个状态(不是 运行、运行、已删除),您想将此信息合并为 "data"。在 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
倾听他们的声音并采取自己的行动。
有很多方法可以做到这一点,但我很懒,所以我将使用可用的 属性 更改 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 lists and Writing a Custom Cell Renderer