Forum: PC-Programmierung JAVA Hintergrundanwendung


von Markus H. (gammeltante)


Lesenswert?

Grüß euch zusammen

ich möchte gerne ein Java Programm im Hintergrund laufen lassen. 
Beispielsweise eine Anwendung, die Temperaturdaten ausließt und 
anschließend in eine .txt reinschreibt.

Damit das Programm nicht stört soll es im Hintergrund laufen.
ABER: Wenn der Benutzer die aktuelle Temperatur nachschauen will soll 
dies über die "notification icons" (rechts unten - neben der Systemuhr) 
möglich sein. Also dass man mit einem Klick dann ein Fenster mit den 
entsprechenden Infos öffnen kann.

Das Programm soll bei Systemstart gestartet und bei Herunterfahren 
gestoppt werden.

Wie kann ich so etwas realisieren?

1. Auto-Programmstart (==> .bat in Autostart??? gehts auch schöner?)
2. Programm im Hintergrund
3. notification icons
4. Programm-Ende bei shutdown

(Ich habe schon eine Weile mit den Daemon Threads rumgeeiert, aber ich 
glaube dass sie nicht das richtige für meinen Anwendungsfall sind...)

Vielen Dank für eure Hilfe

von meine fresse (Gast)


Lesenswert?

Ich nehme an, du sprichst von Windows. Autostart ist nicht der richtige 
Weg, da nicht funktioniert, solange kein Benutzer angemeldet ist... was 
du brauchst ist die JVM als Service zu starten. In Linux geht das 
schöner, indem man das in run level 3 startet. Schaue dich mal um in 
Richtung Java als Service starten.

von Udo S. (urschmitt)


Lesenswert?

meine fresse schrieb:
> Schaue dich mal um in Richtung Java als Service starten.
Geht aber da läuft eine komplette Java VM im Hintergrund. Kanonen auf 
Spatzen...

Markus H. schrieb:
> ABER: Wenn der Benutzer die aktuelle Temperatur nachschauen will soll
> dies über die "notification icons" (rechts unten - neben der Systemuhr)
> möglich sein.
Heisst das nicht "System tray"?
Da sehe ich jetzt nur das in C über die entsprechende Windows API zu 
implementieren und dann via JNI einzubinden.

Ich würde dann eher das ganze Programm in C / C++ oder C# schreiben.

von Peter II (Gast)


Lesenswert?

Udo Schmitt schrieb:
> Heisst das nicht "System tray"?
> Da sehe ich jetzt nur das in C über die entsprechende Windows API zu
> implementieren und dann via JNI einzubinden.

für java gibt es auch System tray klassen. Aber ein Dienst soll NIE 
direkt mit der GUI arbeiten. Es sollte also 2 Programme geben. Ein 
Dienst für das Abfrufen der daten und eine Autostart anwendung für die 
System tray. Diese kommuniziert dann mit dem Dienst.

ja ich würde es auch mit C# machen

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Udo Schmitt schrieb:
> Da sehe ich jetzt nur das in C über die entsprechende Windows API
> zu implementieren und dann via JNI einzubinden
Java sieht das anders: 
http://docs.oracle.com/javase/tutorial/uiswing/misc/systemtray.html

Für den "Hintergrund":
http://jsmooth.sourceforge.net/
bietet auch einen Servicewrapper an, das TrayIcon sollte dann aber in 
der Trat eine eigene Anwendung im Autostart werden.

von Udo S. (urschmitt)


Lesenswert?

Läubi .. schrieb:
> Udo Schmitt schrieb:
>> Da sehe ich jetzt nur das in C über die entsprechende Windows API
>> zu implementieren und dann via JNI einzubinden
> Java sieht das anders:
> http://docs.oracle.com/javase/tutorial/uiswing/mis...

Sieh an, das wusste ich noch gar nicht.
Liegt wohl daran, daß unsere Anwendungen zum einen auch auf Unixen 
laufen müssen und ausserdem wir gerade erst auf Java 1.5 als 
Voraussetzung umgestiegen sind, da wir davon ausgehen müssen, dass 
unsere Kunden noch ältere Java Versionen benutzen Banken halt :-(.

Danke euch, wieder was gelernt :-)

Läubi .. schrieb:
> Für den "Hintergrund":
> http://jsmooth.sourceforge.net/
> bietet auch einen Servicewrapper an, das TrayIcon sollte dann aber in
> der Trat eine eigene Anwendung im Autostart werden.

Wenn das ein Service werden soll der schon ohne User läuft auf jeden 
Fall.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Udo Schmitt schrieb:
> daß unsere Anwendungen zum einen auch auf Unixen
> laufen müssen

Funktioniert zumindest unter Debian problemlos, auch wen "schön" sicher 
was anderes ist...

Udo Schmitt schrieb:
> und ausserdem wir gerade erst auf Java 1.5 als
> Voraussetzung umgestiegen sind

