001 /* 002 Copyright (C) 2001-2003 Renaud Pawlak <renaud@aopsys.com>, 003 Laurent Martelli <laurent@aopsys.com> 004 005 This program is free software; you can redistribute it and/or modify 006 it under the terms of the GNU Lesser General Public License as 007 published by the Free Software Foundation; either version 2 of the 008 License, or (at your option) any later version. 009 010 This program is distributed in the hope that it will be useful, 011 but WITHOUT ANY WARRANTY; without even the implied warranty of 012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 GNU Lesser General Public License for more details. 014 015 You should have received a copy of the GNU Lesser General Public License 016 along with this program; if not, write to the Free Software 017 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 018 019 package org.objectweb.jac.aspects.gui.swing; 020 021 import java.awt.BorderLayout; 022 import java.awt.Component; 023 import java.awt.Container; 024 import java.awt.Dialog; 025 import java.awt.Dimension; 026 import java.awt.Frame; 027 import java.awt.Rectangle; 028 import java.awt.Toolkit; 029 import java.awt.event.ActionEvent; 030 import java.awt.event.ActionListener; 031 import java.awt.event.ContainerEvent; 032 import java.awt.event.ContainerListener; 033 import java.awt.event.KeyEvent; 034 import java.awt.event.KeyListener; 035 import java.awt.event.WindowAdapter; 036 import java.awt.event.WindowEvent; 037 import java.util.Map; 038 import javax.swing.BorderFactory; 039 import javax.swing.JButton; 040 import javax.swing.JDialog; 041 import javax.swing.JLabel; 042 import javax.swing.JPanel; 043 import javax.swing.SwingConstants; 044 import org.apache.log4j.Logger; 045 import org.objectweb.jac.aspects.gui.CommitException; 046 import org.objectweb.jac.aspects.gui.DialogView; 047 import org.objectweb.jac.aspects.gui.DisplayContext; 048 import org.objectweb.jac.aspects.gui.GuiAC; 049 import org.objectweb.jac.aspects.gui.View; 050 import org.objectweb.jac.core.Collaboration; 051 import org.objectweb.jac.util.Strings; 052 053 public class ObjectViewDialog extends JDialog 054 implements ActionListener, KeyListener, ContainerListener 055 { 056 static Logger loggerEvents = Logger.getLogger("gui.events"); 057 static Logger loggerFocus = Logger.getLogger("gui.focus"); 058 059 public boolean ok=false; 060 JButton okButton; 061 JButton cancelButton; 062 JButton closeButton; 063 View objectView; 064 protected DisplayContext context; 065 066 /** Stores context attributes at creation time so they can be 067 restored by components when invoking methods */ 068 Map attributes; 069 070 public ObjectViewDialog(View view, 071 String title, String header, 072 Frame parent, 073 boolean okay, boolean cancel, boolean close, 074 DisplayContext context) { 075 super(parent); 076 setModal(parent!=null); 077 context.setWindow(this); 078 init(view,title,header,okay,cancel,close,context); 079 } 080 081 public ObjectViewDialog(View view, 082 String title, String header, 083 Dialog parent, 084 boolean okay, boolean cancel, boolean close, 085 DisplayContext context) { 086 super(parent); 087 setModal(parent!=null); 088 context.setWindow(this); 089 init(view,title,header,okay,cancel,close,context); 090 } 091 092 093 public ObjectViewDialog(View view, 094 String title, String header, 095 boolean okay, boolean cancel, boolean close, 096 DisplayContext context) { 097 setModal(false); 098 context.setWindow(this); 099 init(view,title,header,okay,cancel,close,context); 100 } 101 102 void init(View view, 103 String title, String header, 104 boolean okay, boolean cancel, boolean close, 105 DisplayContext context) 106 { 107 this.context = context; 108 setTitle(title); 109 110 if (okay || cancel) { 111 //((AbstractSwingDisplay)display).addDialog(this); 112 //setModal(true); 113 } 114 115 if (header != null) { 116 JPanel p=new JPanel(); 117 p.setBorder(BorderFactory.createEtchedBorder()); 118 p.add(new JLabel(header,SwingConstants.LEFT)); 119 getContentPane().add(p,BorderLayout.NORTH); 120 } 121 if (view != null) { 122 getContentPane().add((Component)view,BorderLayout.CENTER); 123 objectView = view; 124 } 125 126 if (okay || cancel || close) { 127 JPanel p2 = new JPanel(); 128 p2.setBorder(BorderFactory.createEtchedBorder()); 129 if (okay) { 130 okButton = addButton(p2, "Ok"); 131 } 132 if (cancel) { 133 cancelButton = addButton(p2, "Cancel"); 134 } 135 if (close) { 136 closeButton = addButton(p2,"Close"); 137 } 138 getContentPane().add(p2, BorderLayout.SOUTH); 139 if (closeButton!=null) { 140 getRootPane().setDefaultButton(closeButton); 141 } else if (okButton!=null) { 142 getRootPane().setDefaultButton(okButton); 143 } 144 } 145 pack(); 146 147 // open the box centered in the screen... 148 Dimension screenDim = Toolkit.getDefaultToolkit().getScreenSize(); 149 Rectangle rect = getBounds(); 150 rect.width = Math.min(screenDim.width,rect.width); 151 rect.height = Math.min(screenDim.height,rect.height); 152 double left = (screenDim.getWidth()-rect.getWidth())/2; 153 double top = (screenDim.getHeight()-rect.getHeight())/2; 154 Rectangle newRect = new Rectangle( 155 (int)left,(int)top, 156 (int)rect.getWidth(),(int)rect.getHeight()); 157 setBounds(newRect); 158 159 addWindowListener( new WindowAdapter () { 160 public void windowClosing(WindowEvent e) { 161 loggerEvents.debug("windowClosing: "+e); 162 if (objectView!=null) 163 objectView.close(true); 164 } 165 } 166 ); 167 168 java.util.List editors = context.getEditors(); 169 if (!editors.isEmpty()) { 170 loggerFocus.debug("give focus to "+editors.get(0)); 171 ((Component)editors.get(0)).requestFocus(); 172 } else { 173 loggerFocus.debug("no editor to give focus to"); 174 } 175 176 addKeyAndContainerListenerRecursively(this); 177 178 attributes = Collaboration.get().getAttributes(); 179 180 setVisible(true); 181 } 182 183 public void actionPerformed(ActionEvent evt) { 184 try { 185 Object source = evt.getSource(); 186 if (source==okButton || source==closeButton) { 187 if (objectView!=null) { 188 objectView.close(true); 189 } 190 ok = true; 191 close(true); 192 dispose(); 193 } else if (source==cancelButton) { 194 ok = false; 195 // ((AbstractSwingDisplay)display).removeDialog(this); 196 close(false); 197 dispose(); 198 } 199 } catch (CommitException e) { 200 context.getDisplay().showModal(e,"Error","",context.getWindow(),false,false,true); 201 } catch (Exception e) { 202 loggerEvents.error("ObjectViewDialog.actionPerformed failed",e); 203 } 204 } 205 206 public void close(boolean validate) { 207 if (objectView!=null) 208 objectView.close(validate); 209 objectView = null; 210 } 211 212 public JButton addButton(Container c, String name) { 213 JButton button = new JButton(name); 214 button.addActionListener(this); 215 c.add(button); 216 return button; 217 } 218 219 // We should implement DialogView !!! 220 public void restoreContext() { 221 loggerEvents.debug("Restoring attributes: "+attributes.keySet()); 222 Collaboration.get().setAttributes(attributes); 223 } 224 225 // KeyListener interface 226 public void keyPressed(KeyEvent event) { 227 int code = event.getKeyCode(); 228 switch (code) { 229 case KeyEvent.VK_ESCAPE: 230 ok = false; 231 dispose(); 232 break; 233 default: 234 } 235 } 236 public void keyTyped(KeyEvent event) {} 237 public void keyReleased(KeyEvent event) {} 238 239 // ContainerListener interface 240 // Copied from http://www.javaworld.com/javaworld/javatips/jw-javatip69.html 241 242 public void componentAdded(ContainerEvent event) { 243 addKeyAndContainerListenerRecursively(event.getChild()); 244 } 245 246 /** 247 * Register as a KeyListener and ContainerListener on the component 248 * and its children recursively. 249 * @param c the component 250 */ 251 protected void addKeyAndContainerListenerRecursively(Component c) { 252 c.addKeyListener(this); 253 if (c instanceof Container) { 254 Container cont = (Container)c; 255 cont.addContainerListener(this); 256 Component[] children = cont.getComponents(); 257 for(int i=0; i<children.length; i++){ 258 addKeyAndContainerListenerRecursively(children[i]); 259 } 260 } 261 } 262 263 public void componentRemoved(ContainerEvent event) { 264 removeKeyAndContainerListenerRecursively(event.getChild()); 265 } 266 267 /** 268 * Unregister as a KeyListener and ContainerListener on the 269 * component and its children recursively. 270 * @param c the component 271 */ 272 protected void removeKeyAndContainerListenerRecursively(Component c) { 273 c.removeKeyListener(this); 274 if (c instanceof Container) { 275 Container cont = (Container)c; 276 cont.removeContainerListener(this); 277 Component[] children = cont.getComponents(); 278 for(int i=0; i<children.length; i++){ 279 removeKeyAndContainerListenerRecursively(children[i]); 280 } 281 } 282 } 283 284 public String toString() { 285 return Strings.hex(this); 286 } 287 }