通过 Java 中的按钮刷新自定义容器

Posted

技术标签:

【中文标题】通过 Java 中的按钮刷新自定义容器【英文标题】:Refresh custom container through a button inside it in Java 【发布时间】:2015-08-09 08:03:50 【问题描述】:

早上好,

我有一个继承自 java.awt.Container 的类。他的范围是包装一个文件列表,将它们垂直显示为“文件名标签+删除按钮”列表。

文件显示正确,每次添加新文件时,都会正确刷新。

组件类的代码:

public class AttachmentsList extends Container 
private List<File>  attachments = null;

public AttachmentsList(List<File> attachments)

    super();
    this.attachments = attachments;
    buildListAttachments();


@Override
public void repaint()

    buildListAttachments();
    super.repaint();


protected void buildListAttachments()

    int yTraslation = 0;

    for (File attachment : this.attachments)
    
        Label fileName = new Label(attachment.getName());
        fileName.setBounds(10, 10 + yTraslation, 70, 20);

        //invisible, just contain the absolute path...
        final Label path = new Label(attachment.getAbsolutePath());
        fileName.setBounds(10, 10 + yTraslation, 70, 20);

        Button deleteFile = new Button("x");
        deleteFile.setBounds(90, 10 + yTraslation, 20, 20);

        deleteFile.addActionListener(new ActionListener()
        
            @Override
            public void actionPerformed(ActionEvent e)
            
                File fileToRemove = new File(path.getText());
                attachments.remove(fileToRemove);
                System.out.println(attachments.size());
                repaint();//<---- It doesn't refresh the main UI.
            
        );

        add(fileName);
        add(deleteFile);

        yTraslation += 20;
    

按钮的作用域是从文件列表中删除由他自己的绝对路径标识的特定文件。它可以工作,但我不知道如何通过主界面刷新他的 UI。

上面的代码在主 UI 类中被调用:

...
final List<File> filesAttached = new LinkedList<File>();
...
final AttachmentsList attachmentsList = new AttachmentsList(fileAttached);
attachmentsList.setBounds(10, 80, 120, 200);
...
//inside ActionListener
...
//pathChooser is a JFileChooser object
fileAttached.add(pathChooser.getSelectedFile());
//every time that one file is added i have to refresh that component. It refreshes!
attachmentsList.repaint();
...

每次按下“deleteFile”按钮时,我都必须刷新该容器。我该怎么做?

谢谢你,问候

安德烈亚

【问题讨论】:

为什么要使用 AWT?请参阅 this answer 了解放弃 AWT 使用支持 Swing 的组件的许多充分理由。 谢谢安德鲁!我不知道 AWT 和那个答案中描述的一样差。没有任何关于 Java GUI 的经验,我拿了一本旧的 Java 教科书来构建该应用程序,它解释了 AWT,但没有解释 Swing,这就是我开始使用 AWT 的原因。 “我拿了一本旧的 Java 教科书” 一本书!多么..古雅。我一直期待(害怕)看到 Youtube 上的教程的链接。 ;) 但对于中间地带(基于网络,低带宽),请参阅 Creating a GUI With JFC/Swing。 :) 是的......可能会更好。多年来我一直相信那本书,但现在是时候烧掉它了!尽管在docs.oracle.com/javase/tutorial/uiswing/layout/index.html 下阅读了您的链接,但我无法找出问题所在……我是新手! :) “将它们垂直显示为“文件名标签 + 删除按钮”列表。” 我会使用 JListJTable 来显示文件,也许在Delete Selected Files下方有一个JButton。请参阅 File Browser GUI,了解在基于 Swing 的 JTable(或 JTree!)中如何优雅地表示文件。 【参考方案1】:

终于根据安德鲁的建议找到了解决办法。

这是我的课:

public class AttachmentsList extends JPanel

private List<File>          attachments = null;

private JTable              jt          = null;
private DefaultTableModel   model       = null;
private JScrollPane         scroller    = null;

public AttachmentsList(List<File> attachments)

    super();
    this.attachments = attachments;
    setLayout(new GridLayout());

    Vector<Vector> rowData = new Vector<Vector>();

    for (File iterable_element : this.attachments)
    
        Vector<Object> row = new Vector<Object>();
        row.addElement(iterable_element.getName());
        row.addElement(new JCheckBox());

        rowData.add(row);
    

    Vector<String> columnNames = new Vector<String>();
    columnNames.add("File");
    columnNames.add("Selected");

    this.jt = new JTable(rowData, columnNames);
    this.jt.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

    this.model = (DefaultTableModel) this.jt.getModel();

    final TableColumnModel columnModel = this.jt.getColumnModel();

    columnModel.getColumn(0).setPreferredWidth(100);
    columnModel.getColumn(1).setPreferredWidth(60);

    this.scroller = new JScrollPane(this.jt);

    add(this.scroller);


@Override
public void repaint()

    buildTable();


protected void buildTable()

    if (this.attachments != null)
    
        Vector<Vector> rowData = new Vector<Vector>();

        for (File currentFile : this.attachments)
        
            Vector<Object> row = new Vector<Object>();
            row.addElement(currentFile.getName());
            row.addElement(false);

            rowData.add(row);
        

        this.model.addRow(rowData);
    


public void addFile(File file)

    Vector<Object> row = new Vector<Object>();
    row.addElement(file.getName());
    row.addElement(false);

    this.model.addRow(row);


public List<File> getAttachments()

    return attachments;


public void setAttachments(List<File> attachments)

    this.attachments = attachments;



这是一个有效的原始组件,显示存储在 List 中的文件。

【讨论】:

以上是关于通过 Java 中的按钮刷新自定义容器的主要内容,如果未能解决你的问题,请参考以下文章

删除数据库行后刷新自定义游标适配器

在 Kotlin 中单击按钮后每秒刷新自定义视图

echarts自定义dataview里面lang默认的按钮怎么删除

添加自定义android webview错误页面

ios 自定义cell怎么刷新表

在 xcode 中的自定义视图中给出高度后刷新情节提要视图控制器