Mein Beileid mit pre 1.5 arbeite ich nur unter Protest ;-P
1.6 ist auch nochmal ein Stück konsistenter als 1.5 und die Desktop API 
besonders bei der GUI Entwicklung ganz hilfreich, bei mir wird wohl die 
nächsten Jahre irgendwann der Umstieg auf 1.7 erfolgen, einfach weil 1.6 
schon offiziell gar nicht mehr unterstützt wird (also auf neuen Systemen 
nur noch über Umwege installierbar).

Udo Schmitt schrieb:
> da wir davon ausgehen müssen, dass
> unsere Kunden noch ältere Java Versionen benutzen

Man kann JVMs auch wunderbar parallel installieren oder als Bundle 
ausliefern.

von Udo S. (urschmitt)


Lesenswert?

Läubi .. schrieb:
> Mein Beileid mit pre 1.5 arbeite ich nur unter Protest ;-P
> 1.6 ist auch nochmal ein Stück konsistenter als 1.5 und die Desktop API
> besonders bei der GUI Entwicklung ganz hilfreich, bei mir wird wohl die
> nächsten Jahre irgendwann der Umstieg auf 1.7 erfolgen, einfach weil 1.6
> schon offiziell gar nicht mehr unterstützt wird (also auf neuen Systemen
> nur noch über Umwege installierbar).

Wir sind gerade vor einem halben Jahr von 1.4 auf 1.5 umgestiegen. Gott 
sei Dank.
Auf meinem neuen Rechner habe ich jetzt 1.7 drauf, als 64 Bit Version 
und bin sofort in die ODBC Falle getappt (32 versus 64 bit) Vor allem da 
man für Access nicht einen Treiber für beide Versionen installieren kann 
und ein 64 Bit ODBC Treiber es notwendig macht das komplette 32 Bit 
Office (Version ohne Access!!!) runterzuschmeissen.
Das ist mal wieder die absolute Krönung von MS!

Läubi .. schrieb:
> Man kann JVMs auch wunderbar parallel installieren oder als Bundle
> ausliefern.
Nicht wenn man Banken als Kunden hat. Vor allem wenn diese Banken in 
Liechtenstein, Schweiz und Luxemburg Ableger haben und vollkommen 
durchdrehen wegen der Gefahr daß mal wieder eine CD an Schäuble 
geschickt werden könnte...

Viel Spass noch ...
Grüße
Udo

von Markus H. (gammeltante)


Lesenswert?

Grüß euch zusammen,
vielen Dank für eure Antworten!
Ich habe mit dem TrayIcon angefangen und das funktioniert auch schon.
Im Popup-Menü wird "Start" und "Exit" angezeigt.
Mit Exit wird das TrayIcon geschlossen. ==> funktioniert bereits.
ABER:
Mit Start soll ein externes Java Programm gestartet werden.
Und das bekomme ich nicht hin?
Wie kann ich ein externes Programm starten?

Anbei mein bisheriger Code:
1
public class Merch {
2
    public static void main(String[] args) {
3
        SwingUtilities.invokeLater(new Runnable() { 
4
            public void run() {
5
                createAndShowGUI();
6
            }
7
        });
8
    }
9
10
private static void createAndShowGUI(){
11
    
12
    // Wird der SystemTray unterstuetzt?
13
    if(!SystemTray.isSupported()){
14
        System.out.println("SystemTray wird nicht unterstuetzt!");
15
        return;
16
    }
17
    
18
    final PopupMenu popup = new PopupMenu();
19
    final TrayIcon trayIcon = new TrayIcon(createImage("images/test.gif", "tray icon"));
20
    final SystemTray tray = SystemTray.getSystemTray();
21
    trayIcon.setImageAutoSize(true);
22
23
    // Popup Menue Komponenten
24
    MenuItem startItem = new MenuItem("Start");
25
    MenuItem exitItem = new MenuItem("Exit");
26
27
    // Komponenten einfuegen und anordnen
28
    popup.add(startItem);
29
    popup.addSeparator();
30
    popup.add(exitItem);
31
32
    trayIcon.setPopupMenu(popup);
33
34
    try {
35
        tray.add(trayIcon);
36
    } catch (AWTException e) {
37
        System.out.println("tray.add konnte nicht ausgefuehrt werden");
38
        return;
39
    }
40
    
41
    // Programm starten "Start"    
42
    
43
    // ActionListener fuer Tray Button Exit 
44
    exitItem.addActionListener(
45
            new ActionListener() {
46
                public void actionPerformed(ActionEvent e) {
47
                    tray.remove(trayIcon);
48
                    System.exit(0);
49
                }
50
            });
51
}
52
53
    // erstellt ein neues Image und lädt das Image der URL hinein
54
    protected static Image createImage(String path, String description) {         URL imageURL = Merch.class.getResource(path);                           
55
56
        if (imageURL == null) {
57
            System.err.println("Image not found: " + path);
58
            return null;
59
        } else {
60
            return (new ImageIcon(imageURL, description)).getImage();
61
        }
62
    }
63
64
65
} // MAIN ENDE

von Robert L. (lrlr)


Lesenswert?

>Mit Start soll ein externes Java Programm gestartet werden.

wozu denn das ??
ist doch schon ein Java Programm


egal:

wo ist der ActionListener für StartItem ??
ohne den, wird sich nix tun

