Ich habe angefangen, diesen Artikel zu schreiben, als ich versuchte, ihn auf JavaFX Adventskalender 2017 zu veröffentlichen, aber ich konnte mir aufgrund von Arbeit und Influenza keine Zeit nehmen, also später Es ist für die Öffentlichkeit zugänglich.
In der Ecke des Desktops befindet sich ein Desktop-Gadget, das kleine GUI-Funktionen wie Uhren und Kalender anzeigt. Früher war es ein Gadget von Windows Vista / 7, wie z. B. xclock und oclock von X Window System. Windows-Gadgets sind jedoch seit Windows 8 aufgrund von Sicherheitslücken veraltet.
Wenn Sie in Windows 8 oder höher (10 usw.) ein Desktop-Gadget möchten, müssen Sie daher separat nach einem solchen Programm suchen, es abrufen und verwenden. Es gibt viele kostenlose Software, die wie Desktop-Gadgets aussieht, aber ich dachte, es wäre gut für Programmierer, ihre eigenen Gadgets zu verwenden, also habe ich ein wenig mit JavaFX gemacht. Dieser Bereich wurde in der nächsten Sitzung auf der JJUG CCC 2017 Spring vorgestellt.
Als Desktop-Gadget wollte ich eine Uhr und einen Kalender, also habe ich ein Kalender-Gadget erstellt, das dem Uhr-Gadget folgt.
Dieses Mal besteht der Inhalt darin, das mit Java SE 8 erstellte Kalender-Gadget mit Java SE 9 kompatibel zu machen.
Das Kalender-Gadget verwendet das DatePicker-Steuerelement von JavaFX, um einen kleinen Kalender (Monat) in einer Ecke des Desktops anzuzeigen.
Das Programm-Repository (Quellcode) lautet wie folgt (Github). CalendarGadget
Dieses Programm ist in Java SE 8 geschrieben. Ich habe im folgenden Blog geschrieben, wie man mit Java SE 8 ein Kalender-Gadget erstellt.
Die entsprechende Richtlinie wird nachstehend kurz beschrieben. Beschreiben Sie anschließend die Korrespondenzdetails der einzelnen Artikel.
Der Kalenderanzeigeteil des DatePicker-Steuerelements verwendet die DatePickerSkin-Klasse, die beim Wechsel von Java SE 8 zu Java SE 9 einen Paketnamen hat.
Von
Es wurde geändert in. Es wurde von einer internen API auf eine öffentliche API aktualisiert. Sie müssen jedoch den Quellcode für Java SE 8 und 9 ändern.
Ab Java SE 9 wurde zusätzlich zu der herkömmlichen Methode zum Referenzieren von Klassendateien und JAR-Dateien zur Laufzeit eine Methode zum Referenzieren von Moduldateien zur Laufzeit mit dem Modulpfad hinzugefügt.
Da es sich um eine große Sache handelt, werden wir hier dem Modul entsprechen.
Das Kalender-Gadget markiert das heutige Datum, sodass Sie das aktuelle Datum sehen können (ein Rechteck umgibt den heutigen Tag). Wenn sich das Datum ändert, während Sie das Kalender-Gadget ausführen, müssen Sie daher die Markierungen am heutigen Datum auf den nächsten Tag ändern. Beim Erstellen mit Java SE 8 wird die Zeit bis zum Ende des Tages berechnet, wenn das Kalender-Gadget gestartet wird, und der Vorgang zum Aktualisieren des heutigen Datums wird nach Ablauf dieser Zeit ausgeführt (implementiert mit ScheduledExecutorService). ..
Wenn jedoch der PC, auf dem das Gadget ausgeführt wird, in den Ruhezustand oder in den Ruhezustand wechselt, wird dieser Vorgang nicht zum gewünschten Zeitpunkt aktiviert. Daher versuche ich, den Prozess der Datumsaktualisierung stündlich als sorgfältige Maßnahme zu überprüfen.
Ab Java SE 9 wurde die Möglichkeit hinzugefügt, anhand eines Ereignisses zu erkennen, dass ein PC in den Ruhezustand oder Ruhezustand eingetreten ist und aus dem Ruhezustand oder Ruhezustand wiederhergestellt wurde.
Daher werde ich diese Veranstaltung nutzen.
Benennen Sie das DatePickerSkin-Paket um, das das erste Java SE 9-Supportelement ist.
CalendarGadgetApp.java
- import com.sun.javafx.scene.control.skin.DatePickerSkin;
+ import javafx.scene.control.skin.DatePickerSkin;
Unterstützt das Java-Modulsystem, das das zweite Java SE 9-Unterstützungselement ist. Dieses Mal werde ich hauptsächlich die Korrespondenz mit NetBeans beschreiben.
NetBeans 9 für Java SE 9 (JDK 9) wurde zu diesem Zeitpunkt noch nicht offiziell veröffentlicht. Daher werden wir die Entwicklungsversion von NetBeans 9 verwenden. http://bits.netbeans.org/download/trunk/nightly/latest/
In NetBeans 9 ist der dem Modulsystem entsprechende Projekttyp Java Modular Project. Projekttypen wie JavaFX-Anwendungen sind nicht mit Modulsystemen kompatibel. Daher werde ich das Projekt einmal neu erstellen.
Erstellen Sie ein leeres Arbeitsverzeichnis und erstellen Sie zwei neue Projekte darunter.
Das Folgende ist der erste Schritt auf dem Bildschirm des Assistenten für neue Projekte. [Java Modular Project] wurde der Kategorie [Java] hinzugefügt.
Weiter ist der nächste Schritt auf dem Bildschirm des Assistenten für neue Projekte. Geben Sie den Speicherort und den Projektnamen an, um das Projekt zu erstellen.
Das Java Modular Project kann mehrere Module unter einem Projekt enthalten. Das Modul ist zunächst leer. Dieses Mal werden wir nur ein Modul in jedes der beiden von uns erstellten Projekte aufnehmen.
Definieren Sie in jedem Projekt ein Modul.
Der nächste Schritt besteht darin, ein Projekt auszuwählen und ein Modul hinzuzufügen.
Geben Sie im Bildschirm Neues Modul den Modulnamen ein.
Der Modulname ist der wichtigste Paketname der zu veröffentlichenden Pakete (gemäß der Namenskonvention von Java Language Specification 6.1).
Wenn Sie ein Modul erstellen, wird module-info.java generiert.
Im Gegensatz zu herkömmlichen NetBeans-Projektkonfigurationen wird unter dem Projekt ein Modulordner erstellt, darunter ein Klassenordner und hier das Quelldateipaket. Da module-info.java auf der obersten Ebene bereitgestellt wird (kein Paketname), wird es in das eingefügt, was NetBeans als
Die Verzeichnisdateistruktur ist wie folgt.
Bringen Sie die Quelldatei hierher. Wenn ich die Quelldatei einbringe, ist die Importanweisung fehlerhaft.
Wir werden die Moduldefinition des Moduls com.torutk.gadget.support des GadgetSupport-Projekts beschreiben.
Wenn Sie im Java SE 9-Modulsystem eine andere Klasse als die zum Modul java.base gehörende verwenden, müssen Sie das Modul, das die Klasse enthält, die in der Moduldefinitionsdatei (module-info.java) verwendet werden soll, explizit beschreiben.
Eine Fehlermeldung wird angezeigt, wenn Sie den Cursor auf die Markierung (: Ausrufezeichen :) am Anfang der Fehlerzeile setzen. Der folgende Bildschirm zeigt einen Fehler in java.util.prefs.Preferences an.
Fügen Sie das Modul java.prefs gemäß der Fehlermeldung zu module-info.java hinzu.
module-info.java
module com.torutk.gadget.support {
requires java.prefs;
}
Fügen Sie in ähnlicher Weise die Modulverwendungsbeschreibung hinzu, die dem Fehler der verbleibenden Importanweisung entspricht.
Die Fehlermeldung sagt uns, dass wir zwei Module benötigen, javafx.graphics und javafx.controls. Sie können diese beiden Module in module-info.java beschreiben. Da jedoch javafx.graphics und javafx.controls eine Übergangsabhängigkeit aufweisen, geben Sie in der Moduldefinition auf der Anwendungsseite nur javafx.controls an. Wird geklärt werden.
module-info.java
module com.torutk.gadget.support {
requires java.prefs;
requires javafx.controls;
}
Die Moduldefinition von javafx.controls enthält die folgende Beschreibung.
requires transitive javafx.base;
requires transitive javafx.graphics;
Da transitiv angegeben ist, sind zwei Module, javafx.base und javafx.graphics, automatisch für Module verfügbar, die javafx.controls verwenden.
Da das GadgetSupport-Projekt eine Dienstprogrammbibliothek ist, müssen Sie das Paket com.torutk.gadget.support in Ihrer Anwendung (z. B. CalendarGadget) veröffentlichen.
module-info.java
module com.torutk.gadget.support {
requires java.prefs;
requires javafx.controls;
exports com.torutk.gadget.support;
}
Dies wird bauen. Kompilierte Klassendateien werden unter build / modules und JAR-Dateien unter dist generiert.
GadgetSupport
+-- build
| +-- modules
| +-- com.torutk.gadget.support
| +-- module-info.class
| +-- com
| +-- torutk
| +-- gadget
| +-- support
| +-- TinyGadgetSupport.class
+-- dist
: +-- com.torutk.gadget.support.jar
Wir werden die Moduldefinition des Moduls com.torutk.gadget.calendar des Calendar Gadget-Projekts beschreiben.
Dieses Mal verwende ich zusätzlich zur Java SE 9-Standard-API eine von mir erstellte Bibliothek (GadgetSupport). Fügen Sie daher in den Projekteinstellungen eine Bibliotheksabhängigkeit hinzu. GadgetSupport wurde als Modul erstellt. Legen Sie es also fest, indem Sie ein Modul hinzufügen.
Klicken Sie mit der rechten Maustaste auf das CalendarGadget-Projekt und wählen Sie Eigenschaften. Wählen Sie im linken Bereich Bibliotheken aus, klicken Sie im rechten Bereich auf die Registerkarte Kompilieren, klicken Sie auf das + ganz rechts in Modulepath und wählen Sie Projekt hinzufügen ...
Der Bildschirm Projekt hinzufügen wird geöffnet. Wählen Sie das Gadget-Support-Projekt aus. Anschließend wird die vom Projekt generierte JAR-Datei angezeigt.
Beschreiben Sie die abhängigen Module in der Moduldefinitionsdatei.
module-info.java
module com.torutk.gadget.calendar {
requires java.logging;
requires java.prefs;
requires javafx.controls;
requires com.torutk.gadget.support;
}
Ich habe einen Kompilierungsfehler, also werde ich es versuchen. Dann bekomme ich folgenden Fehler:
run:
Exception in Application constructor
Exception in thread "main" java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:945)
Caused by: java.lang.RuntimeException: Unable to construct Application instance: class com.torutk.gadget.calendar.CalendarGadgetApp
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:963)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:198)
at java.base/java.lang.Thread.run(Thread.java:844)
Caused by: java.lang.IllegalAccessException: class com.sun.javafx.application.LauncherImpl (in module javafx.graphics) cannot access class com.torutk.gadget.calendar.CalendarGadgetApp (in module com.torutk.gadget.calendar) because module com.torutk.gadget.calendar does not export com.torutk.gadget.calendar to module javafx.graphics
at java.base/jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:361)
at java.base/java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:589)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:479)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$8(LauncherImpl.java:875)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$11(PlatformImpl.java:449)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$9(PlatformImpl.java:418)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:417)
at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:175)
... 1 more
Hier sind die Meldungen, die die Hauptursache für den Fehler sind:
com.sun.javafx.application.LauncherImpl (in module javafx.graphics) cannot access
class com.torutk.gadget.calendar.CalendarGadgetApp (in module
com.torutk.gadget.calendar) because module com.torutk.gadget.calendar does not export
com.torutk.gadget.calendar to module javafx.graphics
Es besagt, dass auf die JavaFX-Anwendungsklasse CalendarGadgetApp über das Modul javafx.graphics zugegriffen werden muss.
Sie können es ausführen, indem Sie der Moduldefinitionsdatei die folgende Anweisung hinzufügen.
opens com.torutk.gadget.calendar;
Dieses Mal kann es mit Exporten anstelle von Öffnen ausgeführt werden. Wenn Sie jedoch in Zukunft FXML verwenden oder binden, ist ein Reflexionszugriff vom Javafx-Modul auf die Klasse auf der Anwendungsseite erforderlich. Daher muss Öffnen anstelle von Exporten verwendet werden. .. Geben Sie sich daher in der Moduldefinition der JavaFX-Anwendung mit opens an.
Dies ist der letzte der drei Punkte.
Erstens erhält es die Rückkehr aus dem Ruhezustand / Ruhezustand des Betriebssystems als Ereignis.
private void initResumeProc() {
Desktop desktop = Desktop.getDesktop();
desktop.addAppEventListener(new SystemSleepListener() {
@Override
public void systemAboutToSleep(SystemSleepEvent e) {
logger.info("Detect system about to sleep.");
}
@Override
public void systemAwoke(SystemSleepEvent e) {
logger.info("Detect system awake.");
if (schedule != null ) {
schedule.cancel(true);
}
crossoverDate();
}
});
}
Übergeben Sie eine Instanz der Implementierungsklasse der SystemSleepListener-Schnittstelle an die addAppEventListener-Methode, die von Java SE 9 zur java.awt.Desktop-Klasse hinzugefügt wurde. Wenn das Betriebssystem in den Ruhezustand versetzt oder in den Ruhezustand versetzt (angehalten) wird und wenn es aufwacht, wird die entsprechende Methode von SystemSleepListener aufgerufen. Stellen Sie diesmal den Datumsaktualisierungsprozess (crossoverDate-Methode) zu diesem Zeitpunkt erneut ein. Wenn der Zeitplan für die Aktualisierung des Datums bereits festgelegt wurde, brechen Sie den Zeitplan ab.
Das Kalender-Gadget-Repository mit Java SE 9-Unterstützung lautet wie folgt.
https://github.com/torutk/CalendarGadget/tree/jdk9_module
Recommended Posts