/* *------------------------------------------------------------------------------ * Copyright (C) 2014-2015 University of Dundee. All rights reserved. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *------------------------------------------------------------------------------ */ package org.openmicroscopy.shoola.agents.dataBrowser.view; import java.awt.Component; import java.awt.FlowLayout; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.Date; import java.util.EventObject; import java.util.List; import javax.swing.Icon; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTable; import javax.swing.ListSelectionModel; import javax.swing.SwingUtilities; import javax.swing.event.CellEditorListener; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.TableCellEditor; import javax.swing.table.TableCellRenderer; import org.jdesktop.swingx.JXTable; import org.openmicroscopy.shoola.agents.dataBrowser.DataBrowserAgent; import org.openmicroscopy.shoola.agents.events.iviewer.ViewImage; import org.openmicroscopy.shoola.agents.events.iviewer.ViewImageObject; import org.openmicroscopy.shoola.agents.imviewer.ImViewerAgent; import omero.gateway.SecurityContext; import org.openmicroscopy.shoola.env.event.RequestEvent; import org.openmicroscopy.shoola.env.ui.UserNotifier; import org.openmicroscopy.shoola.util.ui.UIUtilities; import omero.gateway.model.DataObject; import omero.gateway.model.ImageData; /** * A table for displaying a search result. * * @author Dominik Lindner      <a * href="mailto:d.lindner@dundee.ac.uk">d.lindner@dundee.ac.uk</a> * * @since 5.0 */ public class SearchResultTable extends JXTable { /** Reference to the DataBrowserModel */ private AdvancedResultSearchModel model; /** Holds the DataObjects shown in the table */ private List<DataObject> data; /** A reference to the component holding this table */ private SearchResultView parent; /** * Creates a new instance * * @param parent Reference to the view. * @param data The data to display * @param browserModel The model. */ public SearchResultTable(SearchResultView parent, List<DataObject> data, AdvancedResultSearchModel browserModel) { this.parent = parent; this.data = data; this.model = browserModel; this.model.registerTable(this); initTable(); } /** * Initializes the table; i.e. creates/sets the cell renderers, etc. */ public void initTable() { TableCellRenderer defaultRenderer = new MyRenderer(); setDefaultRenderer(DataObject.class, defaultRenderer); setDefaultRenderer(String.class, defaultRenderer); setDefaultRenderer(Icon.class, defaultRenderer); setDefaultEditor(DataObject.class, new DataObjectEditor()); setBackground(UIUtilities.BACKGROUND_COLOR); setRowHeight(42); // disable column dragging: getTableHeader().setReorderingAllowed(false); getSelectionModel().setSelectionMode( ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); getSelectionModel().addListSelectionListener( new ListSelectionListener() { @Override public void valueChanged(ListSelectionEvent e) { List<DataObject> selectedObjs = getSelectedObjects(); if (!selectedObjs.isEmpty()) { if (!isSelectionValid(selectedObjs)) { UserNotifier un = DataBrowserAgent .getRegistry().getUserNotifier(); un.notifyInfo("Invalid Selection", "A selection of items of different groups is not supported."); getSelectionModel().clearSelection(); return; } parent.fireSelectionEvent(selectedObjs); } } /** * Returns <code>true</code> if all {@link DataObject}s in * selectedObjs belong to the same group; <code>false</code> * otherwise. * * @param selectedObjs * @return */ boolean isSelectionValid(List<DataObject> selectedObjs) { long groupId = -1; for (DataObject obj : selectedObjs) { if (groupId == -1) { groupId = obj.getGroupId(); } else if (groupId != obj.getGroupId()) return false; } return true; } }); addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { e = SwingUtilities.convertMouseEvent((Component) e.getSource(), e, SearchResultTable.this); Point p = e.getPoint(); if (e.getButton() == 3) { parent.firePopupEvent(p); } } }); } /** * Get the current selected DataObjects */ public List<DataObject> getSelectedObjects() { List<DataObject> selectedObjs = new ArrayList<DataObject>(); for (int row : getSelectedRows()) { row = convertRowIndexToModel(row); DataObject obj = (DataObject) getModel().getValueAt(row, SearchResultTableModel.VIEWBUTTON_COLUMN_INDEX); if (obj != null) { selectedObjs.add(obj); } } return selectedObjs; } /** * Constructs a new TableModel on basis of the underlying search results */ public void refreshTable() { setModel(new SearchResultTableModel(this, data, model)); getColumnExt(SearchResultTableModel.VIEWBUTTON_COLUMN_INDEX) .setSortable(false); int wI = 80; int wB = 140; getColumn(0).setMinWidth(wI); getColumn(0).setMaxWidth(wI); getColumn(0).setPreferredWidth(wI); getColumn(0).setWidth(wI); getColumn(4).setMinWidth(wB); getColumn(4).setMaxWidth(wB); getColumn(4).setPreferredWidth(wB); getColumn(4).setWidth(wB); } private JButton createActionButton(final DataObject obj) { JButton button = null; if (obj instanceof ImageData) { button = new JButton("View"); button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { ImageData img = (ImageData) obj; RequestEvent ev = new ViewImage(new SecurityContext(obj .getGroupId()), new ViewImageObject(img), null); ImViewerAgent.getRegistry().getEventBus().post(ev); } }); } else { // TODO: Have to remove the Browse Button for now; first it must // be ensured that DataObjectSelectionEvent are handled properly, // i. e. they also can navigate to nodes which are not yet already // visible/expanded. // button = new JButton("Browse"); // button.addActionListener(new ActionListener() { // // @Override // public void actionPerformed(ActionEvent arg0) { // DataObjectSelectionEvent event = // new DataObjectSelectionEvent(obj.getClass(), obj.getId()); // event.setSelectTab(true); // EventBus bus = MetadataViewerAgent.getRegistry().getEventBus(); // bus.post(event); // } // }); } return button; } /** * A custom renderer which shows a JLabel, Icon or Button depending on the * Object it gets */ class MyRenderer extends DefaultTableCellRenderer { @Override public Component getTableCellRendererComponent(JTable table, final Object value, boolean isSelected, boolean hasFocus, int row, int column) { JPanel p = new JPanel(); if (isSelected) p.setBackground(UIUtilities.SELECTED_BACKGROUND_COLOUR); else p.setBackground(row % 2 == 0 ? UIUtilities.BACKGROUND_COLOUR_EVEN : UIUtilities.BACKGROUND_COLOUR_ODD); if (value==null) { JLabel l = new JLabel("--"); p.add(l); } else if (value instanceof DataObject) { final DataObject dataObj = (DataObject) value; JButton b = createActionButton(dataObj); if (b != null) p.add(b); } else if (value instanceof Icon) { JLabel l = new JLabel((Icon) value); p.add(l); } else if (value instanceof Date) { JLabel l = new JLabel(UIUtilities.formatDefaultDate(((Date)value))); p.add(l); } else { String s = value.toString(); if (s.matches(".*\\<.*\\>.*")) { s = "<html>" + s + "</html>"; } JLabel l = new JLabel(s); p.add(l); if (column == 1) p.setLayout(new FlowLayout(FlowLayout.LEFT)); } return p; } } /** * The editor which shows the View button for the last column */ class DataObjectEditor implements TableCellEditor { public DataObjectEditor() { } @Override public void addCellEditorListener(CellEditorListener arg0) { } @Override public void cancelCellEditing() { } @Override public Object getCellEditorValue() { return null; } @Override public boolean isCellEditable(EventObject arg0) { return true; } @Override public void removeCellEditorListener(CellEditorListener arg0) { } @Override public boolean shouldSelectCell(EventObject arg0) { return true; } @Override public boolean stopCellEditing() { return true; } @Override public Component getTableCellEditorComponent(JTable arg0, final Object arg1, boolean arg2, int arg3, int arg4) { JPanel p = new JPanel(); if (arg2) p.setBackground(UIUtilities.SELECTED_BACKGROUND_COLOUR); else p.setBackground(arg3 % 2 == 0 ? UIUtilities.BACKGROUND_COLOUR_EVEN : UIUtilities.BACKGROUND_COLOUR_ODD); final DataObject dataObj = (DataObject) arg1; JButton b = createActionButton(dataObj); if (b != null) p.add(b); return p; } } }