How do I call a PowerPoint macro via Java and pass parameters? - java

I have a Java application that is required to do a bunch of stuff to a PowerPoint file, one of which involves invoking an existing PowerPoint macro and passing parameters to it. Here are some sample code:
public static void main (String[] args) {
createPptFile("test");
/* Do stuff */
/* Call macro here */
/* Do more stuff */
}
Sub SaySomething(something)
MsgBox(something)
End Sub
The Java application first creates a new test.pptm file, then at some point later the application is supposed to call SaySomething(something) while passing a value to it. How can I do this? What libraries, if any, would I need? Please provide some sample code to show how this can be done.
The application is to be implemented using Java 1.8, and will run on Windows 10 and using Microsoft Office 2013. Apache POI is being used to edit PowerPoint files at present, though using it is not mandatory.

Related

how to print list of files selected in windows console in java

I have the requirement to print the full path and file names of files selected in windows directory.
the approach I have taken is
1. create key in registry to give option in context menu
2. attached the context menu option to execute my java program
now the issue I have ,
I want to select a few files ,
1. then right click on it
2. then execute my java program
3. and have the list of files selected in my java program as an input
i am not able to achieve point 3
any guidance how to approach it or better alternative
I think there is 2 possible approaches here.
You can custom Send to context menu, it supports passing multiple selected files. I prefer this one. It's quite simple to implement.
For example:
Ex.java
import java.io.IOException;
public class Ex {
public static void main(String[] args)
throws IOException {
for (String argument : args) {
System.out.println(argument);
}
System.in.read();
}
}
Compile it to Ex.class.
Create a shortcut named Test Send To in C:\Users\[username]\AppData\Roaming\Microsoft\Windows\SendTo point to:
"path\to\java.exe" -cp "path\to\Ex.class folder" Ex
Now try selecting multiple files and then right-click Send To > Test Send To, you will see the list of selected files onscreen.
You can implement interprocess communication to tell the existing instance that you want to add more files to proceed.

Java code in different build environments [duplicate]