von Udo S. (urschmitt)


Lesenswert?

Markus H. schrieb:
> Wie kann ich ein externes Programm starten?

Schau dir mal die Klasse java.lang.ProcessBuilder an.

von Markus H. (gammeltante)


Lesenswert?

Peter II schrieb:
> für java gibt es auch System tray klassen. Aber ein Dienst soll NIE
> direkt mit der GUI arbeiten. Es sollte also 2 Programme geben. Ein
> Dienst für das Abfrufen der daten und eine Autostart anwendung für die
> System tray. Diese kommuniziert dann mit dem Dienst.

Ich bin jetzt bissl verwirrt, was ich wo am Besten realisiere...

Von Vorne:
Es soll ein Programm entstehen, dass Temperaturdaten von einem Sensor 
ausliest. Das soll irgendeine Hintergrundanwendung erledigen, die bei 
Systemstart beginnt und bei shutdown aufhört. Die Hintergrundanwendung 
schreibt alle 10 Minuten die Daten des Sensors in ein .txt.
Dann soll es noch ein Programm mit GUI geben. Dieses soll über das 
TrayIcon gestartet werden. Das Programm mit GUI soll es dem Benutzer 
ermöglichen die Werte der .txt anzuschauen, mit einem anderen Wert zu 
vergleichen, drucken,...

Was schreib ich jetzt wo?
Also die Hintergrundanwendung sollte soweit ich das verstanden habe ein 
Dienst sein.
Was ist dann der TrayIcon Teil? Er sollte laut Peter II ja niemals ein 
Dienst sein und mit einer GUI arbeiten.

Ich habe Schwierigkeiten mit dem gegenseitigen Zugriff und Aufruf.

> ja ich würde es auch mit C# machen
Nun, das ist leider Vorgabe...

von Robert L. (lrlr)


Lesenswert?

schreib einen Dienst
und eine GUI Anwendung

kommunizieren brauchen die ja eh "kaum"
da reicht vermutlich ein File-Lock während neue werte geschrieben 
werden..

von Udo S. (urschmitt)


Lesenswert?

Muss es wirklich ein Dienst sein, der unabhängig von einem Benutzer 
gestartet werden soll?
Ich würde mir eher überlegen ob das ein Programm ist das im Usercontext 
(also nach dem Einloggen) (automatisch?) gestartet wird und einen Daemon 
Prozess zum Einlesen der Daten startet.

von Robert L. (lrlr)


Lesenswert?

weils mir gerade einfällt

>Usercontext
>(also nach dem Einloggen)

das geht natürlich auch vor dem einloggen (per scheduler/geplanter task) 
irgendwie

wäre vielleicht tatsächlich besser...

von Peter II (Gast)


Lesenswert?

Robert L. schrieb:
> wäre vielleicht tatsächlich besser...

nö, weil so eine Anwendung dann auch mehrfach gestartet werde könnte. 
Ein Dienst läuft genau einmal. Auch muss der Nutzer dann noch die 
notwendigen rechte haben.

von Markus H. (gammeltante)


Lesenswert?

Robert L. schrieb:
> schreib einen Dienst
> und eine GUI Anwendung

Und wo pack ich den TrayIcon Teil rein? In die GUI Anwendung, oder?

von Udo S. (urschmitt)


Lesenswert?

Peter II schrieb:
> nö, weil so eine Anwendung dann auch mehrfach gestartet werde könnte.

Das könnte man entsprechend verhindern.
Selbst über mehrere User.
Die Frage ist doch wie hochverfügbar, DAU-resistent und sonstwie 
aufwendig muss das werden.
Oder misst der TO AKW Kerntemperaturen?

von Peter II (Gast)


Lesenswert?

Markus H. schrieb:
> Und wo pack ich den TrayIcon Teil rein? In die GUI Anwendung, oder?

ja in den GUI Teil - TrayIcon ist nun mal ein teil der Gui.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Udo Schmitt schrieb:
> Nicht wenn man Banken als Kunden hat. Vor allem wenn diese Banken in
> Liechtenstein, Schweiz und Luxemburg Ableger haben und vollkommen
> durchdrehen wegen der Gefahr daß mal wieder eine CD an Schäuble
> geschickt werden könnte...

Hehe, ja diese ganzen bösen JVMs die heimlich Steuer CDs brennen :-)

Markus H. schrieb:
> Die Hintergrundanwendung schreibt alle 10 Minuten
> die Daten des Sensors in ein .txt
Ich würde das ganze gleich in eine Mysql DB schreiben, aus diese kannst 
du dann von beliebigen (auch Trayicon basierten) Anwendungen zugreifen 
und sparst dir eine Menge Ärger.

von Markus H. (gammeltante)


Lesenswert?

> Ich würde das ganze gleich in eine Mysql DB schreiben, aus diese kannst
> du dann von beliebigen (auch Trayicon basierten) Anwendungen zugreifen
> und sparst dir eine Menge Ärger.

Das würde ich wirklich sehr gerne machen! Ich bin Java Anfänger und muss 
mich da erst in die Materie einlesen. Zumal ich Anfang März fertig sein 
will.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.