1

I have created an file-upload dialog with a JTable:

FileUpload

Every time the user uploads another file, the JTable adds another row with the size of the document and an icon to trigger an action for the specific row.

Since usually there is a bit of space left and right to the icon in the cell, the user does not have to click exactly on the icon, clicking the cell is sufficient to trigger the icon-action.

I fear, that my users might "click around" i.e. wanting to make the column bigger, clicking near the header and triggering the icon-action on the first document without noticing.

So, can I make only the icon clickable and not the cell itself?

My example is very similar to one that mKorbel has written, so if you want to test the code, you can use this as an MCVE:

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import javax.swing.*;
import javax.swing.table.*;

public class TableIcon extends JFrame {

    private static final long serialVersionUID = 1L;
    private JFrame frame = new JFrame ();
    private JTable table;
    private JLabel myLabel = new JLabel("waiting");
    private int pHeight = 40;
    private ImageIcon errorIcon = (ImageIcon) UIManager.getIcon("OptionPane.errorIcon");
    private ImageIcon infoIcon = (ImageIcon) UIManager.getIcon("OptionPane.informationIcon");
    private ImageIcon warnIcon = (ImageIcon) UIManager.getIcon("OptionPane.warningIcon");
    private ImageIcon questIcon = (ImageIcon) UIManager.getIcon("OptionPane.questionIcon");

    public TableIcon() {
        String[] columnNames = {"Picture", "Description"};
        Object[][] data = {{errorIcon, "About"}, {errorIcon, "Add"}, {errorIcon, "Copy"}, {errorIcon, "Copy"}};
        DefaultTableModel model = new DefaultTableModel(data, columnNames);
        table = new JTable(model) {
            private static final long serialVersionUID = 1L;

            @Override
            public Class getColumnClass(int column) {
                return getValueAt(0, column).getClass();
            }

            @Override
            public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
                Component comp = super.prepareRenderer(renderer, row, column);
                JLabel jc = (JLabel) comp;
                if (column == 0) {
                    if (isRowSelected(row) && isColumnSelected(column)) {
                        jc.setIcon(infoIcon);
                    } else if (isRowSelected(row) && !isColumnSelected(column)) {
                        jc.setIcon(warnIcon);
                    } else {
                        jc.setIcon(jc.getIcon());
                    }
                }
                return comp;
            }
        };
        table.setRowHeight(pHeight);
        table.setPreferredScrollableViewportSize(table.getPreferredSize());
        JScrollPane scrollPane = new JScrollPane(table);
        frame.add(scrollPane, BorderLayout.CENTER);
        myLabel.setPreferredSize(new Dimension(200, pHeight));
        myLabel.setHorizontalAlignment(SwingConstants.CENTER);
        frame.add(myLabel, BorderLayout.SOUTH);
        frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
        frame.setLocation(150, 150);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                TableIcon frame = new TableIcon();
            }
        }); 
    }
}

https://stackoverflow.com/a/15213473/1368690

Community
  • 1
  • 1
hamena314
  • 2,969
  • 5
  • 30
  • 57
  • 2
    The TableCellRenderer may (for that column) return a JPanel with BorderLayout and centered a button for the clicks: borderless and inset-less, with the icon. – Joop Eggen Aug 24 '16 at 11:52
  • 2
    The question that only you can answer, is, how often does a user need to delete a file. If the answer is half or more of the files are deleted, then make deleting easy. Maybe provide an undelete function for the occasional mistake. If the answer is once every 100,000 files, then make your user go through a confirmation dialog. – Gilbert Le Blanc Aug 24 '16 at 13:06
  • 1
    @GilbertLeBlanc: Your comment made me realize, that I 100% need a confirmation dialog, thanks! But the core of my question still is valid, because of the comfort for the user. Please see my edit. – hamena314 Aug 24 '16 at 13:20
  • 2
    I can offer two solutions for your problem: 1) You can add a "Remember my choice" option in notification dialog. 2) You can check whether the click is on icon. To do it - get the cell bounds where the user has clicked, and check whether the click point is in the middle part of this rectangle (+/- half of icon's height and width). Useful methods for this approach are: `JTable.rowAtPoint`, `JTable.columnAtPoint` and `JTable.getCellRect` – Sergiy Medvynskyy Aug 24 '16 at 13:27
  • 2
    The code you posted has nothing to do with deleting a row from a table. The MCVE should demonstrate your problem, not be code you copied from another question. Don't use an editor. Instead you will need to make the cell uneditable and then you need to add a MouseListener to the table as suggested by Sergiy to handle the mouse click. Also, since you are worried about the user experience you will need to add Key Bindings to the table to allow the user to delete the row using a KeyStroke. Proper GUI design allows a user to use either the mouse or keyboard to invoke a function. – camickr Aug 24 '16 at 14:59
  • @camickr: You're right, the part with deleting something seems to confuse possible answerers. I've therefore removed the delete-part and put the focus back on triggering an icon-action by not clicking exactly on the icon. This might not be expected by the user and therefore should be avoided somehow. As a nice sideeffect, I can use the code-example by mKorbel, since the behaviour of not having to exactly hit the icon is demonstrated there as well. Thanks! – hamena314 Aug 25 '16 at 12:51
  • The suggestion by Joop Eggen is best in my opinion (you probably don't even need the panel, just a button). There are many places showing how to do this. – user1803551 Aug 25 '16 at 14:15

0 Answers0