My project requires Java 1.6 for compilation and running. Now I have a requirement to make it working with Java 1.5 (from the marketing side). I want to replace method body (return type and arguments remain the same) to make it compiling with Java 1.5 without errors.
Details: I have an utility class called OS which encapsulates all OS-specific things. It has a method
public static void openFile(java.io.File file) throws java.io.IOException {
// open the file using java.awt.Desktop
...
}
to open files like with double-click (start Windows command or open Mac OS X command equivalent). Since it cannot be compiled with Java 1.5, I want to exclude it during compilation and replace by another method which calls run32dll for Windows or open for Mac OS X using Runtime.exec.
Question: How can I do that? Can annotations help here?
Note: I use ant, and I can make two java files OS4J5.java and OS4J6.java which will contain the OS class with the desired code for Java 1.5 and 1.6 and copy one of them to OS.java before compiling (or an ugly way - replace the content of OS.java conditionally depending on java version) but I don't want to do that, if there is another way.
Elaborating more: in C I could use ifdef, ifndef, in Python there is no compilation and I could check a feature using hasattr or something else, in Common Lisp I could use #+feature. Is there something similar for Java?
Found this post but it doesn't seem to be helpful.
Any help is greatly appreciated. kh.
Nope there isn't any support for conditional compilation in Java.
The usual plan is to hide the OS specific bits of your app behind an Interface and then detect the OS type at runtime and load the implementation using Class.forName(String).
In your case there no reason why you can't compile the both OS* (and infact your whole app) using Java 1.6 with -source 1.5 -target 1.5 then in a the factory method for getting hold of OS classes (which would now be an interface) detect that java.awt.Desktop
class is available and load the correct version.
Something like:
public interface OS {
void openFile(java.io.File file) throws java.io.IOException;
}
public class OSFactory {
public static OS create(){
try{
Class.forName("java.awt.Desktop");
return new OSJ6();
}catch(Exception e){
//fall back
return new OSJ5();
}
}
}
Hiding two implementation classes behind an interface like Gareth proposed is probably the best way to go.
That said, you can introduce a kind of conditional compilation using the replace task in ant build scripts. The trick is to use comments in your code which are opened/closed by a textual replacement just before compiling the source, like:
/*{{ Block visible when compiling for Java 6: IFDEF6
public static void openFile(java.io.File file) throws java.io.IOException {
// open the file using java.awt.Desktop
...
/*}} end of Java 6 code. */
/*{{ Block visible when compiling for Java 5: IFDEF5
// open the file using alternative methods
...
/*}} end of Java 5 code. */
now in ant, when you compile for Java 6, replace "IFDEF6" with "*/", giving:
/*{{ Block visible when compiling for Java 6: */
public static void openFile(java.io.File file) throws java.io.IOException {
// open the file using java.awt.Desktop
...
/*}} end of Java 6 code. */
/*{{ Block visible when compiling for Java 5, IFDEF5
public static void openFile(java.io.File file) throws java.io.IOException {
// open the file using alternative methods
...
/*}} end of Java 5 code. */
and when compiling for Java 5, replace "IFDEF5". Note that you need to be careful to use // comments inside the /*{{, /*}} blocks.
You can make the calls using reflection and compile the code with Java 5.
e.g.
Class clazz = Class.forName("java.package.ClassNotFoundInJavav5");
Method method = clazz.getMethod("methodNotFoundInJava5", Class1.class);
method.invoke(args1);
You can catch any exceptions and fall back to something which works on Java 5.
The Ant script introduced below gives nice and clean trick.
link: https://weblogs.java.net/blog/schaefa/archive/2005/01/how_to_do_condi.html
in example,
//[ifdef]
public byte[] getBytes(String parameterName)
throws SQLException {
...
}
//[enddef]
with Ant script
<filterset begintoken="//[" endtoken="]">
<filter token="ifdef" value="${ifdef.token}"/>
<filter token="enddef" value="${enddef.token}"/>
</filterset>
please go to link above for more detail.
In java 9 it's possible to create multi-release jar files. Essentially it means that you make multiple versions of the same java file.
When you compile them, you compile each version of the java file with the required jdk version. Next you need to pack them in a structure that looks like this:
+ com
+ mypackage
+ Main.class
+ Utils.class
+ META-INF
+ versions
+ 9
+ com
+ mypackage
+ Utils.class
In the example above, the main part of the code is compiled in java 8, but for java 9 there is an additional (but different) version of the Utils class.
When you run this code on the java 8 JVM it won't even check for classes in the META-INF folder. But in java 9 it will, and will find and use the more recent version of the class.
I'm not such a great Java expert, but it seems that conditional compilation in Java is supported and easy to do. Please read:
http://www.javapractices.com/topic/TopicAction.do?Id=64
Quoting the gist:
The conditional compilation practice is used to optionally remove chunks of code from the compiled version of a class. It uses the fact that compilers will ignore any unreachable branches of code.
To implement conditional compilation,
define a static final boolean value as a non-private member of some class
place code which is to be conditionally compiled in an if block which evaluates the boolean
set the value of the boolean to false to cause the compiler to ignore the if block; otherwise, keep its value as true
Of course this lets us to "compile out" chunks of code inside any method. To remove class members, methods or even entire classes (maybe leaving only a stub) you would still need a pre-processor.
if you don't want conditionally enabled code blocks in your application then a preprocessor is only way, you could take a look at java-comment-preprocessor which can be used for both maven and ant projects
p.s.
also I have made some example how to use preprocessing with Maven to build JEP-238 multi-version JAR without duplication of sources
Java Primitive Specializations Generator supports conditional compilation:
/* if Windows compilingFor */
start();
/* elif Mac compilingFor */
open();
/* endif */
This tool has Maven and Gradle plugins.
hi I have got similar problem when I have shared library between Java SDK abd Android and in both environments are used the graphics so basically my code must to work with both
java.awt.Graphics and android.graphics.Canvas,
but I don't want to duplicate almost any code.
My solution is to use wrapper, so I access to graphisc API indirectl way, and
I can change a couple of imports, to import the wrapper I want to compile the projects.
The projects have some cone shaded and some are separate, but there is no duplicating anything except of couple of wrappers etc.
I think it is the best what I can do.

Using Java class in Matlab

I've been struggling with this problem for two days now and no resource I've found have been able to solve it.
I am trying to call a java class (added the link at the bottom) from Matlab (version 7.13.0.564 (R2011b)). I've compiled the java class using java 1.6 into a .class file and also added the path to the folder where the file is situated using javaaddpath (I've of course checked that the path is correct in the list of dynamic paths). However, when I try to call the class from Matlab using javaMethod('main','PerlinNoiseGenerator','') I get the error:
"No class PerlinNoiseGenerator can be located on Java class path"
I would be extremely grateful if someone with experience in calling java from Matlab could put together a short tut on how to do this. I am probably going to distribute my code so I kinda need to set the java path dynamically and from what I've read it really should be possible although I've seen post that indicate that it could be the cause of the problem.
http://svn.j3d.org/code/tags/Xj3D-M10/src/java/org/j3d/texture/procedural/PerlinNoiseGenerator.java
Usually I create jar files that contain java classes. I also had problems loading individual java classes before. In your case I did the following on xubuntu 13.04 x64 and Matlab 2013a x64 to load your particular class:
Compile it using java 6 (not the default 7) with option -d . to create a set of package folders, as your class defines a package org/j3d/texture/proecedural/ etc:
/usr/lib/jvm/java-6-openjdk-amd64/bin/javac -d . PerlinNoiseGenerator.java
This will compile the class and make in the current director (thus .) the set of package folders.
Make jar file containing your class again using jar from java 6. I named it javaNoise.jar:
/usr/lib/jvm/java-6-openjdk-amd64/bin/jar cf javaNoise.jar ./org/j3d/texture/procedural/PerlinNoiseGenerator.class
In Matlab, in the directory where javaNoise.jar is:
javaaddpath('./javaNoise.jar');
Create object of your java class:
png=org.j3d.texture.procedural.PerlinNoiseGenerator()
% results in: png = org.j3d.texture.procedural.PerlinNoiseGenerator#3982a033
To test it, I just generated some 1D noise:
png.noise1(1.2)
ans = -0.0960
Hope this helps.
P.S.
javaMethod('main','PerlinNoiseGenerator','') wont work because this class has no main method:-).
Your notation to the compiler of the constructor is a polymorphic class meaning "use appropriate constructor that is called at runtime".
public PerlinNoiseGenerator()
public PerlinNoiseGenerator(int seed)
The first form with no argument can be called but is irrelevent because the line with this(DEFAULT_SEED) attempts to call itself but only one constructor is allowed used
Second constructor has int for an argument but requires being loaded by an already loaded class.
Use the first version and change the case sensitive name of the one with the argument and remove this(DEFAULT_SEED) from it replace with the method name(the one you changed from a constructor that has the argument).
e.g. public perlinNoiseGenerator(int seed)
note: by convention java code method names start with a lower-case letter.
A final note, java arguments from the command line come in as "String" data type through the "main" method, a starter method for applications (gui or command prompt).
The first argument on the main method argument is the first commandline argument.
public static void main(String[] Args){
new PerlinNoiseGenerator(Args); // recursive class call
}//end main method
int[] args; // global
public PerlinNoiseGenerator(String[] Args){
int arglength=Args.length();
args = new int[arglength];
for(int cnt=0;cnt<arglength;cnt++){
Args[cnt].trim();
args[cnt]=new Integer(Args[cnt]).intValue();
}//enfor
perlinNoiseGenerator(args[0]); // call method
}//end constructor

