package net.trevize.galatee; import java.awt.AWTEvent; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Point; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ComponentEvent; import java.awt.event.ComponentListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseWheelEvent; import java.awt.event.MouseWheelListener; import java.awt.image.BufferedImage; import java.net.URI; import java.net.URL; import java.util.HashMap; import java.util.Vector; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.DefaultListSelectionModel; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.KeyStroke; import javax.swing.ListSelectionModel; import javax.swing.SwingUtilities; import javax.swing.border.EmptyBorder; import javax.swing.border.LineBorder; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.table.TableColumn; /** * * * @author Nicolas James <nicolas.james@gmail.com> [[http://njames.trevize.net]] Galatee.java - Apr * 23, 2009 * * Might fix this sometime... * http://www.objectdefinitions.com/odblog/2011/how-to-fix-right-click-selection-and-jpopupmenu-so-your-jtree-feels-native/ * protected void setSelectedItemsOnPopupTrigger(MouseEvent e) { int row = * table.rowAtPoint(e.getPoint()); boolean selected = * table.getSelectionModel().isSelectedIndex(row); if ( ! selected ) { * table.getSelectionModel().setSelectionInterval(row, row); } } * @author Grant B. Harris 2013 */ public class Galatee extends JPanel implements ListSelectionListener, MouseListener, ComponentListener, KeyListener { private JTable table; private _TableModel model; private _TableCellRenderer renderer; private _TableCellEditor editor; private Vector<GItem> gitems; private int nbcol; private int selectedrow, selectedcol; private ImageLoaderThread ilt; public static BufferedImage imageLoadingError; private Vector<URI> v_uri; private Vector<Vector<Object>> data; private EventQueue eq; private Vector<GListener> listeners; private JScrollPane sp; //if customized imageLoadingError. (not used by default). private String imageLoadingErrorPath = "./gfx/imageLoadingError.jpg"; //if customized imageLoadingError and application packed in an executable JAR. private URL imageLoadingErrorUrl = getClass().getClassLoader().getResource( imageLoadingErrorPath); //default value for the image thumbnail dimension. private Dimension gitemImageDimension = new Dimension(GalateeProperties .getImage_width(), GalateeProperties .getImage_height()); //default value for the text description width. private int gitemDescriptionWidth = GalateeProperties .getDescription_width(); private HashMap<String, URI> uri_index; //private SearchPanel search_panel; private boolean keep_selected_cell_visible; private JPopupMenu popup_menu = new JPopupMenu(); private boolean description_visible; public PreferencesDialog preferences_dialog; private final boolean equalizeHisto; public Galatee(Vector<URI> v_uri, Vector<Vector<Object>> data, Dimension imagesDim, int descriptionWidth, int nbcol) { this(v_uri, data, imagesDim, descriptionWidth, nbcol, true, false); } public Galatee(Vector<URI> v_uri, Vector<Vector<Object>> data, Dimension imagesDim, int descriptionWidth, int nbcol, boolean showDescription, boolean equalizeHisto) { super(); /* * If using a customized image for the imageLoadingError, use the following code. * However, this class is primarily coded to be used from a packed .jar, * (a library), and accessing images in this case is tricky, so * it's better to not use a real image and rather a built image in * java, see the net.trevize.ImageLoadingError class. */ //to lauch directly (not from an executable jar). /* try { imageLoadingError = ImageIO.read(new File(imageLoadingErrorPath)); } catch (IOException e) { e.printStackTrace(); } */ //for launching from an executable jar. /* try { imageLoadingError = ImageIO.read(imageLoadingErrorUrl); } catch (IOException e) { e.printStackTrace(); } */ /* * if build a BufferedImage for the imageLoadingError. */ imageLoadingError = ImageLoadingError.getImageLoadingError(imagesDim); this.v_uri = v_uri; this.data = data; this.equalizeHisto = equalizeHisto; gitemImageDimension = imagesDim; gitemDescriptionWidth = descriptionWidth; setNumberOfColumns(nbcol); setLayout(new BorderLayout()); setBorder(new EmptyBorder(0, 0, 0, 0)); //setting the jtable. table = new JTable(); model = new _TableModel(); // filling the model. gitems = new Vector<GItem>(); fillModel(); //setting the model. table.setModel(model); //setting the renderer and the editor. renderer = new _TableCellRenderer(this, gitemImageDimension, gitemDescriptionWidth); editor = new _TableCellEditor(this, gitemImageDimension, gitemDescriptionWidth); table.setTableHeader(null); //no table header. table.setCellSelectionEnabled(true); //authorize cell selection. // table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); table.setDragEnabled(false); //dragging GItem is not authorized. /* * When the setShowGrid(false) is noticed, the pixels reserved for the grid is still displayed, * but not colored with the grid's color, these pixels are actually pixels of the JTable's background. * * Furthermore, the completely surprising thing is the way used to paint the grid: each vertical line of * the grid is a rigth-border of a column, i.e. there are pixels reserved for the grid at the last right column, * it's very ugly... * * The solution to not have a ugly pixel after the last column is to put the intercellspacing to zero. */ table.setShowGrid(false); table.setIntercellSpacing(new Dimension(0, 0)); table.setRowHeight(renderer.getItemHeight()); table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); // at starting time there is any selected cells. selectedrow = selectedcol = -1; // setting the selection model and the selection mode table.setSelectionModel(new DefaultListSelectionModel()); table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); table.getColumnModel().setSelectionModel(new DefaultListSelectionModel()); table.getColumnModel().getSelectionModel(). setSelectionMode(ListSelectionModel.SINGLE_SELECTION); //setting the JTable's listeners. table.getSelectionModel().addListSelectionListener(this); table.getColumnModel().getSelectionModel().addListSelectionListener(this); table.addMouseListener(this); // setRenderOfColumns(); // // authorize the creation of events. enableEvents(GEvent.GALATEE_EVENT); eq = Toolkit.getDefaultToolkit().getSystemEventQueue(); listeners = new Vector<GListener>(); //creating and starting the ImageLoaderThread. ilt = new ImageLoaderThread(this, gitemImageDimension.width, gitemImageDimension.height); ilt.start(); //and the JTable in a JScrollPane, and the JScrollPane into this. sp = new JScrollPane(table); sp.setBorder(new LineBorder(null, 0)); sp.setViewportView(table); sp.getVerticalScrollBar().setUnitIncrement( GalateeProperties.getVertical_scrollbar_unit_increment()); sp.getHorizontalScrollBar().setUnitIncrement( GalateeProperties.getHorizontal_scrollbar_unit_increment()); add(sp, BorderLayout.CENTER); mapKeys(); sp.addComponentListener(this); addScrollpaneMouseListeners(sp); // popup_menu = new JPopupMenu(); // popup_menu.setBorder(new MatteBorder(0, 15, 0, 0, Color.BLUE)); setDescriptionVisible(showDescription); preferences_dialog = new PreferencesDialog(this); } // constructor public void setNumberOfColumns(int numColumns) { /* :!: WARNING :!: * the indicated nbcol given in parameter to the constructor * is not respected if it is greater than the number of results. */ if (v_uri.size() < numColumns) { this.nbcol = v_uri.size(); if(this.nbcol < 1) this.nbcol = 1; } else { this.nbcol = numColumns; } } public void setRenderOfColumns() { for (int i = 0; i < nbcol; ++i) { TableColumn c = table.getColumnModel().getColumn(i); c.setCellRenderer(renderer); c.setCellEditor(editor); c.setPreferredWidth(renderer.getItemWidth()); c.setWidth(renderer.getItemWidth()); } } public boolean isEqualizeHisto() { return equalizeHisto; } public void enableSearchFunctionality() { } public JTable getTable() { return table; } public void updateGItemDimension(Dimension gitemImageDimension, int description_width) { this.gitemImageDimension = gitemImageDimension; //update the renderer and the editor. if (description_visible) { renderer.updateDimension(gitemImageDimension, description_width); editor.updateDimension(gitemImageDimension, description_width); } else { renderer.updateDimension(gitemImageDimension, 0); editor.updateDimension(gitemImageDimension, 0); } //update the image loader thread. ilt.setImageWidth(gitemImageDimension.width); ilt.setImageHeight(gitemImageDimension.height); //erase the list of ever loaded images. for (GItem gitem : gitems) { gitem.setImage(null); } } public ImageLoaderThread getImageLoaderThread() { return ilt; } public boolean isKeep_selected_cell_visible() { return keep_selected_cell_visible; } public void setKeep_selected_cell_visible(boolean keepSelectedCellVisible) { keep_selected_cell_visible = keepSelectedCellVisible; } private void fillModel() { //create columns in the JTable model. for (int i = 0; i < nbcol; ++i) { model.addColumn(new Vector<GItem>()); } //use a local model, affect it to the JTable later. Vector<Vector<GItem>> columns = new Vector<Vector<GItem>>(); for (int i = 0; i < nbcol; ++i) { columns.add(new Vector<GItem>()); } for (int i = 0; i < v_uri.size(); ++i) { //loading the GItem. GItem gi = new GItem(v_uri.get(i)); if (data != null) { //setting the data. gi.setData(data.get(i)); // Set the description. <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< String desc = data.get(i).get(0).toString(); // >>>>>>>>>>>>>>>>>>>>>>> gi.setText(desc); } gitems.add(gi); //add the GItem in the model. columns.get(i % nbcol).add(gi); } //setting the JTable model with our local model. for (int i = 0; i < nbcol; ++i) { model.setColumn(i, columns.get(i)); } Runtime.getRuntime().gc(); } //Change # columns... private void changeModelAddColumn() { /* * we add the following condition for not adding an invisible * column, i.e. not adding a column if we have no data to * put in it. */ if (nbcol == v_uri.size()) { return; } //save the previous nbcol for updating the selectedrow and selectedcol //in the new model. int prev_nbcol = nbcol; int prev_selectedrow = table.getSelectedRow(); int prev_selectedcol = table.getSelectedColumn(); //adding a column to the JTable model. model.addColumn(new Vector<GItem>()); //update the nbcol variable. nbcol++; //clearing the model content. ((Vector<Vector<GItem>>) model.getDataVector()).clear(); //using a local model, affect it to the JTable later. Vector<Vector<GItem>> columns = new Vector<Vector<GItem>>(); for (int i = 0; i < nbcol; ++i) { columns.add(new Vector<GItem>()); } //insert data in the model. for (int i = 0; i < v_uri.size(); ++i) { GItem gi = gitems.get(i); columns.get(i % nbcol).add(gi); } //affect the model to the JTable model. for (int i = 0; i < nbcol; ++i) { model.setColumn(i, columns.get(i)); } setRenderOfColumns(); model.fireTableDataChanged(); Runtime.getRuntime().gc(); //updating the selectedrow and selectedcol. if (prev_selectedrow != -1 && prev_selectedcol != -1) { int n = prev_selectedcol + prev_nbcol * prev_selectedrow; table.changeSelection(n / nbcol, n % nbcol, false, false); } } private void changeModelRemoveColumn() { //we can't remove all columns. if (nbcol == 1) { return; } //save the previous nbcol for updating the selectedrow and selectedcol //in the new model. int prev_nbcol = nbcol; int prev_selectedrow = table.getSelectedRow(); int prev_selectedcol = table.getSelectedColumn(); //remove a column to the JTable model. table.removeColumn(table.getColumnModel().getColumn(nbcol - 1)); //update the nbcol variable. nbcol--; //clearing the model content. ((Vector<Vector<GItem>>) model.getDataVector()).clear(); //it's mandatory to remove also the column id. Vector v = new Vector(); for (int i = 0; i < nbcol; ++i) { v.add(model.getColumnName(i)); } model.setDataVector(((Vector<Vector<GItem>>) model.getDataVector()), v); //using a local model, affect it to the JTable later. Vector<Vector<GItem>> columns = new Vector<Vector<GItem>>(); for (int i = 0; i < nbcol; ++i) { columns.add(new Vector<GItem>()); } //insert data in the model. for (int i = 0; i < v_uri.size(); ++i) { GItem gi = gitems.get(i); columns.get(i % nbcol).add(gi); } //affect the model to the JTable model. for (int i = 0; i < nbcol; ++i) { model.setColumn(i, columns.get(i)); } setRenderOfColumns(); model.fireTableDataChanged(); Runtime.getRuntime().gc(); //updating the selectedrow and selectedcol. if (prev_selectedrow != -1 && prev_selectedcol != -1) { int n = prev_selectedcol + prev_nbcol * prev_selectedrow; table.changeSelection(n / nbcol, n % nbcol, false, false); } } // ++ GBH -------------------------------------------------------------------- public void setView(int numcolumns, boolean showDescription) { //save the previous nbcol for updating the selectedrow and selectedcol //in the new model. int prev_nbcol = nbcol; int prev_selectedrow = table.getSelectedRow(); int prev_selectedcol = table.getSelectedColumn(); setNumberOfColumns(numcolumns); model = new _TableModel(); fillModel(); table.setModel(model); setRenderOfColumns(); model.fireTableDataChanged(); Runtime.getRuntime().gc(); //updating the selectedrow and selectedcol. if (prev_selectedrow != -1 && prev_selectedcol != -1) { int n = prev_selectedcol + prev_nbcol * prev_selectedrow; table.changeSelection(n / nbcol, n % nbcol, false, false); } setDescriptionVisible(showDescription); } //------------------------------------------------------------------ public void scrollToItem(String item_uri_value) { int item_number = v_uri.indexOf(uri_index.get(item_uri_value)); scrollToItem(item_number); } public void scrollToItem(int item_number) { keep_selected_cell_visible = true; int r = item_number / nbcol; int c = item_number % nbcol; /* * THE NEXT LINES ARE A TEMPORARY SOLUTION, THE TRICK WILL NOT WORK ON SLOW CPUs AND HUGE IMAGES. * we push the gitem that contains the image on which we want to scroll, * and we wait some milliseconds for the ImageLoaderThread. */ ilt.pushItem((GItem) table.getValueAt(r, c)); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } table.changeSelection(r, c, false, false); } /** * ************************************************************************* * Managing GalateeListener. * ************************************************************************ */ /** * for adding listener to the Galatee * * @param listener */ public void addGalateeListener(GListener listener) { listeners.add(listener); } /** * this method is mandatory for event/listening mechanisms */ @Override public void processEvent(AWTEvent e) { if (e instanceof GEvent) { GEvent gevent = (GEvent) e; if (gevent.getType().equals(GEvent.E_ITEM_DOUBLECLICKED)) { for (GListener l : listeners) { l.itemDoubleClicked((GEvent) e); } } else if (gevent.getType().equals(GEvent.E_SELECTION_CHANGED)) { for (GListener l : listeners) { l.selectionChanged((GEvent) e); } } } } // public void setPopup_menu(JPopupMenu jPopupMenu) { this.popup_menu = jPopupMenu; } public JPopupMenu getPopup_menu() { return popup_menu; } /** * ************************************************************************* * implementation of MouseListener. * ************************************************************************ */ @Override public void mouseClicked(MouseEvent e) { if (e.getButton() == MouseEvent.BUTTON1) { Point p = e.getPoint(); if (p != null) { int r = table.rowAtPoint(p); int c = table.columnAtPoint(p); GItem gitem = (GItem) table.getModel().getValueAt(r, c); if (gitem != null) { //managing the double click. if (e.getClickCount() > 1) { //updating the focused cell and the selected cells. table.setRowSelectionInterval(r, r); table.setColumnSelectionInterval(c, c); eq.postEvent(new GEvent(GEvent.E_ITEM_DOUBLECLICKED, this, (GItem) model.getValueAt(table .getSelectedRow(), table .getSelectedColumn()))); } else { // single click } }//end the cell is not empty. }//end the point is in the JTable. }//end if MouseEvent.BUTTON1 } @Override public void mouseEntered(MouseEvent e) { } @Override public void mouseExited(MouseEvent e) { } @Override public void mousePressed(MouseEvent e) { keep_selected_cell_visible = false; if (e.getButton() == MouseEvent.BUTTON1) { popup_menu.setVisible(false); } else if (e.getButton() == MouseEvent.BUTTON3) { //we select the item under the mouse pointer like for a MouseEvent.BUTTON1 Point p = e.getPoint(); if (p != null) { int r = table.rowAtPoint(p); int c = table.columnAtPoint(p); GItem gitem = (GItem) table.getModel().getValueAt(r, c); if (gitem != null) { //updating the focused cell and the selected cells. table.setRowSelectionInterval(r, r); table.setColumnSelectionInterval(c, c); eq.postEvent(new GEvent(GEvent.E_SELECTION_CHANGED, this, (GItem) model.getValueAt(table.getSelectedRow(), table.getSelectedColumn()))); }//end the cell is not empty. }//end the point is in the JTable. //we display the JPopupMenu. if (popup_menu == null) { return; } popup_menu.show(table, e.getX(), e.getY()); } } @Override public void mouseReleased(MouseEvent e) { } /** * ************************************************************************* * keystrokes actions. *********************************************************************** */ private void addScrollpaneMouseListeners(JScrollPane sp) { sp.addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { table.requestFocus(); } }); sp.getVerticalScrollBar().addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { keep_selected_cell_visible = false; } }); sp.getHorizontalScrollBar().addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { keep_selected_cell_visible = false; } }); sp.addMouseWheelListener(new MouseWheelListener() { @Override public void mouseWheelMoved(MouseWheelEvent e) { keep_selected_cell_visible = false; } }); } // +GBH moved from constructor private void mapKeys() { ((GalateeAction) action_vk_up).setEventSource(this); table.getActionMap().put("action_vk_up", action_vk_up); table.getInputMap().put( KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false), "action_vk_up"); ((GalateeAction) action_vk_right).setEventSource(this); table.getActionMap().put("action_vk_right", action_vk_right); table.getInputMap().put( KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, false), "action_vk_right"); ((GalateeAction) action_vk_down).setEventSource(this); table.getActionMap().put("action_vk_down", action_vk_down); table.getInputMap().put( KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, false), "action_vk_down"); ((GalateeAction) action_vk_left).setEventSource(this); table.getActionMap().put("action_vk_left", action_vk_left); table.getInputMap().put( KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, false), "action_vk_left"); ((GalateeAction) action_vk_enter).setEventSource(this); table.getActionMap().put("action_vk_enter", action_vk_enter); table.getInputMap().put( KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, false), "action_vk_enter"); ((GalateeAction) action_vk_plus).setEventSource(this); table.getActionMap().put("action_vk_plus", action_vk_plus); table.getInputMap().put(KeyStroke.getKeyStroke('+'), "action_vk_plus"); ((GalateeAction) action_vk_minus).setEventSource(this); table.getActionMap().put("action_vk_minus", action_vk_minus); table.getInputMap().put(KeyStroke.getKeyStroke('-'), "action_vk_minus"); ((GalateeAction) action_vk_page_up).setEventSource(this); table.getActionMap().put("action_vk_page_up", action_vk_page_up); table.getInputMap().put( KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP, 0, false), "action_vk_page_up"); ((GalateeAction) action_vk_page_down).setEventSource(this); table.getActionMap().put("action_vk_page_down", action_vk_page_down); table.getInputMap().put( KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN, 0, false), "action_vk_page_down"); ((GalateeAction) action_vk_home).setEventSource(this); table.getActionMap().put("action_vk_home", action_vk_home); table.getInputMap().put( KeyStroke.getKeyStroke(KeyEvent.VK_HOME, 0, false), "action_vk_home"); ((GalateeAction) action_vk_end).setEventSource(this); table.getActionMap().put("action_vk_end", action_vk_end); table.getInputMap().put( KeyStroke.getKeyStroke(KeyEvent.VK_END, 0, false), "action_vk_end"); ((GalateeAction) action_vk_tab).setEventSource(this); table.getActionMap().put("action_vk_tab", action_vk_tab); table.getInputMap().put( KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0, false), "action_vk_tab"); table.getActionMap().put("action_preferences_dialog", action_preferences_dialog); table.getInputMap().put( KeyStroke.getKeyStroke(KeyEvent.VK_P, java.awt.event.InputEvent.CTRL_MASK, false), "action_preferences_dialog"); // ((GalateeAction) action_changeToGrid).setEventSource(this); // table.getActionMap().put("action_changeToGrid", // action_changeToGrid); // table.getInputMap().put( // KeyStroke.getKeyStroke(KeyEvent.VK_G, // java.awt.event.InputEvent.CTRL_MASK, false), // "action_changeToGrid"); ((GalateeAction) action_asterisk).setEventSource(this); table.getActionMap().put("action_asterisk", action_asterisk); table.getInputMap().put(KeyStroke.getKeyStroke('*'), "action_asterisk"); } private abstract class GalateeAction extends AbstractAction { protected Object source; public void setEventSource(Object source) { this.source = source; } } private Action action_vk_up = new GalateeAction() { public void actionPerformed(ActionEvent e) { //System.out.println("up"); //if any gitem has been selected yet. if (table.getSelectedRow() == -1 || table.getSelectedColumn() == -1) { //updating selected item. table.setRowSelectionInterval(0, 0); table.setColumnSelectionInterval(0, 0); } else if (table.getSelectedRow() > 0) { //if we don't go out the table. //updating selected item.* table.setRowSelectionInterval(table.getSelectedRow() - 1, table .getSelectedRow() - 1); } else { //scrolling the table to view the selected cell. table.scrollRectToVisible(table.getCellRect(table .getSelectedRow(), table.getSelectedColumn(), true)); return; } } }; private Action action_vk_down = new GalateeAction() { public void actionPerformed(ActionEvent e) { // System.out.println("down"); //if any gitem has been selected yet. if (table.getSelectedRow() == -1 || table.getSelectedColumn() == -1) { //updating selected item. table.setRowSelectionInterval(0, 0); table.setColumnSelectionInterval(0, 0); } else if (table.getSelectedRow() < table.getRowCount() - 1) { //if we don't go out the table. if (table.getModel().getValueAt(table.getSelectedRow() + 1, table.getSelectedColumn()) == null) { //if the cell at the bottom is empty. //scrolling the table to view the selected cell. table .scrollRectToVisible(table.getCellRect(table .getSelectedRow(), table .getSelectedColumn(), true)); return; } //updating selected cell. table.setRowSelectionInterval(table.getSelectedRow() + 1, table .getSelectedRow() + 1); } else { //scrolling the table to view the selected cell. table.scrollRectToVisible(table.getCellRect(table .getSelectedRow(), table.getSelectedColumn(), true)); return; } } }; private Action action_vk_right = new GalateeAction() { public void actionPerformed(ActionEvent e) { //System.out.println("right"); //if any gitem has been selected yet. if (table.getSelectedRow() == -1 || table.getSelectedColumn() == -1) { //updating selected item. table.setRowSelectionInterval(0, 0); table.setColumnSelectionInterval(0, 0); } else if (table.getSelectedColumn() < nbcol - 1) { //if we don't go out the table. if (table.getModel().getValueAt(table.getSelectedRow(), table.getSelectedColumn() + 1) == null) { //if the cell at the right is empty. //scrolling the table to view the selected cell. table .scrollRectToVisible(table.getCellRect(table .getSelectedRow(), table .getSelectedColumn(), true)); return; } //updating the selected cell. table.setColumnSelectionInterval(table.getSelectedColumn() + 1, table.getSelectedColumn() + 1); } else { //scrolling the table to view the selected cell. table.scrollRectToVisible(table.getCellRect(table .getSelectedRow(), table.getSelectedColumn(), true)); return; } } }; private Action action_vk_left = new GalateeAction() { public void actionPerformed(ActionEvent e) { //System.out.println("left"); //if any gitem has been selected yet. if (table.getSelectedRow() == -1 || table.getSelectedColumn() == -1) { //updating selected item. table.setRowSelectionInterval(0, 0); table.setColumnSelectionInterval(0, 0); } else if (table.getSelectedColumn() > 0) { //if we don't go out the table. //updating selected item. table.setColumnSelectionInterval(table.getSelectedColumn() - 1, table.getSelectedColumn() - 1); } else { //scrolling the table to view the selected cell. table.scrollRectToVisible(table.getCellRect(table .getSelectedRow(), table.getSelectedColumn(), true)); return; } } }; private Action action_vk_enter = new GalateeAction() { public void actionPerformed(ActionEvent e) { //System.out.println("enter"); if (table.getSelectedRow() >= 0 && table.getSelectedColumn() >= 0) { eq.postEvent(new GEvent(GEvent.E_ITEM_DOUBLECLICKED, source, (GItem) model.getValueAt(table.getSelectedRow(), table .getSelectedColumn()))); } } }; private Action action_vk_plus = new GalateeAction() { public void actionPerformed(ActionEvent e) { //System.out.println("plus"); changeModelAddColumn(); } }; private Action action_vk_minus = new GalateeAction() { public void actionPerformed(ActionEvent e) { //System.out.println("minus"); changeModelRemoveColumn(); } }; private Action action_vk_tab = new GalateeAction() { public void actionPerformed(ActionEvent e) { //System.out.println("tab"); } }; private Action action_vk_page_up = new GalateeAction() { public void actionPerformed(ActionEvent e) { //System.out.println("page_up"); //getting the pixel coordinates of the gitem at the corner left in the viewport. Point gitem_at_left_bottom_corner_in_spviewport = new Point(1, sp .getViewport().getHeight() - 1); //transforming these coordinates in coordinates for the jtable. Point gitem_at_left_bottom_corner_in_table = SwingUtilities .convertPoint(sp.getViewport(), gitem_at_left_bottom_corner_in_spviewport, table); //getting the row and the column for the found coordinates. int gitem_bottom_row = table .rowAtPoint(gitem_at_left_bottom_corner_in_table); int gitem_left_col = table .columnAtPoint(gitem_at_left_bottom_corner_in_table); //get the number of gitems vertically displayed in the JScrollPane. int verticallyDisplayableGItems = sp.getViewport().getHeight() / gitemImageDimension.height; //get the row number of the new first row (i.e. after page_up). int new_first_displayed_row = gitem_bottom_row - verticallyDisplayableGItems * 2 + 2; //the +1 is for keeping the first gitem displayed. if (new_first_displayed_row < 0) { new_first_displayed_row = 0; } //do the scroll. table.scrollRectToVisible(table.getCellRect( new_first_displayed_row, gitem_left_col, true)); } }; private Action action_vk_page_down = new GalateeAction() { public void actionPerformed(ActionEvent e) { //System.out.println("page_down"); //getting the pixel coordinates of the gitem at the corner left in the viewport. Point gitem_at_left_bottom_corner_in_spviewport = new Point(1, sp .getViewport().getHeight() - 1); //transforming these coordinates in coordinates for the jtable. Point gitem_at_left_bottom_corner_in_table = SwingUtilities .convertPoint(sp.getViewport(), gitem_at_left_bottom_corner_in_spviewport, table); //getting the row and the column for the found coordinates. int gitem_bottom_row = table .rowAtPoint(gitem_at_left_bottom_corner_in_table); int gitem_left_col = table .columnAtPoint(gitem_at_left_bottom_corner_in_table); //get the number of gitems vertically displayed in the JScrollPane. int verticallyDisplayableGItems = sp.getViewport().getHeight() / gitemImageDimension.height; //get the row number of the new first row (i.e. after page_down). int new_last_displayed_row = gitem_bottom_row + verticallyDisplayableGItems - 2; //the -2 is for keeping the last gitem displayed. if (new_last_displayed_row > (table.getRowCount() - 1)) { new_last_displayed_row = table.getRowCount() - 1; } //do the scroll. table.scrollRectToVisible(table.getCellRect(new_last_displayed_row, gitem_left_col, true)); } }; private Action action_vk_home = new GalateeAction() { public void actionPerformed(ActionEvent e) { //System.out.println("home"); //do the scroll. table.scrollRectToVisible(table.getCellRect(0, 0, true)); } }; private Action action_vk_end = new GalateeAction() { public void actionPerformed(ActionEvent e) { //System.out.println("end"); //do the scroll. table.scrollRectToVisible(table.getCellRect( table.getRowCount() - 1, 0, true)); } }; private Action action_preferences_dialog = new GalateeAction() { public void actionPerformed(ActionEvent e) { //System.out.println("preferences"); preferences_dialog.setVisible(true); } }; private Action action_asterisk = new GalateeAction() { public void actionPerformed(ActionEvent e) { System.out.println("asterisk"); setDescriptionVisible(!description_visible); } }; // private Action action_changeToGrid = new GalateeAction() { // public void actionPerformed(ActionEvent e) { // Galatee.this.changeToGridView(3); // } // }; public void setDescriptionVisible(boolean vis) { if (!vis) { renderer.updateDimension(gitemImageDimension, 0); editor.updateDimension(gitemImageDimension, 0); table.repaint(); description_visible = false; } else { renderer.updateDimension(gitemImageDimension, gitemDescriptionWidth); editor.updateDimension(gitemImageDimension, gitemDescriptionWidth); table.repaint(); description_visible = true; } } /** * ************************************************************************* * implementation of ComponentListener. * ************************************************************************ */ @Override public void componentHidden(ComponentEvent e) { } @Override public void componentMoved(ComponentEvent e) { } @Override public void componentResized(ComponentEvent e) { JScrollPane sp = (JScrollPane) e.getSource(); // if (sp.getViewport().getSize().width > (nbcol + 1) * renderer.getItemWidth()) { // while (sp.getViewport().getSize().width > (nbcol + 1) * renderer.getItemWidth()) { // changeModelAddColumn(); // } // return; // } // if (sp.getViewport().getSize().width < (nbcol) * renderer.getItemWidth()) { // while (sp.getViewport().getSize().width < (nbcol) * renderer.getItemWidth()) { // changeModelRetrieveColumn(); // } // return; // } } @Override public void componentShown(ComponentEvent e) { } /** * ************************************************************************* * implementation of ListSelectionListener. * ************************************************************************ */ @Override public void valueChanged(ListSelectionEvent e) { synchronized (this) { if (!e.getValueIsAdjusting()) { /* * verifying that it's a true real "new selection". * (the contrary could happen because we have a ListSelectionListener * for the rows and another one for the columns). */ if (selectedrow == table.getSelectedRow() && selectedcol == table.getSelectedColumn()) { return; } int r = table.getSelectedRow(); int c = table.getSelectedColumn(); /* * some ListSelectionEvent are thrown with no selection... */ if (r == -1 || c == -1) { return; } //scrolling the table to view the selected cell. table.scrollRectToVisible(table.getCellRect(r, c, true)); /* * we edit the current cell (for having the JTextArea in the cell, and thus * allowing the selection of the text with the mouse for copy/paste filepath etc.). */ table.editCellAt(r, c); //creating the new GEvent.E_SELECTION_CHANGED event. eq.postEvent(new GEvent(GEvent.E_SELECTION_CHANGED, this, (GItem) model.getValueAt(r, c))); /* * updating the selectedcell. */ selectedrow = r; selectedcol = c; } } } /** * ************************************************************************* * implementation of KeyListener. * ************************************************************************ */ @Override public void keyPressed(KeyEvent e) { keep_selected_cell_visible = false; } @Override public void keyReleased(KeyEvent e) { } @Override public void keyTyped(KeyEvent e) { } }