<The previous article in this series | The table of contents of this series | The next article in this series>
To Know How to Use Swing GUIs in UNO Extensions (LibreOffice Extensions or Apache OpenOffice Extensions)
About: UNO (Universal Network Objects)
About: LibreOffice
About: Apache OpenOffice
About: Java Programming Language
Here are -Hypothesizer and -Rebutter sitting in front of a computer screen in a room on a brook among some mountains on the Bias planet.
We are going to implement GUIs in our UNO Extensions.
Well, . . . why not? As we can develop UNO extensions in Java, we can just use JavaFX, Swing, or whatever in them, can't we?
In fact, that isn't the case. There are some things we have to be aware of.
Oh? What are they?
The most important thing is, we don't seem to be able to use JavaFX in UNO extensions on Linux.
That seems to imply that we can use JavaFX in UNO extensions on Windows.
Based on the fact that I can show some simple dialogs of JavaFX on Windows, I guess so. In fact, I haven't investigated further because as our main machine is Linux, being able to use it only on Windows isn't helpful for us.
Why can't we use JavaFX in UNO extensions on Linux?
This is my guess. JavaFX uses GDK while LibreOffice does so too. As JavaFX tries to create its main loop of GDK, the main loop doesn't seem to be able to coexist with the main loop of GDK of LibreOffice in the same process.
Ah, as JavaFX programs are supposed to be executed as explicit FX program instances, it might be natural that we can't use JavaFX in a JVM that resides in the LibreOffice program instance.
So, what happens if we try to use JavaFX in UNO extensions on Linux?
The initialization of JavaFX freezes without being able to receive some events to be received. So, the whole LibreOffice program instance freezes.
Hmm, . . . so, isn't there any evasive maneuver?
At least, I don't know one, although there is an ultimate solution.
What is that?
We can create a GUIs server as a UNO server.
Ah, as we discussed in the series, 'How to Use UNO (Handle LibreOffice or Apache OpenOffice Documents) in External Java Programs', we can create UNO servers. As a UNO server is an independent Java program, there can't be any restriction in using JavaFX or whatever Java features.
As we can use Swing all right (although there is a pitfall as we will discuss later), we will defer pursuing that solution to another occasion.
All right.
Note that there is a GUI library that is recommended for use in UNO extensions, but we won't comply because . . .
. . . we are of warped personalities?
That's not the reason here although we are, to some degree. The reason is that I don't expect that library to be as handy or rich in functionality as Swing or JavaFX is.
Is that based on some facts?
It's rather a wild guess. . . . Another reason is that I don't want to learn how to use another GUI library just for developing UNO extensions.
That's understandable.
If necessary, we will opt for the GUIs server solution, not for using that GUI library.
The same with the previous scene.
We can use Swing in UNO extensions all right, but there is one thing we have to do before we begin using Swing.
What is that?
-Hypothesizer opens a Java source file and points to a line.
We have to call this line.
Thread.currentThread ().setContextClassLoader (ClassLoader.getSystemClassLoader ());
Well, . . . are we registering a class loader into the current thread?
Yes. Swing uses it, but it isn't registered in the JVM prepared by LibreOffice, somehow.
Hmm. . . . So, once we do that, can we use Swing in UNO extensions with no problem?
As far as I know, yes.
The same with the previous scene.
We will create a sample.
How about creating a control panel that has buttons, each of which launches a function?
A control panel is fine, but what functions, for example?
Well, . . . how about a cell editor?
What do you mean by 'cell editor'?
Spread sheets are handy in organizing data in a grid, but when we put a long text in a cell, it's cumbersome to see or edit the text inside the cell.
In fact, when we deal with only numbers and short texts, it's fine, but if we have to deal with also long texts, spread sheets tend to be practically unusable.
If we can handle long texts in our cell editor, we will be able to handily use spread sheets also in such cases.
Hmm . . .
In this article, we will concentrate on creating the control panel: the cell editor is a dummy in this stage.
Well, as we already know how to read from and write to spread sheet cells, creating a cell editor is just a matter of Java programming, once we know how to use GUIs in UNO extensions.
Exactly.
Showing the control panel is just a matter of Swing programming, but here, we will show the control panel in an appropriate place relative to the current LibreOffice frame.
Ah, so, we don't want the control panel to be shown at a random or a fixed position on the screen.
We will show the control panel adjacent to the left border of the current LibreOffice frame.
What if there is no space there?
Then, we will have to show it on the current LibreOffice frame.
Wherever we want to show it, the matter is how we can get the geometry of the borders of the current LibreOffice frame.
We can get it like this.
-Hypothesizer selects a section of the Java source file.
import com.sun.star.awt.XWindow;
import com.sun.star.frame.XDesktop;
import com.sun.star.frame.XFrame;
import thebiasplanet.unoutilities.constantsgroups.*;
import thebiasplanet.unoutilities.serviceshandling.UnoServiceHandler;
XDesktop l_unoDesktopInXDesktop = (XDesktop) UnoServiceHandler.getServiceInstance (i_componentContextInXComponentContext, UnoServiceNamesConstantsGroup.c_com_sun_star_frame_Desktop, XDesktop.class);
XFrame l_unoFrameInXFrame = l_unoDesktopInXDesktop.getCurrentFrame ();
XWindow l_desktopContainerWindowInXWindow = l_unoFrameInXFrame.getContainerWindow ();
com.sun.star.awt.Rectangle l_desktopContainerWindowBoundary = l_desktopContainerWindowInXWindow.getPosSize ();
Rectangle l_applicationContainerWindowBoundary = new Rectangle (l_desktopContainerWindowBoundary.X, l_desktopContainerWindowBoundary.Y, l_desktopContainerWindowBoundary.Width, l_desktopContainerWindowBoundary.Height);
Well, classes under the 'thebiasplanet' package are our utility classes.
As for codes already explained in previous articles, we may not repeat explicitly citing them, but use our utility classes. As our utility classes are included in our zip files, see inside them if necessary.
All right.
Our sample program is here.
You have implemented into the sample UNO extension project cited before.
Yes. How to use the zip file is written there. Note that as we add codes into projects cited in some articles, projects cited in an article can include some codes that are irrelevant to the article: those codes have come from other articles.
-Hypothesizer runs the gradle command, which finishes successfully. -Hypothesizer opens the 'TestSpreadSheetsDocumentForExecutingTests.ods' spread sheets document.
You have added the second button on the sheet.
Yes. Before we push the button, we have to import the LibreOffice Basic library, as described in the previous article.
-Hypothesizer clicks the 'Show Test Control Panel' button; a tiny dialog box shows adjacent to the left border of the current LibreOffice frame.
. . . It's unimpressive to be called a 'control panel' . . .
Unimpressive or not, it's a control panel. Clicking the 'Edit Cell' button shows the cell editor.
-Hypothesizer clicks the 'Edit Cell' button; a dummy window opens.
At this stage, the window is a dummy, without showing any cell datum.
<The previous article in this series | The table of contents of this series | The next article in this series>