Java Applet/Web Browser Issue

I am new to Java (and programming in general) so I thought that making a simple test case applet would help to form a basic understanding of the language.
So, I decided to make a basic applet that would display a green rectangle. The code looks like:
import javax.swing.JApplet;
import java.awt.Color;
import java.awt.Graphics;
public class Box extends JApplet{
public void paint(Graphics page){
page.setColor(Color.green);
page.fillRect(0,150,400,50);
}
}
The HTML file (test.html) that I then embedded that into looks like:
<html>
<body>
<applet code="Box", height="200" width="400">
</applet>
</body>
</html>
I then compiled/saved the Java bit, and put the two into the same folder. However, when I attempt to view the html file, all I see is an "Error. Click for details" box. I tested this in both the most current version of Fire Fox and Opera, and too did I make sure that the Java plug-in was enabled and up to date for both.
So what exactly am I forgetting to do here?
It seems as if everything is close to OK.
Once the .class file is in the same folder as your HTML file it should come up. Your code might contain a typos (comma after "Box").
Example :
<Applet Code="MyApplet.class" width=200 Height=100>
See also :
http://www.echoecho.com/applets01.htm
#Juser1167589 I hope your not still having issues with this, but if you are, try going into your program files, delete the JAVA folder, then redownload java from the big red button on 'java.com'. If there is no JAVA folder then * FACEPALM * GO DOWNLOAD JAVA. another possible answer to why you were seeing the errors on the other sites is that they might not have the required resources to run it anymore.
Applets are not a good place to start.
They are a very old technology and really not very widely used compared to other parts of the Java technology stack.
If you're new to programming in general, I really wouldn't start with applets.
Instead, you should try learning basic programming and Java by building some simple console apps. I've added some general comments about how to do this. After your confidence rises, you can then start worrying about adding extra complexity, applets etc.
First of all download an IDE. Eclipse is one obvious choice (there are also NetBeans and IntelliJ). All modern developers work within an IDE - don't be tempted to try to muddle through without one.
Then, you should have a "scratchpad" - a class where you can try out some simple language features. Here's one which might be useful:
package scratch.misc;
public class ScratchImpl {
private static ScratchImpl instance = null;
// Constructor
public ScratchImpl() {
super();
}
/*
* This is where your actual code will go
*/
private void run() {
}
/**
* #param args
*/
public static void main(String[] args) {
instance = new ScratchImpl();
instance.run();
}
}
To use this, save this as a .java file. It can be a template for other simple experiments with Java. If you want to experiment with a language feature (inheritance, or polymorphism, or collections or whatever you want to learn) - then copy the template (use the copy and rename features inside your IDE, rather than manually copying the file and changing the type names) to a new name for your experiment.
You may also find some of my answer here to be useful.

