/* * 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.frontends.swing; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.io.FileOutputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.List; import java.util.logging.Logger; import javax.swing.BorderFactory; 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.ListSelectionModel; import javax.swing.Spring; import javax.swing.SpringLayout; import javax.swing.UIManager; 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.AbstractVascFrontend; import com.idcanet.vasc.core.VascEntry; import com.idcanet.vasc.core.VascEntryField; import com.idcanet.vasc.core.VascFrontendData; import com.idcanet.vasc.core.actions.GlobalVascAction; import com.idcanet.vasc.core.actions.RowVascAction; import com.idcanet.vasc.core.entry.VascEntryExporter; import com.idcanet.vasc.core.entry.VascEntryEventListener.VascEventType; import com.idcanet.vasc.core.ui.VascColumnValueModelListener; import com.idcanet.vasc.core.ui.VascUIComponent; import com.idcanet.vasc.core.ui.VascValueModel; import com.idcanet.vasc.frontends.swing.ui.SwingBoolean; import com.idcanet.vasc.frontends.swing.ui.SwingButton; import com.idcanet.vasc.frontends.swing.ui.SwingColorChooser; import com.idcanet.vasc.frontends.swing.ui.SwingDate; import com.idcanet.vasc.frontends.swing.ui.SwingLabel; import com.idcanet.vasc.frontends.swing.ui.SwingList; import com.idcanet.vasc.frontends.swing.ui.SwingText; import com.idcanet.vasc.frontends.swing.ui.SwingTextArea; /** * * @author Willem Cazander * @version 1.0 Mar 21, 2007 */ public class SwingVascFrontend extends AbstractVascFrontend { private Logger logger = null; private JComponent parent = null; public SwingVascFrontend(JComponent parent) { logger = Logger.getLogger(SwingVascFrontend.class.getName()); this.parent=parent; } /** * Add swing implmented ui components */ protected void addUiComponents() { VascFrontendData vfd = getVascEntry().getVascFrontendData(); // required UI components vfd.putVascUIComponent(VascUIComponent.VASC_LABEL,SwingLabel.class.getName()); vfd.putVascUIComponent(VascUIComponent.VASC_TEXT, SwingText.class.getName()); vfd.putVascUIComponent(VascUIComponent.VASC_LIST, SwingList.class.getName()); vfd.putVascUIComponent(VascUIComponent.VASC_BUTTON, SwingButton.class.getName()); // optional UI components vfd.putVascUIComponent(VascUIComponent.VASC_BOOLEAN , SwingBoolean.class.getName()); vfd.putVascUIComponent(VascUIComponent.VASC_DATE , SwingDate.class.getName()); vfd.putVascUIComponent(VascUIComponent.VASC_TEXTAREA, SwingTextArea.class.getName()); vfd.putVascUIComponent(VascUIComponent.VASC_COLOR, SwingColorChooser.class.getName()); } public ImageIcon getImageIcon(String imageResource) { /// TODO hack beter String key = entry.getVascFrontendData().getVascEntryResourceResolver().getTextValue(imageResource); //logger.fine("KEY======================="+key); if (key.startsWith("vasc.entry")) { return null; } if (key.indexOf("META-INF")>0 | key.indexOf("resource")>0) { return SwingImageHelper.getImageIcon(key); } else { return null; } } /** * @see com.idcanet.vasc.core.VascViewRenderer#renderEdit(com.idcanet.vasc.core.VascEntry, java.lang.Object) */ public void renderEdit(Object rowBean) throws Exception { logger.fine("Rending Edit View"); rowBean = entry.getVascFrontendData().getVascFrontendHelper().initEditObject(entry, rowBean); String beanValue = rowBean.toString(); if (entry.getDisplayNameFieldId()!=null) { VascEntryField v = entry.getVascEntryFieldById(entry.getDisplayNameFieldId()); Object vv = v.getVascEntryFieldValue().getValue(v, rowBean); if (vv==null) { beanValue=""; } else { beanValue=""+vv; } if (beanValue.length()>30) { beanValue=beanValue.substring(0, 30); } } SwingEditDialog dialog = new SwingEditDialog(parent,entry,rowBean,i18n("vasc.dialog.edit.title"),i18n("vasc.dialog.edit.message",beanValue)); Object result = dialog.openDialog(); logger.finest("OPEN closed : "+result); if(result==null) { return; } entry.getVascFrontendData().getVascFrontendHelper().mergeObject(entry, result); } public void renderDelete(Object rowBean) throws Exception { String beanValue = rowBean.toString(); if (entry.getDisplayNameFieldId()!=null) { VascEntryField v = entry.getVascEntryFieldById(entry.getDisplayNameFieldId()); beanValue = ""+v.getVascEntryFieldValue().getValue(v, rowBean); if (beanValue.length()>30) { beanValue=beanValue.substring(0, 30); } } int response = JOptionPane.showOptionDialog( parent // Center in window. , i18n("vasc.dialog.delete.message",beanValue) // Message , i18n("vasc.dialog.delete.title") // 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) { entry.getVascFrontendData().getVascController().getVascBackendControllerResolver().getVascBackendController().getVascBackendById(entry.getBackendId()).delete(rowBean); entry.getVascFrontendData().getEntryDataList().remove(rowBean); entry.getVascFrontendData().setEntryDataObject(null); //entry.getVascFrontendController().getVascFrontendHelper().fireVascEvent(VascEventListener.VascEventType.DATA_UPDATE, rowBean); } } class SwingEditDialog extends JDialog { private static final long serialVersionUID = 10L; private String headerText = null; private Object result = null; private Object bean = null; public SwingEditDialog(JComponent parent,VascEntry entry,Object bean,String title,String headerText) throws Exception { super(); this.headerText = headerText; this.bean = bean; setTitle(i18n(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(i18n(headerText)); l.setFont(new Font(null,Font.BOLD, 14)); //l.setToolTipText(i18n(headerText)); header.add(l); } public void createBody(JPanel body) throws Exception { body.setLayout(new SpringLayout()); int column = 0; for (VascEntryField c:entry.getVascEntryFields()) { entry.getVascFrontendData().getVascFrontendHelper().initEditObjectColumn(c, bean); if (c.isEdit()==false) { continue; } //if (c.isEditReadOnly()==true) { for (int i=0;i list = new ArrayList(); for(VascEntryField c:entry.getVascEntryFields()) { if (c.isList()==false) { continue; } list.add(c); } VascEntryField vtc = list.get(columnIndex); try { //if (vtc.getVascColumnRenderer()!=null) { // return vtc.getVascColumnRenderer().rendererColumn(vtc,bean); //} else { return ""+vtc.getVascEntryFieldValue().getValue(vtc,bean); // } } catch (Exception e) { return "Error"; } } } } /** * A 1.4 file that provides utility methods for creating form- or grid-style * layouts with SpringLayout. These utilities are used by several programs, such * as SpringBox and SpringCompactGrid. */ class SpringUtilities { /** * Aligns the first rows*cols components of * parent in a grid. Each component is as big as the maximum * preferred width and height of the components. 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 makeGrid(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 makeGrid must use SpringLayout."); return; } Spring xPadSpring = Spring.constant(xPad); Spring yPadSpring = Spring.constant(yPad); Spring initialXSpring = Spring.constant(initialX); Spring initialYSpring = Spring.constant(initialY); int max = rows * cols; //Calculate Springs that are the max of the width/height so that all //cells have the same size. Spring maxWidthSpring = layout.getConstraints(parent.getComponent(0)) .getWidth(); Spring maxHeightSpring = layout.getConstraints(parent.getComponent(0)) .getWidth(); for (int i = 1; i < max; i++) { SpringLayout.Constraints cons = layout.getConstraints(parent .getComponent(i)); maxWidthSpring = Spring.max(maxWidthSpring, cons.getWidth()); maxHeightSpring = Spring.max(maxHeightSpring, cons.getHeight()); } //Apply the new width/height Spring. This forces all the //components to have the same size. for (int i = 0; i < max; i++) { SpringLayout.Constraints cons = layout.getConstraints(parent .getComponent(i)); cons.setWidth(maxWidthSpring); cons.setHeight(maxHeightSpring); } //Then adjust the x/y constraints of all the cells so that they //are aligned in a grid. SpringLayout.Constraints lastCons = null; SpringLayout.Constraints lastRowCons = null; for (int i = 0; i < max; i++) { SpringLayout.Constraints cons = layout.getConstraints(parent .getComponent(i)); if (i % cols == 0) { //start of new row lastRowCons = lastCons; cons.setX(initialXSpring); } else { //x position depends on previous component cons.setX(Spring.sum(lastCons.getConstraint(SpringLayout.EAST), xPadSpring)); } if (i / cols == 0) { //first row cons.setY(initialYSpring); } else { //y position depends on previous row cons.setY(Spring.sum(lastRowCons .getConstraint(SpringLayout.SOUTH), yPadSpring)); } lastCons = cons; } //Set the parent's size. SpringLayout.Constraints pCons = layout.getConstraints(parent); pCons.setConstraint(SpringLayout.SOUTH, Spring.sum(Spring .constant(yPad), lastCons.getConstraint(SpringLayout.SOUTH))); pCons.setConstraint(SpringLayout.EAST, Spring.sum( Spring.constant(xPad), lastCons .getConstraint(SpringLayout.EAST))); } /* Used by makeCompactGrid. */ private static SpringLayout.Constraints getConstraintsForCell(int row, int col, Container parent, int cols) { SpringLayout layout = (SpringLayout) parent.getLayout(); Component c = parent.getComponent(row * cols + col); return layout.getConstraints(c); } /** * Aligns the first rows*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); } }