0

Good morning,

I have a class that inherit from java.awt.Container. His scope is to wrap a list of Files showing them vertically as a "file name Labels + delete Buttons" list.

files are shown properly and every time a new one is added, it refresh correctly.

The component class's code:

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;
    }
}

The button's scope is removing from the files list a specific file identified by his own absolute path. It works, but I can't figure how to refresh his UI through the main interface.

The above code it's called in the main UI class:

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

Every time "deleteFile" button is pressed I have to refresh that Container. How can I do that?

Thankyou, regards

Andrea

Andrea Grimandi
  • 631
  • 2
  • 8
  • 32
  • Why use AWT? See [this answer](http://stackoverflow.com/questions/6255106/java-gui-listeners-without-awt/6255978#6255978) for many good reasons to abandon AWT using components in favor of Swing. – Andrew Thompson May 28 '15 at 12:29
  • Thank you Andrew! I didn't know that AWT is as poor as described in that answer. Not having any experiences about Java GUI I took an old Java school book to build that application and it explained AWT but not Swing that's why I've started using AWT. – Andrea Grimandi May 28 '15 at 15:55
  • *"I took an old Java school book"* A book! How ..quaint. I keep expecting (dreading) to see links to **tutorials on Youtube.** ;) But for the middle ground (net based, low bandwidth) see [Creating a GUI With JFC/Swing](http://docs.oracle.com/javase/tutorial/uiswing/). :) – Andrew Thompson May 28 '15 at 15:59
  • Yeah... could be better. I trusted that book for years but now it's time to burn it! In spite of having read your link under http://docs.oracle.com/javase/tutorial/uiswing/layout/index.html I can't figure out the problem... I'm a newbie! :) – Andrea Grimandi May 30 '15 at 07:29
  • *"showing them vertically as a "file name Labels + delete Buttons" list."* I'd use a `JList` or a `JTable` for showing the files, perhaps with a single `JButton` below to `Delete Selected Files`. See the [File Browser GUI](http://codereview.stackexchange.com/q/4446/7784) for how elegantly files can be represented in a Swing based `JTable` (or a `JTree`!). – Andrew Thompson May 30 '15 at 07:36
  • Thank you Andrew! Still have a question: do using components in a class (as I did) is a good practice in your opinion? – Andrea Grimandi May 31 '15 at 22:23
  • *"do using components in a class (as I did) is a good practice"* ..how else would you use them? – Andrew Thompson May 31 '15 at 22:43
  • May I write down the code all in the same "main" class but although I've a very little experience with GUI in Java, I've asked you because I also wanted to know your opinion :). Then I can continue in this way. Thank you! – Andrea Grimandi Jun 02 '15 at 13:28
  • *"May I write down the code all in the same "main" class .."* It is **possible** (in some situations) but **not recommended** for any but the most trivial applications (or an [MCVE](http://stackoverflow.com/help/mcve)). – Andrew Thompson Jun 02 '15 at 13:52
  • Finally I've used a JTable as you suggested me and just figured out how to refresh that component in [this thread](http://stackoverflow.com/questions/3549206/how-to-add-row-in-jtable). – Andrea Grimandi Jun 03 '15 at 10:05

1 Answers1

0

Finally found a solution on Andrew's suggestions.

This is my class:

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;
}

}

This is a working raw component that shows files stored into a List.

Andrea Grimandi
  • 631
  • 2
  • 8
  • 32