/* * Copyright 2004-2007 IDCA. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and * the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions * and the following disclaimer in the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY IDCA AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL IDCA OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * The views and conclusions contained in the software and documentation are those of the authors and * should not be interpreted as representing official policies, either expressed or implied, of IDCA. */ package com.idcanet.vasc.impl.swing; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Container; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.FileOutputStream; import java.io.OutputStream; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JFileChooser; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.JTextField; import javax.swing.ListSelectionModel; import javax.swing.Spring; import javax.swing.SpringLayout; import javax.swing.UIManager; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.table.AbstractTableModel; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.JTableHeader; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; import com.idcanet.fff.SwingImageHelper; import com.idcanet.vasc.core.VascDataExporter; import com.idcanet.vasc.core.VascEventListener; import com.idcanet.vasc.core.VascTable; import com.idcanet.vasc.core.VascUserOption; import com.idcanet.vasc.core.VascViewRenderer; import com.idcanet.vasc.core.actions.GlobalVascAction; import com.idcanet.vasc.core.actions.RowVascAction; import com.idcanet.vasc.core.column.VascTableColumn; /** * * @author Willem Cazander * @version 1.0 Mar 21, 2007 */ public class SwingVascViewRenderer implements VascViewRenderer { private Logger logger = null; private JComponent parent = null; private VascTable table = null; public SwingVascViewRenderer(JComponent parent) { logger = Logger.getLogger(SwingVascViewRenderer.class.getName()); this.parent=parent; } /** * @see com.idcanet.vasc.core.VascViewRenderer#defaultColumnEditor(com.idcanet.vasc.core.column.VascTableColumn, java.lang.Object, java.lang.Object) */ public Object defaultColumnEditor(VascTableColumn column, Object bean, Object gui) throws Exception { JTextField def = new JTextField(); def.setText(""+column.getVascColumnValue().getValue(column, bean)); ((JComponent)gui).add(def); def.getDocument().addDocumentListener(new TextListener(column,bean) ); return def; } public ImageIcon getImageIcon(String imageResource) { return SwingImageHelper.getImageIcon(imageResource); } class TextListener implements DocumentListener { private VascTableColumn column = null; private Object bean = null; public TextListener(VascTableColumn column,Object bean) { this.column=column; this.bean=bean; } /* (non-Javadoc) * @see javax.swing.event.DocumentListener#changedUpdate(javax.swing.event.DocumentEvent) */ public void changedUpdate(DocumentEvent e) { update(e); } /* (non-Javadoc) * @see javax.swing.event.DocumentListener#insertUpdate(javax.swing.event.DocumentEvent) */ public void insertUpdate(DocumentEvent e) { update(e); } /* (non-Javadoc) * @see javax.swing.event.DocumentListener#removeUpdate(javax.swing.event.DocumentEvent) */ public void removeUpdate(DocumentEvent e) { update(e); } public void update(DocumentEvent event) { try { String value = event.getDocument().getText(0, event.getDocument().getLength()); logger.finer("Setting value: "+value); column.getVascColumnValue().setValue(column, bean, value); } catch (Exception ee) { ee.printStackTrace(); } } } /** * @see com.idcanet.vasc.core.VascViewRenderer#defaultColumnRenderer(com.idcanet.vasc.core.column.VascTableColumn, java.lang.Object) */ public Object defaultColumnRenderer(VascTableColumn column, Object gui) throws Exception { return null; } /** * @see com.idcanet.vasc.core.VascViewRenderer#renderEdit(com.idcanet.vasc.core.VascTable, java.lang.Object) */ public void renderEdit(VascTable table, Object rowBean) throws Exception { logger.info("Rending Edit View"); table.getVascTableController().initEditObject(table, rowBean); SwingEditDialog dialog = new SwingEditDialog(parent,table,rowBean,"Vasc Edit","Edit"); Object result = dialog.openDialog(); System.out.println("---------------- OPEN closed : "+result); if(result==null) { return; } try { result = table.getVascDataSource().merge(rowBean); table.getVascTableController().fireVascEvent(VascEventListener.VascEventType.DATA_UPDATE, result); } finally { //TODO: or merge into table == faster table.getVascTableController().refreshData(table); } } public void renderDelete(VascTable table,Object rowBean) throws Exception { int response = JOptionPane.showOptionDialog( parent // Center in window. , "Delete "+rowBean // Message , "Delete" // Title in titlebar , JOptionPane.YES_NO_OPTION // Option type , JOptionPane.PLAIN_MESSAGE // messageType , null // Icon (none) , null // Button text as above. , null // Default button's label ); if (response==JOptionPane.YES_OPTION) { table.getVascDataSource().delete(rowBean); table.getVascTableController().fireVascEvent(VascEventListener.VascEventType.DATA_UPDATE, rowBean); } } class SwingEditDialog extends JDialog { private String headerText = null; private String title = null; private Object result = null; private Object bean = null; public SwingEditDialog(JComponent parent,VascTable table,Object bean,String title,String headerText) { super(); this.headerText = headerText; this.title = title; this.bean = bean; setTitle(title); setModal(true); JPanel pane = new JPanel(); pane.setLayout(new BorderLayout()); JPanel header = new JPanel(); createHeader(header); pane.add(header,BorderLayout.NORTH); JPanel body = new JPanel(); createBody(body); pane.add(body,BorderLayout.CENTER); JPanel footer = new JPanel(); createFooter(footer); pane.add(footer,BorderLayout.SOUTH); add(pane); setDefaultCloseOperation(DISPOSE_ON_CLOSE); //Ensure the text field always gets the first focus. //addComponentListener(new ComponentAdapter() { // public void componentShown(ComponentEvent ce) { // textField.requestFocusInWindow(); // } /// }); pack(); setLocationRelativeTo(parent); } public Object openDialog() { setVisible(true); return result; } public void createHeader(JPanel header) { JLabel l = new JLabel(); l.setText(headerText); l.setFont(new Font(null,Font.BOLD, 14)); header.add(l); } public void createBody(JPanel body) { body.setLayout(new SpringLayout()); for(VascTableColumn c:table.getTableColumns()) { JLabel l = new JLabel(); l.setHorizontalAlignment(JLabel.TRAILING); l.setText(c.getName()); if(c.getToolTip()!=null) { l.setToolTipText(c.getToolTip()); } body.add(l); try { table.getVascTableController().initEditObjectColumn(c, bean); if(c.getVascColumnEditor()==null) { JLabel valueLabel = new JLabel(); valueLabel.setText(""+c.getVascColumnValue().getValue(c, bean)); c.setColumnEditor(valueLabel); body.add(valueLabel); } else { c.setColumnEditor(c.getVascColumnEditor().createColumnEditor(c,bean,body)); } } catch (Exception e) { logger.log(Level.WARNING,"Error making column editor: '"+c.getVascColumnValue()+"' error: "+e.getMessage(),e); } } //JComponent, rows, cols, initX, initY ,xPad, yPad SpringUtilities.makeCompactGrid(body, table.getTableColumns().size(),2, 6,6, 6,6); } public void createFooter(JPanel footer) { JButton saveButton = new JButton(); saveButton.setIcon(getImageIcon("/META-INF/images/silk/png/tick.png")); saveButton.setText("generic.save"); saveButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { //if(hasRecordError()) { // return; //} result = bean; setVisible(false); } }); footer.add(saveButton); JButton cancelButton = new JButton(); cancelButton.setIcon(getImageIcon("/META-INF/images/silk/png/cancel.png")); cancelButton.setText("generic.cancel"); cancelButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { result = null; setVisible(false); } }); footer.add(cancelButton); } } /** * @see com.idcanet.vasc.core.VascViewRenderer#renderExport(com.idcanet.vasc.core.VascTable, com.idcanet.vasc.core.VascDataExporter) */ public void renderExport(VascTable table, VascDataExporter exporter) throws Exception { String fileName = null; JFileChooser c = new JFileChooser(); // Demonstrate "Save" dialog: int rVal = c.showSaveDialog(null); if (rVal == JFileChooser.APPROVE_OPTION) { fileName = c.getSelectedFile().getAbsolutePath(); // filename.setText(c.getSelectedFile().getName()); //dir.setText(c.getCurrentDirectory().toString()); } if (rVal == JFileChooser.CANCEL_OPTION) { return; } logger.fine("FileName: "+fileName); if (fileName == null) { return; } OutputStream out = new FileOutputStream(fileName); try { exporter.doExport(out, table); } catch (Exception e) { //MessageDialog.openError(Display.getCurrent().getActiveShell(),crudTable.i18n("crud.event.export.error.title"),crudTable.i18n("crud.event.export.error.message")); logger.log(Level.WARNING,"Error: "+e.getMessage(),e); } finally { if (out!=null) { out.close(); } } } /** * @see com.idcanet.vasc.core.VascViewRenderer#renderView(com.idcanet.vasc.core.VascTable) */ public void renderView(VascTable table) throws Exception { if (table.getVascViewRenderer()==null) { table.setVascViewRenderer(this); } else { if (table.getVascViewRenderer()!=this) { throw new IllegalArgumentException("VascTable has already a differtent VascViewRenderer attected"); } } table.getVascTableController().finalizeVascColumns(table); table.getVascTableController().finalizeVascTable(table); table.getVascTableController().refreshData(table); this.table=table; JPanel topPanel = new JPanel(); topPanel.setLayout(new BorderLayout()); JPanel n = new JPanel(); topPanel.add(n,BorderLayout.NORTH); renderHeader(n); JPanel c = new JPanel(); topPanel.add(c,BorderLayout.CENTER); renderBody(c); JPanel f = new JPanel(); topPanel.add(f,BorderLayout.SOUTH); renderFooter(f); parent.add(topPanel); } private void renderHeader(JComponent parent2) { if(table.getHeaderName()!=null) { JLabel l = new JLabel(table.getVascTextValue().getTextValue(table.getHeaderName())); l.setFont(new Font(null,Font.BOLD, 14)); parent2.add(l); } for (GlobalVascAction action:table.getGlobalActions()) { JButton but = new JButton(); but.setText(table.getVascTextValue().getTextValue(action.getName())); but.setToolTipText(table.getVascTextValue().getTextValue(action.getToolTip())); but.addActionListener(new GlobalActionListener(action)); but.setIcon(getImageIcon(action.getImage())); parent2.add(but); } // create options for(VascUserOption option:table.getUserOptions()) { } } private void renderBody(JComponent parent2) { VascColumnModel model = new VascColumnModel(); table.getVascTableController().addEventListener(model); JTable jTable = new JTable(model); // remove auto columns :( int cols = jTable.getColumnModel().getColumnCount(); for (int i=0;irows*cols components of * parent in a grid. Each component in a column is as wide as * the maximum preferred width of the components in that column; height is * similarly determined for each row. The parent is made just big enough to * fit them all. * * @param rows * number of rows * @param cols * number of columns * @param initialX * x location to start the grid at * @param initialY * y location to start the grid at * @param xPad * x padding between cells * @param yPad * y padding between cells */ public static void makeCompactGrid(Container parent, int rows, int cols, int initialX, int initialY, int xPad, int yPad) { SpringLayout layout; try { layout = (SpringLayout) parent.getLayout(); } catch (ClassCastException exc) { System.err .println("The first argument to makeCompactGrid must use SpringLayout."); return; } //Align all cells in each column and make them the same width. Spring x = Spring.constant(initialX); for (int c = 0; c < cols; c++) { Spring width = Spring.constant(0); for (int r = 0; r < rows; r++) { width = Spring.max(width, getConstraintsForCell(r, c, parent, cols).getWidth()); } for (int r = 0; r < rows; r++) { SpringLayout.Constraints constraints = getConstraintsForCell(r, c, parent, cols); constraints.setX(x); constraints.setWidth(width); } x = Spring.sum(x, Spring.sum(width, Spring.constant(xPad))); } //Align all cells in each row and make them the same height. Spring y = Spring.constant(initialY); for (int r = 0; r < rows; r++) { Spring height = Spring.constant(0); for (int c = 0; c < cols; c++) { height = Spring.max(height, getConstraintsForCell(r, c, parent, cols).getHeight()); } for (int c = 0; c < cols; c++) { SpringLayout.Constraints constraints = getConstraintsForCell(r, c, parent, cols); constraints.setY(y); constraints.setHeight(height); } y = Spring.sum(y, Spring.sum(height, Spring.constant(yPad))); } //Set the parent's size. SpringLayout.Constraints pCons = layout.getConstraints(parent); pCons.setConstraint(SpringLayout.SOUTH, y); pCons.setConstraint(SpringLayout.EAST, x); } }