How to call a user defined Matlab from Java using matlabcontrol.jar

I am trying to call a user defined Matlab Function(M file) which takes 3 arguments(Java Strings) from my Java application which is developed in Eclipse. At the moment I am able to call proxy.eval and proxy.feval methods with the functions/commands like disp or sqr. But when i try to invoke a user-defined function it says on the matlab console that there is no such function defined like that and on the Java console MatlabInvocationException occurs.
Then I tried with a simple user-defined function which takes no arguments and just has single line disp('Hello') but still the result is same. So I think rather than a type conversion problem there is something wrong with how user-defined functions are getting invoked.
Please can anyone help me soon? I am meeting the deadline very soon for this project. I would be so thankful if someone can come up with a solution. (Mr Joshuwa Kaplan, is there any guide on solving an issue like this in your posts? I tried but found nothing)
Thanks in advance
You must have any user-defined m-files on the MATLAB search path, just as if you were working normally inside MATLAB.
I tested with the following example:
C:\some\path\myfunc.m
function myfunc()
disp('hello from MYFUNC')
end
HelloWorld.java
import matlabcontrol.*;
public class HelloWorld
{
public static void main(String[] args)
throws MatlabConnectionException, MatlabInvocationException
{
// create proxy
MatlabProxyFactoryOptions options =
new MatlabProxyFactoryOptions.Builder()
.setUsePreviouslyControlledSession(true)
.build();
MatlabProxyFactory factory = new MatlabProxyFactory(options);
MatlabProxy proxy = factory.getProxy();
// call builtin function
proxy.eval("disp('hello world')");
// call user-defined function (must be on the path)
proxy.eval("addpath('C:\\some\\path')");
proxy.feval("myfunc");
proxy.eval("rmpath('C:\\some\\path')");
// close connection
proxy.disconnect();
}
}
We compile and run the Java program:
javac -cp matlabcontrol-4.0.0.jar HelloWorld.java
java -cp ".;matlabcontrol-4.0.0.jar" HelloWorld
a MATLAB session will open up, and display the output:
hello world
hello from MYFUNC
You could also add your folder to the path once, then persist it using SAVEPATH. That way you won't have to do it each time.

Categories