1 19 20 package org.netbeans.modules.db.sql.loader; 21 22 import java.awt.Component ; 23 import java.awt.KeyboardFocusManager ; 24 import java.beans.PropertyChangeEvent ; 25 import java.beans.PropertyChangeListener ; 26 import java.beans.PropertyChangeSupport ; 27 import java.io.IOException ; 28 import javax.swing.Action ; 29 import javax.swing.ActionMap ; 30 import javax.swing.JComponent ; 31 import javax.swing.JEditorPane ; 32 import javax.swing.JPanel ; 33 import javax.swing.JSplitPane ; 34 import javax.swing.SwingUtilities ; 35 import javax.swing.text.BadLocationException ; 36 import javax.swing.text.Document ; 37 import org.netbeans.api.db.explorer.DatabaseConnection; 38 import org.netbeans.modules.db.api.sql.execute.SQLExecution; 39 import org.netbeans.modules.db.sql.execute.ui.SQLResultPanel; 40 import org.openide.ErrorManager; 41 import org.openide.text.CloneableEditor; 42 import org.openide.util.Lookup; 43 import org.openide.util.Mutex; 44 import org.openide.util.lookup.AbstractLookup; 45 import org.openide.util.lookup.InstanceContent; 46 import org.openide.util.lookup.ProxyLookup; 47 import org.openide.windows.TopComponent; 48 49 56 public class SQLCloneableEditor extends CloneableEditor { 57 58 private transient JPanel container; 59 private transient JSplitPane splitter; 60 private transient SQLResultPanel resultComponent; 61 62 private transient SQLExecutionImpl sqlExecution; 63 64 private transient Lookup originalLookup; 65 66 private transient InstanceContent instanceContent = new InstanceContent(); 67 private transient Lookup ourLookup = new AbstractLookup(instanceContent); 68 69 private transient SQLCloneableEditorLookup resultingLookup; 70 71 public SQLCloneableEditor() { 72 super(null); 73 } 74 75 public SQLCloneableEditor(SQLEditorSupport support) { 76 super(support); 77 initialize(); 78 } 79 80 public boolean hasResultComponent() { 81 return resultComponent != null; 82 } 83 84 public SQLResultPanel getResultComponent() { 85 assert SwingUtilities.isEventDispatchThread(); 86 if (resultComponent == null) { 87 createResultComponent(); 88 } 89 return resultComponent; 90 } 91 92 private void createResultComponent() { 93 JPanel container = findContainer(this); 94 if (container == null) { 95 return; 98 } 99 100 Component editor = container.getComponent(0); 101 container.removeAll(); 102 103 resultComponent = new SQLResultPanel(); 104 splitter = new JSplitPane (JSplitPane.VERTICAL_SPLIT, editor, resultComponent); 105 splitter.setBorder(null); 106 107 container.add(splitter); 108 splitter.setDividerLocation(250); 109 splitter.setDividerSize(7); 110 111 container.invalidate(); 112 container.validate(); 113 container.repaint(); 114 115 getActionMap().setParent(new DelegateActionMap(getActionMap().getParent(), getEditorPane())); 120 121 if (equals(TopComponent.getRegistry().getActivated())) { 122 requestFocusInWindow(); 124 } 125 } 126 127 131 private JPanel findContainer(Component parent) { 132 if (!(parent instanceof JComponent )) { 133 return null; 134 } 135 Component [] components = ((JComponent )parent).getComponents(); 136 for (int i = 0; i < components.length; i++) { 137 Component component = components[i]; 138 if (component instanceof JPanel && SQLEditorSupport.EDITOR_CONTAINER.equals(component.getName())) { 139 return (JPanel )component; 140 } 141 JPanel container = findContainer(component); 142 if (container != null) { 143 return container; 144 } 145 } 146 return null; 147 } 148 149 public synchronized Lookup getLookup() { 150 Lookup currentLookup = super.getLookup(); 151 if (currentLookup != originalLookup) { 152 originalLookup = currentLookup; 153 if (resultingLookup == null) { 154 resultingLookup = new SQLCloneableEditorLookup(); 155 } 156 resultingLookup.updateLookups(new Lookup[] { originalLookup, ourLookup }); 157 } 158 return resultingLookup; 159 } 160 161 protected void componentDeactivated() { 162 if (sqlEditorSupport().isConsole()) { 163 try { 164 cloneableEditorSupport().saveDocument(); 165 } catch (IOException e) { 166 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 167 } 168 } 169 super.componentDeactivated(); 170 } 171 172 protected void componentClosed() { 173 sqlExecution.editorClosed(); 174 super.componentClosed(); 175 } 176 177 public void writeExternal(java.io.ObjectOutput out) throws IOException { 178 if (sqlEditorSupport().isConsole()) { 179 try { 180 cloneableEditorSupport().saveDocument(); 181 } catch (IOException e) { 182 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 183 } 184 } 185 super.writeExternal(out); 186 } 187 188 public void readExternal(java.io.ObjectInput in) throws IOException , ClassNotFoundException { 189 super.readExternal(in); 190 initialize(); 191 } 192 193 private void initialize() { 194 sqlExecution = new SQLExecutionImpl(); 195 instanceContent.add(sqlExecution); 196 } 197 198 private SQLEditorSupport sqlEditorSupport() { 199 return (SQLEditorSupport)cloneableEditorSupport(); 200 } 201 202 private static final class DelegateActionMap extends ActionMap { 203 204 private ActionMap delegate; 205 private JEditorPane editorPane; 206 207 public DelegateActionMap(ActionMap delegate, JEditorPane editorPane) { 208 this.delegate = delegate; 209 this.editorPane = editorPane; 210 } 211 212 public void remove(Object key) { 213 214 super.remove(key); 215 } 216 217 public javax.swing.Action get(Object key) { 218 boolean isEditorPaneFocused = KeyboardFocusManager.getCurrentKeyboardFocusManager().getPermanentFocusOwner() == editorPane; 219 if (isEditorPaneFocused) { 220 return delegate.get(key); 221 } else { 222 return null; 223 } 224 } 225 226 public void put(Object key, Action action) { 227 delegate.put(key, action); 228 } 229 230 public void setParent(ActionMap map) { 231 delegate.setParent(map); 232 } 233 234 public int size() { 235 return delegate.size(); 236 } 237 238 public Object [] keys() { 239 return delegate.keys(); 240 } 241 242 public ActionMap getParent() { 243 return delegate.getParent(); 244 } 245 246 public void clear() { 247 delegate.clear(); 248 } 249 250 public Object [] allKeys() { 251 return delegate.allKeys(); 252 } 253 } 254 255 private static final class SQLCloneableEditorLookup extends ProxyLookup { 256 257 public SQLCloneableEditorLookup() { 258 super(new Lookup[0]); 259 } 260 261 public void updateLookups(Lookup[] lookups) { 262 setLookups(lookups); 263 } 264 } 265 266 269 private final class SQLExecutionImpl implements SQLExecution, PropertyChangeListener { 270 271 private final PropertyChangeSupport propChangeSupport = new PropertyChangeSupport (this); 277 278 public SQLExecutionImpl() { 279 sqlEditorSupport().addSQLPropertyChangeListener(this); 280 } 281 282 private void editorClosed() { 283 sqlEditorSupport().removeSQLPropertyChangeListener(this); 284 } 285 286 public void propertyChange(PropertyChangeEvent event) { 287 propChangeSupport.firePropertyChange(event); 288 } 289 290 public void addPropertyChangeListener(PropertyChangeListener listener) { 291 propChangeSupport.addPropertyChangeListener(listener); 292 } 293 294 public void removePropertyChangeListener(PropertyChangeListener listener) { 295 propChangeSupport.removePropertyChangeListener(listener); 296 } 297 298 public DatabaseConnection getDatabaseConnection() { 299 return sqlEditorSupport().getDatabaseConnection(); 300 } 301 302 public void setDatabaseConnection(DatabaseConnection dbconn) { 303 sqlEditorSupport().setDatabaseConnection(dbconn); 304 } 305 306 public void execute() { 307 String text = Mutex.EVENT.readAccess(new Mutex.Action<String >() { 308 public String run() { 309 return getText(getEditorPane()); 310 } 311 }); 312 sqlEditorSupport().execute(text, 0, text.length()); 313 } 314 315 public void executeSelection() { 316 final int[] offsets = new int[2]; 317 String text = Mutex.EVENT.readAccess(new Mutex.Action<String >() { 318 public String run() { 319 JEditorPane editorPane = getEditorPane(); 320 int startOffset = editorPane.getSelectionStart(); 321 int endOffset = editorPane.getSelectionEnd(); 322 if (startOffset == endOffset) { 323 offsets[0] = offsets[1] = editorPane.getCaretPosition(); 326 } else { 327 offsets[0] = startOffset; 328 offsets[1] = endOffset; 329 } 330 return getText(editorPane); 331 } 332 }); 333 sqlEditorSupport().execute(text, offsets[0], offsets[1]); 334 } 335 336 public boolean isExecuting() { 337 return sqlEditorSupport().isExecuting(); 338 } 339 340 public boolean isSelection() { 341 Boolean result = Mutex.EVENT.readAccess(new Mutex.Action<Boolean >() { 342 public Boolean run() { 343 JEditorPane editorPane = getEditorPane(); 344 return Boolean.valueOf(editorPane.getSelectionStart() < editorPane.getSelectionEnd()); 345 } 346 }); 347 return result.booleanValue(); 348 } 349 350 public String toString() { 351 return "SQLExecution[support=" + sqlEditorSupport().messageName() + ", dbconn=" + sqlEditorSupport().getDatabaseConnection() + "]"; } 353 354 private String getText(JEditorPane editorPane) { 355 Document doc = editorPane.getDocument(); 359 try { 360 return doc.getText(0, doc.getLength()); 361 } catch (BadLocationException e) { 362 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 364 return ""; } 366 } 367 } 368 } 369 | Popular Tags |