Olá
Pessoal estou com esse erro:
org.eclipse.swt.SWT.error(SWT.java:3563)
Eu não conheço esse pacote SWT.
O problema encontra-se no meu construtor :
public WordSearchReplace() {
this.shell = new Shell();
this.frame = new OleFrame(this.shell, SWT.NONE);
this.wordSite = new OleClientSite(this.frame, SWT.NONE, WordSearchReplace.PROG_ID);
this.wordAutomation = new OleAutomation(this.wordSite);
}
A primeira vez que eu executo a classe a aplicação funciona correto , porem ao executar a segunda vez ao entrar no construtor eu tenho erro.
Ao executar a segunda vez o erro da na primeira linha :
this.shell = new Shell();
Essa classe faz o seguinte : Ler um documento MS word e faz um search e eplace no arquivo e depois salva.
Como faço para resolver esse problema?
Segue a classe.
Grato
Silva
========================classe java============================
package br.com.wordreplace.view;
import java.util.ArrayList;
import java.util.Iterator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.internal.ole.win32.TYPEATTR;
import org.eclipse.swt.ole.win32.OLE;
import org.eclipse.swt.ole.win32.OleAutomation;
import org.eclipse.swt.ole.win32.OleClientSite;
import org.eclipse.swt.ole.win32.OleFrame;
import org.eclipse.swt.ole.win32.OleFunctionDescription;
import org.eclipse.swt.ole.win32.OlePropertyDescription;
import org.eclipse.swt.ole.win32.OleParameterDescription;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.ole.win32.Variant;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.BufferedWriter;
import java.io.IOException;
public class WordSearchReplace {
private static final String PROG_ID = "Word.Application";
private static final int WD_REPLACE_ALL = 1;
private static final int WD_FIND_CONTINUE = 1;
private Shell shell = null;
private OleFrame frame = null;
private OleClientSite wordSite = null;
private OleAutomation wordAutomation = null;
private OleAutomation activeDocumentAutomation = null;
private boolean cleaned = false;
/**
* Create a new instance of the WordSearchReplace class.
*/
public WordSearchReplace() {
System.out.println("entrei no construtor");
this.shell = new Shell();
this.frame = new OleFrame(this.shell, SWT.NONE);
this.wordSite = new OleClientSite(this.frame, SWT.NONE, WordSearchReplace.PROG_ID);
this.wordAutomation = new OleAutomation(this.wordSite);
}
/**
* Open an MS Word file. This is a file whose name ends with the extension
* .doc or .doc and which conforms to the correct format.
*
* Note; if it is possible to open the named file, an attempt is made
* to cache an OleAutomation object referencing that file which will be
* referred to in future as the active document. Most other methods
* need to capture references to further OleAutomation(s) that have the
* active document as their root.
*
* @param fileName An instance of the String class that encapsulates the
* path to and name of the file that is to be opened.
* Note; the full path name must be supplied as Word
* will be opening the file and no assumptions can
* safely be made concerning the applications 'home'
* folder.
*
* @throws NullPointerException if a null value is passed to the fileName
* parameter.
* @throws FileNotFoundException if it is not possible to locate the
* file.
* @throws IllegalArgumentException if the name of the file does not end
* with either the .dot or .doc extensions.
* @throws SWTException if a problem occurs whilst invoking any of the OLE
* methods.
*/
public void openFile(String fileName) throws SWTException,
NullPointerException,
FileNotFoundException,
IllegalArgumentException {
OleAutomation documentsAutomation = null;
int[] id = null;
Variant[] arguments = null;
Variant invokeResult = null;
try {
// Check the the file name is not null
if(fileName == null) {
throw new NullPointerException("Null value passed to " +
"fileName parameters of the openFile() method.");
}
// Check the the file names ends with '.dot' or '.doc'.
// Remember to include templates and docuemnts
if(!(fileName.endsWith(".doc")) && !(fileName.endsWith(".dot"))) {
throw new IllegalArgumentException(
"The filename must end with the extensions \'.doc\' or \'.dot\'");
}
// Check that the file exists
File fileToPrint = new File(fileName);
if(!(fileToPrint.exists())) {
throw new FileNotFoundException("The file " +
fileName +
"cannot be found.");
}
// From the application, get an automation for the Documents property
documentsAutomation = this.getChildAutomation(this.wordAutomation, "Documents");
// Get the ID of the Open method
id = documentsAutomation.getIDsOfNames(new String[]{"Open"});
if(id == null) {
throw new SWTException("It was not possible to recover an " +
"identifer for the Open method in WordSearchReplace.openFile().");
}
// Build an array of parameters - holds just the file name
arguments = new Variant[1];
arguments[0] = new Variant(fileName);
// Invoke the Open method on the Documents property
invokeResult = documentsAutomation.invoke(id[0], arguments);
// If the call to invoke the open method failed, throw an SWTException
// to terminate processing.
if(invokeResult == null) {
throw new SWTException("An error occurred whilst invoking the " +
"Open method for the following file: " +
fileName +
" in WordSearchReplace.openFile().");
}
// If it was possible to open the document successfully, grab an
// automation object referencing the active document here.
else {
this.activeDocumentAutomation = this.getChildAutomation(
this.wordAutomation, "ActiveDocument");
}
}
finally {
// If the automation was instantiated then dispose of it to
// release resources. This OleAutomation was only required
// to open the file and can safely be released here.
if(documentsAutomation != null) {
documentsAutomation.dispose();
}
}
}
/**
* Save the currently open file - the active document.
*
* @throws SWTException if a problem occurs whilst invoking any of the OLE
* methods.
*/
public void save() throws SWTException {
int[] id = null;
Variant invokeResult = null;
// From the automation for the ActiveDocument object, get an id for
// the Save method
id = this.activeDocumentAutomation.getIDsOfNames(new String[]{"Save"});
// If it was not possible to recover the id of the Save
// method, throw an exception to notify the user and terminate
// processing.
if(id == null) {
throw new SWTException("Unable to obtain an automation for " +
"the Save method in WordSearchReplace.save().");
}
// Invoke the Save method and catch the value returned
invokeResult = this.activeDocumentAutomation.invoke(id[0]);
// If a null value was returned then the invocation of the
// Save method failed. Throw an exception to notify the
// user and terminate processing.
if(invokeResult == null) {
throw new SWTException("A problem occurred invoking the " +
"Save method in WordSearchReplace.save().");
}
}
/**
* Save the active document using the name provided.
*
* @param fileName Am instance of the String class encapsulating the name
* for the file. Again, the path to and name of the file should
* be supplied.
*
* @throws NullPointerException if a null value is passed to the fileName
* parameter.
* @throws IllegalArgumentException if either an empty String is passed
* to the fileName parameter or if the files name does not end
* with one of the two permissible extensions - .dot and .doc
*/
public void saveAs(String fileName) throws SWTException,
NullPointerException,
IllegalArgumentException {
int[] id = null;
Variant[] arguments = null;
Variant invokeResult = null;
// If the fileName parameter is passed a null
// value, throw an exception.
if(fileName == null) {
throw new NullPointerException("A null value was passed to " +
"the fileName parameter of WordSearchReplace.saveAs().");
}
// If the fileName parameter has been passed an empty String
// then again throw an exception.
if(fileName.length() == 0) {
throw new NullPointerException("An empty string was passed " +
"to the fileName parameter of WordSearchReplace.saveAs().");
}
// Finally, make sure the file name ends in either
// .doc or .dot.
if((!fileName.endsWith(".dot")) && (!fileName.endsWith(".doc"))) {
throw new IllegalArgumentException("An illegal file name was " +
"passed to the fileName parameter of " +
"WordSearchReplace.saveAs(). The file name must " +
"end in \'.dot\' or \'.doc\'.");
}
// From the automation for the ActiveDocument object, get an id for
// the SaveAs method
id = this.activeDocumentAutomation.getIDsOfNames(new String[]{"SaveAs"});
// If it was not possible to recover the id of the SaveAs
// method, throw an exception to notify the user and terminate
// processing.
if(id == null) {
throw new SWTException("Unable to obtain an automation for " +
"the SaveAs method in WordSearchReplace.saveAs().");
}
// Build the array of arguments that will be passed to the invoke
// method when the SaveAs method is invoked. In this case, this
// array will contain a single member - a String object encapsulating
// the path to and name of the output file.
arguments = new Variant[1];
arguments[0] = new Variant(fileName);
// Invoke the SaveAs method and catch the value returned
invokeResult = this.activeDocumentAutomation.invoke(id[0], arguments);
// If a null value was returned then the invocation of the
// PrintOut method failed. Throw an exception to notify the
// user and terminate processing.
if(invokeResult == null) {
throw new SWTException("A problem occurred invoking the " +
"SaveAs method in WordSearchReplace.saveAs().");
}
}
/**
* Mimics Words 'replace' functionality by searching the active
* document for evey string of characters that matches the value passed to
* the searchTerm parameter and replacing them with the string of
* characters passed to the replacementTerm method.
*
* It is possible to code a VBA macro within Word that will perfrom a serach
* and replace. That code would look like the following;
*
* <pre>
* Selection.Find.ClearFormatting
* Selection.Find.Replacement.ClearFormatting
* With Selection.Find
* .Text = "serach"
* .Replacement.Text = "search"
* .Forward = True
* .Wrap = wdFindContinue
* .Format = False
* .MatchCase = False
* .MatchWholeWord = False
* .MatchWildcards = False
* .MatchSoundsLike = False
* .MatchAllWordForms = False
* End With
* Selection.Find.Execute Replace:=wdReplaceAll
* <pre>
*
* and this method will 'automate' it.
*
* @param searchTerm An instance of the String class that will encapsulate
* the series of characters that should be replaced.
* @param replacementTerm An instance of the String class that will
* encapsulate the series of characters that should replace the
* searchTerm.
*
* @throws NullPointerException if a null value is passed to either the
* searchTerm or replacementTerm methods.
* @throws SWTException if a problem occurs when invoking any of the
* OLE methods.
*/
public void replace(String searchTerm,
String replacementTerm) throws SWTException,
NullPointerException {
OleAutomation selectionFindAutomation = null;
OleAutomation childAutomation = null;
Variant[] arguments = null;
Variant invokeResult = null;
int[] id = null;
int[] namedArguments = null;
boolean success = true;
// Validate the searchTerm parameter and throw exception if
// null value passed.
if(searchTerm == null) {
throw new NullPointerException("Null value passed to " +
"searchTerm parameter of the replace() method.");
}
// Validate the replacementTerm parameter and throw exception if
// null value passed.
if(replacementTerm == null) {
throw new NullPointerException("Null value passed to " +
"replacementTerm parameter of the replace() method.");
}
// Most of the VBA instructions used to perform the search and
// replace functionality and child automations of Selection.Find,
// therefore, it is wise to cache that automation first.
// From the application, get an automation for the Selection property
childAutomation = this.getChildAutomation(this.wordAutomation,
"Selection");
selectionFindAutomation = this.getChildAutomation(childAutomation,
"Find");
// Next, using the cached automation, invoke the 'ClearFormatting'
// method, validate the returned value and invoke the method.
//
// Selection.Find.ClearFormatting
//
id = selectionFindAutomation.getIDsOfNames(new String[]{"ClearFormatting"});
if(id == null) {
throw new SWTException("It is not possible to recover an identifier " +
"for the ClearFormatting method in WordSearchReplace.replace() " +
"when clearing the formatting for the search string.");
}
invokeResult = selectionFindAutomation.invoke(id[0]);
if(invokeResult == null) {
throw new SWTException("A problem occurred invoking the " +
"ClearFormatting method in WordSearchReplace.repace() " +
"when clearing formatting for the search string.");
}
// Now, perform the same function but for the replacement string.
//
// Selection.Find.Replacement.ClearFormatting
//
childAutomation = this.getChildAutomation(selectionFindAutomation,
"Replacement");
id = childAutomation.getIDsOfNames(new String[]{"ClearFormatting"});
if(id == null) {
throw new SWTException("It is not possible to recover an identifier " +
"for the ClearFormatting method in WordSearchReplace.replace() " +
"when clearing the formatting for the replacement string.");
}
invokeResult = childAutomation.invoke(id[0]);
if(invokeResult == null) {
throw new SWTException("A problem occurred invoking the " +
"ClearFormatting method in WordSearchReplace.repace() " +
"when clearing formatting for the replacement string.");
}
// Firstly, set the search text.
//
// .Text = "search term"
//
arguments = new Variant[1];
arguments[0] = new Variant(searchTerm);
success = this.setPropertyValue(selectionFindAutomation, "Text", arguments);
if(!success) {
throw new SWTException("A problem occurred setting the Text " +
"property for the search string in WordSearchReplace.replace().");
}
// Next, the replacement text
//
// .Replacement.Text = "replacement term"
//
childAutomation = this.getChildAutomation(selectionFindAutomation, "Replacement");
arguments[0] = new Variant(replacementTerm);
success = this.setPropertyValue(childAutomation, "Text", arguments);
if(!success) {
throw new SWTException("A problem occurred setting the Text property" +
" for the replacement string in WordSearchReplace.replace().");
}
// Set the direction of the search - forward in this case.
//
// .Forward = True
//
arguments[0] = new Variant(true);
success = this.setPropertyValue(selectionFindAutomation, "Forward", arguments);
if(!success) {
throw new SWTException("A problem occurred setting the Forward " +
"property in WordSearchReplace.replace().");
}
// Tell the search to wrap. Note the literal wdFindContinue relates to
// a constant that is defined within Word. I have provided a static
// final to replace it called WD_FIND_CONTINUE
//
// .Wrap = wdFindContinue
//
arguments[0] = new Variant(WordSearchReplace.WD_FIND_CONTINUE);
// System.out.println(“jose vieira WD_FIND_CONTINUE:” + arguments[0]);
success = this.setPropertyValue(selectionFindAutomation, “Wrap”, arguments);
if(!success) {
throw new SWTException("A problem occurred setting the Wrap " +
“property in WordSearchReplace.replace().”);
}
// Set the Format property to False.
//
// .Format = False
//
arguments[0] = new Variant(false);
success = this.setPropertyValue(selectionFindAutomation, "Format", arguments);
if(!success) {
throw new SWTException("A problem occurred setting the Format " +
"property in WordSearchReplace.replace().");
}
// Set the MatchCase property to false.
//
// .MatchCase = False
//
arguments[0] = new Variant(false);
success = this.setPropertyValue(selectionFindAutomation, "MatchCase", arguments);
if(!success) {
throw new SWTException("A problem occurred setting the MatchCase " +
"property in WordSearchReplace.replace().");
}
// Set the MatchWholeWord property to false.
//
// .MatchWholeWord = False
//
arguments[0] = new Variant(false);
success = this.setPropertyValue(selectionFindAutomation, "MatchWholeWord", arguments);
if(!success) {
throw new SWTException("A problem occurred setting the " +
"MatchWholeWord property in WordSearchReplace.replace().");
}
// Set the MatchWildCards property to false.
//
// .MatchWildcards = False
//
arguments[0] = new Variant(false);
success = this.setPropertyValue(selectionFindAutomation, "MatchWildCards", arguments);
if(!success) {
throw new SWTException("A problem occurred setting the " +
"MatchWildCards property in WordSearchReplace.replace().");
}
// Set the MatchSoundsLike property to false.
//
// .MatchSoundsLike = False
//
arguments[0] = new Variant(false);
success = this.setPropertyValue(selectionFindAutomation, "MatchSoundsLike", arguments);
if(!success) {
throw new SWTException("A problem occurred setting the " +
"MatchSoundsLike property in WordSearchReplace.replace().");
}
// Set the MatchAllWordForms property to false.
//
// .MatchAllWordForms = False
//
arguments[0] = new Variant(false);
success = this.setPropertyValue(selectionFindAutomation, "MatchAllWordForms", arguments);
if(!success) {
throw new SWTException("A problem occurred setting the " +
"MatchAllWordForms property in WordSearchReplace.replace().");
}
// Invoke the Execute command passing the correct value to the Replace
// parameter. Again, wdReplaceAll is a constant that I have provided
// a ststic final for called WD_REPLACE_ALL
//
// Selection.Find.Execute Replace:=wdReplaceAll
//
id = selectionFindAutomation.getIDsOfNames(new String[]{"Execute", "Replace"});
if(id == null) {
throw new SWTException("It was not possible to recover an identifier " +
"for the Execute method in WordSearchReplace.replace().");
}
arguments = new Variant[1];
arguments[0] = new Variant(WordSearchReplace.WD_REPLACE_ALL);
namedArguments = new int[1];
namedArguments[0] = id[1];
// There was some indication that the invokeNoReply method should
// be used when making this call but no, invoke SEEMS to work well
//selectionFindAutomation.invokeNoReply(id[0], arguments, namedArguments);
invokeResult = selectionFindAutomation.invoke(id[0], arguments, namedArguments);
if(invokeResult == null) {
throw new SWTException("A problem occurred trying to invoke the " +
"Execute method in WordSearchReplace.replace().");
}
}
/**
* Close the active document.
*
* @throws SWTException if a problem is encountered invoking any of the
* OLE methods.
*/
public void closeFile() throws SWTException {
int[] id = null;
Variant[] arguments = null;
Variant invokeResult = null;
try {
// From the OleAutomation referencing the active document, recover
// the id of the Close method.
id = this.activeDocumentAutomation.getIDsOfNames(new String[]{"Close"});
// If it was not possible to recover the id of the Close
// method then throw an exception to notify the user and
// terminate processing.
if(id == null) {
throw new SWTException("It was not possible to recover an " +
"identifier for the Close method in " +
"WordSearchReplace.closeFile().");
}
// Invoke the Close method on the ActiveDocument automation
invokeResult = this.activeDocumentAutomation.invoke(id[0]);
// If the invocation of the Close method failed, throw an
// exception to notify the user and terminate processing.
if(invokeResult == null) {
throw new SWTException(
"An error occurred invoking the Close method in " +
"WordSearchReplace.closeFile().");
}
}
finally {
if(this.activeDocumentAutomation != null) {
this.activeDocumentAutomation.dispose();
}
}
System.out.println("finalizei a classe ");
}
/**
* Release resources.
*/
public void dispose() throws SWTException {
try {
// Set the cleaned flag to true. This prevents the method from
// running again if it is called from the finalize() method
this.cleaned = true;
// From the word automation, recover the id of the Quit method
int[] id = this.wordAutomation.getIDsOfNames(new String[]{"Quit"});
// If the id of the Quit method cannot be recovered
// throw an exception - not much good really though.
if(id == null) {
throw new SWTException("Unable to obtain an id for the Quit " +
"property in WordSearchReplace.dispose().");
}
// Invoke Quit
Variant result = this.wordAutomation.invoke(id[0]);
// If an error occurs during the invocation, throw an exception.
// Again though that exception is of limited value.
if(result == null) {
throw new SWTException("A problem occurred trying to invoke the " +
"Quit method in WordSearchReplace.dispose().");
}
}
finally {
// Finally, dispose of the word application automation.
this.wordAutomation.dispose();
}
}
/**
* The finalize() method has been over-ridden to ensure that resources
* are correctly released if a WordSearchReplace object is created but
* not disposed of properly before it becomes eligible for garbage
* collection. The cleaned flag is used as acheck to ensure that the
* dispose() method cannot be called more than once.
*/
public void finalize() throws Throwable {
if(!this.cleaned) {
this.dispose();
}
}
/**
* Creates and returns a 'child' OleAutomation object. The object model
* employed by Word, Excel and the like, arrange objects, methods and
* properties hierarchically. To invoke a method, it is often necessary
* to iterate through this hierarchy from parent to child and this method
* supports that process.
*
* @param automation An OleAutomation object that references the parent
* automation.
* @param childName An instance of the String class that encapsulates the
* name of the child automation.
*
* @throws SWTException if a problem is encountered invoking one or
* other of the OLE methods.
*/
private OleAutomation getChildAutomation(OleAutomation automation,
String childName) throws SWTException {
// Try to recove the unique identifier for the child automation
int[] id = automation.getIDsOfNames(new String[]{childName});
// If the identifier cannot be found then throw an exception to
// terminate processing.
if (id == null) {
throw new SWTException(
"A problem occurred trying to obtain and id for: " +
childName +
"in the getChildAutomation() method.");
}
// SWT's implementation of OLE referes to all of Words objects, methods
// and properties using the single term 'property'. The next stage
// therefore is to recover a refence to the 'property' that relates
// to the child automation.
Variant pVarResult = automation.getProperty(id[0]);
// If it is not possible to recover a 'property' for the child
// automation, then throw an SWTException.
if (pVarResult == null) {
throw new SWTException(
"A problem occurred trying to obtain an automation for property: " +
id[0] +
" in the getChildAutomation() method.");
}
// As we are after a child automation in this instance, call the
// getAutomation() method on the 'property'.
return(pVarResult.getAutomation());
}
/**
* Sets the value of a property.
*
* @param automation An instance of the OleAutomation class that will
* hold a reference to the properties parent automation object
* @param propertyName An instance of the String class that encapsulates the
* name of the property whose value is to be set.
* @param arguments An array of type Variant whose elements contain the
* values that will be set for the named property.
*
* @return A primitive boolean value that indicates whether or not the
* properties value was successfully set.
*
* @throws NullPointerException will be thrown if a null value is passed to
* any of the methods three arguments.
* @throws IllegalArgumentException will be thrown if an empty String
* is passed to the propertyName parameter or if an empty array
* is passed to the arguments parameter. Note, no check is made
* on the vallues of the elements in the arguments array.
* @throws SWTException will be thrown if a problem is encountered
* imvoking any of the OLE methods.
*/
private boolean setPropertyValue(OleAutomation automation,
String propertyName,
Variant[] arguments) throws SWTException,
NullPointerException,
IllegalArgumentException {
// Validate the various parameters
if(automation == null) {
throw new NullPointerException(
"A null value was passed to the automation parameter of " +
"WordSearchReplace.setPropertyValue().");
}
if(propertyName == null) {
throw new NullPointerException(
"A null value was passed to the propertyName parameter of " +
"WordSearchReplace.setPropertyValue().");
}
if(propertyName.length() == 0) {
throw new IllegalArgumentException(
"An empty - zero length - String was passed to the propertyName " +
"parameter of WordSearchReplace.setPropertyValue().");
}
if(arguments == null) {
throw new NullPointerException(
"A null value was passed to the arguments parameter of " +
"WordSearchReplace.setPropertyValue().");
}
if(arguments.length == 0) {
throw new IllegalArgumentException(
"An empty - zero length - array was passed to the arguments " +
"parameter of WordSearchReplace.setPropertyValue().");
}
// Recover the identifier for the property
int[] id = automation.getIDsOfNames(new String[]{propertyName});
if(id == null) {
throw new SWTException("Unable to obtain an identifier for the " +
propertyName +
" property in WordSearchReplace.setPropertyValue().");
}
// Try to set the properties value. If this fails, the boolean value
// false will be returned to the calling code.
return(automation.setProperty(id[0], arguments));
}
}