简体   繁体   中英

Set jtable column to image button, but dynamically change image on specific row/column, not all rows in column

I am trying to do the following:

Set all cells in a jtable column to image button1. When a cell in another row/column changes to a specific value, image button 1 needs to change to image2 in that row only. If rows are deleted, the column image needs to be updated accordingly because the rows shown are filtered from actual defaulttablemodel.

I have done a lot of research and tried different things. I am a java newbie and not good at table cell renderers/editors, which is why i am having so much trouble.

What is currently happening is that the function to change button gets called, but only when i click on button does it hide, and the other image doesn't even show up.

My program does this: btnRenderer = new ButtonRenderer(); btnRenderer.setButtonImagesURL(codebase.toString());

btnEditor = new ButtonEditor(table);
btnEditor.setButtonImagesURL(codebase.toString());

table.getColumnModel().getColumn(5).setCellRenderer(btnRenderer);
table.getColumnModel().getColumn(5).setCellEditor(btnEditor);

And on that specific row/column value changing, it calls: this.btnEditor.changeButtonToComplete(); Because i couldn't figure out how to make table listen to change and change the button.

Below are my renderer/editor classes.

class ButtonRenderer extends ButtonsPanel implements TableCellRenderer {
private boolean changeIconComplete = false;
ImageIcon imageComplete;

public ButtonRenderer() {
    super();
}

@Override 
public Component getTableCellRendererComponent(JTable table,
        Object value, boolean isSelected, boolean hasFocus, int row, int column) { 
    setBackground(table.getBackground());
    this.setAlignmentX(Component.CENTER_ALIGNMENT);
    this.setAlignmentY(Component.CENTER_ALIGNMENT);
    setToolTipText("Abort upload");

    return this;
}

public void setButtonImagesURL(String codebase)
{
    setButtonImages(codebase);

    URL imgURL = null;

    try {
        imgURL = new URL(codebase + "/img/uploadComplete.png");
    } catch (MalformedURLException e) {
        e.printStackTrace();
    }
    imageComplete = new ImageIcon(imgURL);
}
}


public class ButtonEditor extends ButtonsPanel implements TableCellEditor {
Service cloudService;
FileUploader fileUP;
DefaultTableModel model;
int currRow;
int currentlyUploadingRow;

public ButtonEditor(final JTable table) {
    super();

    MouseListener ml = new MouseAdapter() {
        public void mousePressed(MouseEvent e) {
        }
    };

    buttons.get(0).addMouseListener(ml);

    buttons.get(0).addActionListener(new ActionListener() {
        @Override 
        public void actionPerformed(ActionEvent e) {
            if (currRow == currentlyUploadingRow) {
                // Cancel current uploading
                fileUP.setCancelled();
                cloudService.setCancelled();
            } else {
                // Set status to abort
                if (model.getRowCount() == 0 || currRow == -1)
                    return;
                if (model.getValueAt(currRow, 5).toString().contentEquals("Queued") && 
                        (Boolean)model.getValueAt(currRow, 7) == false) {
                    model.setValueAt("Aborted", currRow, 5);
                }
            }
        }
    });


    addMouseListener(new MouseAdapter() {
        @Override 
        public void mousePressed(MouseEvent e) {
        }
    });
}

public void setButtonImagesURL(String codebase)
{
    setButtonImages(codebase);
    createCompletedButton(codebase);
}


public void changeButtonToComplete()
{
    changeAbortToComplete();
}

@Override 
public Component getTableCellEditorComponent(JTable table, Object value, 
        boolean isSelected, int row, int column) {
    //Get table model equivalent of row
    String filename = table.getValueAt(row, 1).toString() + table.getValueAt(row, 0).toString();
    this.currRow = getRowIndexByFilename(filename);
    this.setBackground(table.getBackground());

    return this;
}

private int getRowIndexByFilename(String filename) 
{
    String name;
    for (int row = 0; row < model.getRowCount(); row++) {
        name = model.getValueAt(row, 1).toString() + model.getValueAt(row, 0).toString();
        if (filename.contentEquals(name) && 
                !model.getValueAt(row, 5).toString().contentEquals("Complete") &&
                !model.getValueAt(row, 5).toString().contains("Invalid") &&
                !model.getValueAt(row, 5).toString().contains("Error") &&
                !model.getValueAt(row, 5).toString().contains("Abort"))
            return row;
    }

    return -1;
}

private int getRowIndexByFilenameComplete(String filename) 
{
    String name;
    for (int row = 0; row < model.getRowCount(); row++) {
        name = model.getValueAt(row, 1).toString() + model.getValueAt(row, 0).toString();
        if (filename.contentEquals(name) && 
                model.getValueAt(row, 5).toString().contentEquals("Complete") ||
                model.getValueAt(row, 5).toString().contains("Invalid") ||
                model.getValueAt(row, 5).toString().contains("Error") ||
                model.getValueAt(row, 5).toString().contains("Abort"))
            return row;
    }

    return -1;
}


//  @Override 
public Object getCellEditorValue() {
    return "";
}

@Override 
public boolean isCellEditable(java.util.EventObject e) {
    return true;
}
}


public class ButtonsPanel extends JPanel {

public final java.util.List<JButton> buttons = Arrays.asList(new JButton(), new JButton());
public final JButton btnComplete = new JButton();
private ImageIcon[] images = new ImageIcon[2];

public ButtonsPanel() {
    super();
    setOpaque(false);
    this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
    this.setBorder(new javax.swing.border.EmptyBorder(-5, -5, -5, -5));
}

public void setButtonImages(String codebase)
{
    java.util.List<String> imgPaths = Arrays.asList("abortUpload.png", "/img/uploadComplete.png");
    URL imgURL = null;
    int ii = 0;

    for (String path: imgPaths) {
        try {
            imgURL = new URL(codebase + "/img/" + path);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        images[ii] = new ImageIcon(imgURL);
        images[ii].setDescription(path);
        ii++;
    }

    ii = 0;
    for (JButton b: buttons) {
        b.setFocusable(false);
        b.setRolloverEnabled(false);
        b.setIcon(images[ii]);
        b.setBorderPainted(false);
        b.setAlignmentX(Component.CENTER_ALIGNMENT);
        b.setMargin(new Insets(0,0,0,0));
        add(b);
        if (ii == 1)
            this.getComponent(1).hide();
        ii++;
    }
}

public void changeAbortToComplete()
{
    this.getComponent(0).hide();
    this.getComponent(1).show();

}

}

I'm maybe misinterpreting your question. But seems that it is easier to rely on established concept of table-model-renderer, rather than manually tracking changes and invoking updates.

Try to manage the state in a model. Design a renderer to check object's state and act act accordingly. Then, as a result of a change in the model, the table is notified and repainted. And the renderer is triggered to present an updated data.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM