4

I am making a hospital project in Java, I have made a JTable which is fetching Hospital Name and a Hospital image link i.e "Click to see more" from SQL database. My problem is that the data is successfully fetched from database to the table, but I can't click the link which is in the table cell.

How to make the link active?

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Rahul
  • 51
  • 1
  • 1
  • 8
  • 1
    Is the problem detecting the click, determining the link that was clicked, or doing something with the link once known? What have you tried, where did you get stuck? – Andrew Thompson Aug 11 '12 at 07:16

4 Answers4

8

Consider using JXTable (a class of SwingX): it supports a hyperlink renderer which can be configured to do any action, based on the cell value

JXTable table = new JXTable(myModel);
AbstractHyperlinkAction<Object> simpleAction = new AbstractHyperlinkAction<Object>(null) {

    public void actionPerformed(ActionEvent e) {
        // here goes what you want to do on activating the hyperlink
        //LOG.info("hit: " + getTarget());
    }

};
TableCellRenderer renderer = new DefaultTableRenderer(
    new HyperlinkProvider(simpleAction));
table.getColumnExt(0).setEditable(false);
table.getColumnExt(0).setCellRenderer(renderer);
kleopatra
  • 51,061
  • 28
  • 99
  • 211
6

You can either make a TableCellEditor whose isCellEditable method could be used to activate on a single mouse click. Frankly, this just get messy.

Or, you could attach a MouseListener to the table directly and monitor for the mouseClicked event.

On the clicked event, you could need to getSelectedColumn and getSelectedRow to determine if they've clicked on the column you want and get the link value from the selected cell, using getValueAt

You'll need to take into consideration that the table may be sorted or the columns are no longer in the order you started them in (the user may have moved them).

Then you'll need convertColumnIndexToView and convertRowIndexToModel

Simple :D

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
4

I think that avoiding an external library is a better way to go as MadProgrammer suggests, but I guess swingx is still pure java. Anyway, I would use the mouseClicked listener and then open uri in the way described in this question How to add hyperlink in JLabel.

JTable table = new JTable();

table.addMouseListener(new MouseAdapter() {
  public void mouseClicked(MouseEvent e) {

        int row = table.getSelectedRow();
        int col = table.getSelectedColumn();

        //build your address / link

        URI uri = new URI("http: your link here");

        //see below
        open(uri);
      }
    });

//Then elsewhere as from the McDowell answer
private static void open(URI uri) {
  if (Desktop.isDesktopSupported()) {
    try {
       Desktop.getDesktop().browse(uri);
      } catch (IOException e) { /* TODO: error handling */ }
   } else { /* TODO: error handling */ }
 }
Community
  • 1
  • 1
pbible
  • 1,259
  • 1
  • 18
  • 34
0

I solved adding a button inside the cells clickable, I followed this tutorial Table Button Column from Rob Camick:

String[] columnNames = {"First Name", "Last Name", ""};
Object[][] data =
{
    {"Homer", "Simpson", "delete Homer"},
    {"Madge", "Simpson", "delete Madge"},
    {"Bart",  "Simpson", "delete Bart"},
    {"Lisa",  "Simpson", "delete Lisa"},
};

DefaultTableModel model = new DefaultTableModel(data, columnNames);
JTable table = new JTable( model );

Then:

Action delete = new AbstractAction()
{
    public void actionPerformed(ActionEvent e)
    {
        JTable table = (JTable)e.getSource();
        int modelRow = Integer.valueOf( e.getActionCommand() );
        ((DefaultTableModel)table.getModel()).removeRow(modelRow);
    }
};

ButtonColumn buttonColumn = new ButtonColumn(table, delete, 2);
buttonColumn.setMnemonic(KeyEvent.VK_D);

Where ButtonColumn class is:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.table.*;

/**
 *  The ButtonColumn class provides a renderer and an editor that looks like a
 *  JButton. The renderer and editor will then be used for a specified column
 *  in the table. The TableModel will contain the String to be displayed on
 *  the button.
 *
 *  The button can be invoked by a mouse click or by pressing the space bar
 *  when the cell has focus. Optionally a mnemonic can be set to invoke the
 *  button. When the button is invoked the provided Action is invoked. The
 *  source of the Action will be the table. The action command will contain
 *  the model row number of the button that was clicked.
 *
 */
public class ButtonColumn extends AbstractCellEditor
    implements TableCellRenderer, TableCellEditor, ActionListener, MouseListener
{
    private JTable table;
    private Action action;
    private int mnemonic;
    private Border originalBorder;
    private Border focusBorder;

    private JButton renderButton;
    private JButton editButton;
    private Object editorValue;
    private boolean isButtonColumnEditor;

    /**
     *  Create the ButtonColumn to be used as a renderer and editor. The
     *  renderer and editor will automatically be installed on the TableColumn
     *  of the specified column.
     *
     *  @param table the table containing the button renderer/editor
     *  @param action the Action to be invoked when the button is invoked
     *  @param column the column to which the button renderer/editor is added
     */
    public ButtonColumn(JTable table, Action action, int column)
    {
        this.table = table;
        this.action = action;

        renderButton = new JButton();
        editButton = new JButton();
        editButton.setFocusPainted( false );
        editButton.addActionListener( this );
        originalBorder = editButton.getBorder();
        setFocusBorder( new LineBorder(Color.BLUE) );

        TableColumnModel columnModel = table.getColumnModel();
        columnModel.getColumn(column).setCellRenderer( this );
        columnModel.getColumn(column).setCellEditor( this );
        table.addMouseListener( this );
    }


    /**
     *  Get foreground color of the button when the cell has focus
     *
     *  @return the foreground color
     */
    public Border getFocusBorder()
    {
        return focusBorder;
    }

    /**
     *  The foreground color of the button when the cell has focus
     *
     *  @param focusBorder the foreground color
     */
    public void setFocusBorder(Border focusBorder)
    {
        this.focusBorder = focusBorder;
        editButton.setBorder( focusBorder );
    }

    public int getMnemonic()
    {
        return mnemonic;
    }

    /**
     *  The mnemonic to activate the button when the cell has focus
     *
     *  @param mnemonic the mnemonic
     */
    public void setMnemonic(int mnemonic)
    {
        this.mnemonic = mnemonic;
        renderButton.setMnemonic(mnemonic);
        editButton.setMnemonic(mnemonic);
    }

    @Override
    public Component getTableCellEditorComponent(
        JTable table, Object value, boolean isSelected, int row, int column)
    {
        if (value == null)
        {
            editButton.setText( "" );
            editButton.setIcon( null );
        }
        else if (value instanceof Icon)
        {
            editButton.setText( "" );
            editButton.setIcon( (Icon)value );
        }
        else
        {
            editButton.setText( value.toString() );
            editButton.setIcon( null );
        }

        this.editorValue = value;
        return editButton;
    }

    @Override
    public Object getCellEditorValue()
    {
        return editorValue;
    }

//
//  Implement TableCellRenderer interface
//
    public Component getTableCellRendererComponent(
        JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
    {
        if (isSelected)
        {
            renderButton.setForeground(table.getSelectionForeground());
            renderButton.setBackground(table.getSelectionBackground());
        }
        else
        {
            renderButton.setForeground(table.getForeground());
            renderButton.setBackground(UIManager.getColor("Button.background"));
        }

        if (hasFocus)
        {
            renderButton.setBorder( focusBorder );
        }
        else
        {
            renderButton.setBorder( originalBorder );
        }

//      renderButton.setText( (value == null) ? "" : value.toString() );
        if (value == null)
        {
            renderButton.setText( "" );
            renderButton.setIcon( null );
        }
        else if (value instanceof Icon)
        {
            renderButton.setText( "" );
            renderButton.setIcon( (Icon)value );
        }
        else
        {
            renderButton.setText( value.toString() );
            renderButton.setIcon( null );
        }

        return renderButton;
    }

//
//  Implement ActionListener interface
//
    /*
     *  The button has been pressed. Stop editing and invoke the custom Action
     */
    public void actionPerformed(ActionEvent e)
    {
        int row = table.convertRowIndexToModel( table.getEditingRow() );
        fireEditingStopped();

        //  Invoke the Action

        ActionEvent event = new ActionEvent(
            table,
            ActionEvent.ACTION_PERFORMED,
            "" + row);
        action.actionPerformed(event);
    }

//
//  Implement MouseListener interface
//
    /*
     *  When the mouse is pressed the editor is invoked. If you then then drag
     *  the mouse to another cell before releasing it, the editor is still
     *  active. Make sure editing is stopped when the mouse is released.
     */
    public void mousePressed(MouseEvent e)
    {
        if (table.isEditing()
        &&  table.getCellEditor() == this)
            isButtonColumnEditor = true;
    }

    public void mouseReleased(MouseEvent e)
    {
        if (isButtonColumnEditor
        &&  table.isEditing())
            table.getCellEditor().stopCellEditing();

        isButtonColumnEditor = false;
    }

    public void mouseClicked(MouseEvent e) {}
    public void mouseEntered(MouseEvent e) {}
    public void mouseExited(MouseEvent e) {}
}
madx
  • 6,723
  • 4
  • 55
  • 59