TimerTask Übergabe an andere Klasse

Chefselber

Mitglied
Hallo Gemeinde,

ich bekomme hier eine NullPointerException.
Vielleicht hat jemand Rat?!

Hier wird Aufgabe() aufgerufen

Java:
   public Gasübernahme() {
        initComponents();
         try
          {   
              BufferedImage image = ImageIO.read(new File("E:VISU/Gasübernahme.png"));     
            }
    catch (IOException e)
    {
      // log the exception
      // re-throw if desired
    }
      init();
        
         java.util.Timer timer = new java.util.Timer();
    
      timer.scheduleAtFixedRate(new Aufgabe(),10000,2000);
        
        
        
    }


// Klasse Aufgabe

Java:
public class Aufgabe extends TimerTask implements Runnable{
  
    private Gasübernahme gasübernahme;
   //  private Gaszufuhr gaszufuhr;
    
 
    
    
     @Override
    public void run() {
        
        Einlesen();
    }
 
    public Aufgabe()
    {
        
    
    
    }
    
  
    
    
    // hier die Daten lesen
    public void Einlesen()
    {
      
       gasübernahme.Einlesen();
      
  
    }
    
 
}

Selbst wenn ich mit new Aufgabe(this) den TimerTask starte, kommt eine Exception.

Was mache ich hier falsch?


MfG Chef
 
K

kneitzel

Gast
Die Instanzvariable gasübernahme wird nie gesetzt und ist daher null. Du musst der Variablen erst was zuweisen, damit du darauf Methoden aufrufen kannst.
 

Chefselber

Mitglied
Hallo,
vielen Dank für deine Antwort.

Also

Java:
timer.scheduleAtFixedRate(new Aufgabe(this),10000,2000);

und

Java:
public class Aufgabe extends TimerTask implements Runnable{
 
    private Gasübernahme gasübernahme;
   //  private Gaszufuhr gaszufuhr;
    
 
    
    
     @Override
    public void run() {
        
        Einlesen();
    }
 
    public Aufgabe(Gasübernahme gasübernahme)
    {
        this.gasübernahme = gasübernahme;
    
    
    }
    
 
    
    
    // hier die Daten lesen
    public void Einlesen()
    {
      
       gasübernahme.Einlesen();
      
 
    }
    
 
}


funktioniert aber auch nicht.
Ich versteh nicht warum!
 

Jw456

Top Contributor
Was ich bei deinem Code etwas unsinnig finde ist das runnable. Du erbst von timertask. Übergibst dieses Task an den Timer. Wozu das runnable?


Ein Objekt von deinem Gasübernahme erstellst du keines hast this den Context übergeben.
Das wäre dann ein Objekt des Aufrufer selbst.

Denn Context der aufrufen Klasse also den vom ui Thread übergibst du sicherlich weil du in dem timertask Thread Eine Ausgabe auf den UI machen willst. Nur ob das so geht aus einen Thread auf den UI zu kommen?
 
Zuletzt bearbeitet:

Chefselber

Mitglied
Ja Objekt aus dem TimerTask an die Aufgabe Klasse,

diese soll dann eine Methode in Gasübernahme beschreiben.



Entferne ich die Run Methode in Aufgabe kommt folgender Fehler:

Aufgabe is not abstract and does not override abstract run() in TimerTask.
 

Jw456

Top Contributor
Das wird nicht passen. Mit deinem this beim Aufruf übergibst du nicht die ref auf deine Klasse. In Android würde man den Context übergeben ob es diese Klasse auch unter Desktop java gibt weiß ich nicht.

public Aufgabe(Context context ) würde ich in Android machen. Ich denke es gibt etwas ähnliches im normalen java auch.
 

Chefselber

Mitglied
Wie übergibt man dann eine Instanz?

Also
Timer Klasse 2 (Aufgabe) wird von Klasse 1(BTB) aufgerufen.
Klasse 3 (Gasübernahme) bekommt Aufruf von Timer Klasse 2 (Aufgabe)

Das muss doch mit "this" funktionieren
 
K

kneitzel

Gast
Bitte lass Dich nicht verwirren. Du hast die Instanz von Gasübernahme richtig an den Konstruktor übergeben. Und diese weist Du auch korrekt der Instanzvariablen zu.

Der Punkt ist somit durchaus korrekt abgehakt. Daher wäre jetzt wichtig, was genau nicht funktioniert. Was für einen Fehler / Exception bekommst Du? Oder was ist das erwartete Verhalten und was für ein Verhalten hast Du?

Context gibt es auch in Java.
Und wozu sollte er javax.naming.Context bei seinem Problem wie nutzen?
 

Chefselber

Mitglied
Exception in thread "Timer-1" java.lang.NullPointerException: Cannot invoke "Moka7Demo.Gasübernahme.Einlesen()" because "this.gasübernahme" is null
at Moka7Demo.Aufgabe.run(Aufgabe.java:56)
at java.base/java.util.TimerThread.mainLoop(Timer.java:556)
at java.base/java.util.TimerThread.run(Timer.java:506)


bei diesem Code in Aufgabe:

Java:
 */
public class Aufgabe extends TimerTask implements Runnable
{
    private Gasübernahme gasübernahme;
     private Gaszufuhr gaszufuhr;
    
 
    
    
    
 
    public Aufgabe(Gasübernahme gasübernahme)
    {
        this.gasübernahme = gasübernahme;
    
    
    }
    
      public Aufgabe(Gaszufuhr gaszufuhr)
    {
        this.gaszufuhr = gaszufuhr;
    
    
    }
    
    
    // hier die Daten lesen
    public void Einlesen()
    {
      
    
      
  
    }

    @Override
    public void run() {
         gasübernahme.Einlesen();
    }

 
    
 
}
 
K

kneitzel

Gast
Zeig bitte die ganzen Klassen. So kann man nur raten.

Ein Rateversuch:
Ist das timer.scheduleAtFixedRate(new Aufgabe(this),10000,2000); wirklich in Gasübernahme? Oder hast Du das in Gaszufuhr (Weil Du da halt auch einen solchen Konstruktor hast?)

Weil es in der bisherigen Diskussion erwähnt wurde und von Dir wieder rückgängig gemacht wurde: Das "implements Runnable" kannst Du rausnehmen. Das ist aber nicht falsch. TimerTask hat das bereits und da Du von TimerTask ableitest hast Du das Interface schon drin. Aber es noch einmal anzugeben verändert nichts. Das extends TimerTasks musst Du aber natürlich haben, weil Timer.schedule ein TimerTask als Parameter haben will.
 

Chefselber

Mitglied
Guten Morgen,

hier mal aktueller Stand:

[CODE lang="java" title="Gasübernahme"]/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package Moka7Demo;
import java.awt.*;
import javax.swing.*;
import javax.imageio.*;
import java.io.*;
import java.net.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
/**
*
*
*/
public class Gasübernahme extends javax.swing.JFrame {


public static Komponenten V_931AK01 = new Komponenten();
public static Komponenten V_931AK02 = new Komponenten();
public static Komponenten P_931I41= new Komponenten();
/**
* Creates new form Gasübernahme
*
*/
public Gasübernahme() {
initComponents();
try
{
BufferedImage image = ImageIO.read(new File("E:/VISU/Gasübernahme.png"));
}
catch (IOException e)
{
// log the exception
// re-throw if desired
}
init();

java.util.Timer timer = new java.util.Timer();

timer.scheduleAtFixedRate(new Aufgabe(this),10000,2000);



}

/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {

jLabel6 = new javax.swing.JLabel();
jLabel5 = new javax.swing.JLabel();
jLabel4 = new javax.swing.JLabel();
jLabel3 = new javax.swing.JLabel();
jLabel1 = new javax.swing.JLabel();
jButton3 = new javax.swing.JButton();
jButton4 = new javax.swing.JButton();
jLabel2 = new javax.swing.JLabel();
jButton5 = new javax.swing.JButton();

setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
getContentPane().setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());

jLabel6.setText("931I42");
getContentPane().add(jLabel6, new org.netbeans.lib.awtextra.AbsoluteConstraints(940, 720, -1, -1));

jLabel5.setText("jLabel5");
getContentPane().add(jLabel5, new org.netbeans.lib.awtextra.AbsoluteConstraints(210, 710, -1, -1));

jLabel4.setText("jLabel4");
getContentPane().add(jLabel4, new org.netbeans.lib.awtextra.AbsoluteConstraints(570, 610, -1, -1));

jLabel3.setText("jLabel3");
getContentPane().add(jLabel3, new org.netbeans.lib.awtextra.AbsoluteConstraints(550, 740, -1, -1));

jLabel1.setText("jLabel1");
getContentPane().add(jLabel1, new org.netbeans.lib.awtextra.AbsoluteConstraints(610, 710, 100, -1));

jButton3.setText("931AK02");
jButton3.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton3ActionPerformed(evt);
}
});
getContentPane().add(jButton3, new org.netbeans.lib.awtextra.AbsoluteConstraints(790, 560, -1, -1));

jButton4.setText("931AK01");
jButton4.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton4ActionPerformed(evt);
}
});
getContentPane().add(jButton4, new org.netbeans.lib.awtextra.AbsoluteConstraints(260, 740, -1, -1));

jLabel2.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Moka7Demo/Gasübernahme.png"))); // NOI18N
jLabel2.setText("jLabel2");
getContentPane().add(jLabel2, new org.netbeans.lib.awtextra.AbsoluteConstraints(30, 20, 1320, 770));

jButton5.setText("jButton3");
getContentPane().add(jButton5, new org.netbeans.lib.awtextra.AbsoluteConstraints(500, 500, -1, -1));

pack();
}// </editor-fold>

private void init()
{
// Ventile
V_931AK01.Kennung = "DB";
V_931AK01.db_nr= 111;
V_931AK01.adresse = 54;
V_931AK01.bit = 0;

V_931AK02.Kennung = "DB";
V_931AK02.db_nr= 111;
V_931AK02.adresse = 58;
V_931AK02.bit = 0;

// Drucksensor
// P_931I41
P_931I41.Kennung = "DB";
P_931I41.db_nr= 102;
P_931I41.adresse = 26;

}

public void Einlesen(){
// jLabel6.setText( String.valueOf(Read.Read_float( 102, 26)));
jLabel6.setText("dfgdfgga");




}
// 931AK01
private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) {

if (V_931AK01.Anwahl){
V_931AK01.Anwahl = false;
Read.Write_Bit(V_931AK01.Anwahl, V_931AK01.db_nr, V_931AK01.adresse, V_931AK01.bit);
aktualisieren();
return;
}
if (!V_931AK01.Anwahl)
V_931AK01.Anwahl = true;
Read.Write_Bit(V_931AK01.Anwahl, V_931AK01.db_nr, V_931AK01.adresse, V_931AK01.bit);
aktualisieren();
}

private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {
if (V_931AK02.Anwahl){
V_931AK02.Anwahl = false;
Read.Write_Bit(V_931AK02.Anwahl, V_931AK02.db_nr, V_931AK02.adresse, V_931AK02.bit);
aktualisieren();
return;
}
if (!V_931AK02.Anwahl)
V_931AK02.Anwahl = true;
Read.Write_Bit(V_931AK02.Anwahl, V_931AK02.db_nr, V_931AK02.adresse, V_931AK02.bit);
aktualisieren();
}


private void aktualisieren()
{
if (V_931AK02.Anwahl)
{
jButton3.setBackground(Color.green);
}
else
{
jButton3.setBackground(Color.LIGHT_GRAY);
}
if (V_931AK01.Anwahl)
{
jButton4.setBackground(Color.green);
}
else
{
jButton4.setBackground(Color.LIGHT_GRAY);
}
}



/**
* @param args the command line arguments
*/
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(Gasübernahme.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(Gasübernahme.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(Gasübernahme.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(Gasübernahme.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>

/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
// new Gasübernahme().setVisible(true);

}
});
}

// Variables declaration - do not modify
private javax.swing.JButton jButton3;
private javax.swing.JButton jButton4;
private javax.swing.JButton jButton5;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
private javax.swing.JLabel jLabel3;
private javax.swing.JLabel jLabel4;
private javax.swing.JLabel jLabel5;
private javax.swing.JLabel jLabel6;
// End of variables declaration
}
[/CODE]


[CODE lang="java" title="Aufgabe Klasse"]/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package Moka7Demo;

import Moka7.S7;
import java.awt.Color;
import java.io.IOException;
import java.util.TimerTask;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.text.*;
import javax.swing.DefaultListModel;
/**
*
* @author
*/
public class Aufgabe extends TimerTask implements Runnable
{
private Gasübernahme gasübernahme;
private Gaszufuhr gaszufuhr;






public Aufgabe(Gasübernahme gasübernahme)
{
this.gasübernahme = gasübernahme;


}

public Aufgabe(Gaszufuhr gaszufuhr)
{
// this.gaszufuhr = gaszufuhr;


}


// hier die Daten lesen
public void Einlesen()
{




}

@Override
public void run() {
gasübernahme.Einlesen();
}




}[/CODE]
 
K

kneitzel

Gast
Ok, die main in Gasübernahme ist ja soweit alles auskommentiert - das verstärkt mich bei meiner Vermutung, dass Du eben nicht den Timer über Gasübernahme machst (mit dem Code, den Du hier zeigst) sondern dass Du über die Klasse Gaszufuhr gehst.

Prüf bitte genau, was Du startest und wo Du einen Timer erstellst. Die Stelle dürftest Du auch direkt finden als Fehler wenn Du den Konstruktor public Aufgabe(Gaszufuhr gaszufuhr) rauslöschst. Denn da, wo Du den Konstruktor nutzt, erzeugst Du eine Instanz von Aufgabe bei der gasübernahme null ist.
 

Jw456

Top Contributor
Eine zwischen Frage er startet den timer im construcktor von Gasübernahme. Wenn zu dem Zeitpunkt die Instanz schon verfügbar ist wäre das richtig.
Wann genau ist eine Instanz von einem Objekt fertig erstellt?

Was passiert wenn du garnichts in den timertask machst. Hast du da ich den Fehler.

Oder benutze Gasübernahme.this nicht nur this im sicher zugehen das du das richtige übergibst.
 

Jw456

Top Contributor
PS ich sehe gerade das du zwei fast gleiche construcktor in deinem timertask hast finde ich nicht gut. Bein Aufruf mit this ist nicht eindeutig welcher benutzt wird.
 
K

kneitzel

Gast
Eine zwischen Frage er startet den timer im construcktor von Gasübernahme. Wenn zu dem Zeitpunkt die Instanz schon verfügbar ist wäre das richtig.
Wann genau ist eine Instanz von einem Objekt fertig erstellt?
Die Instanz ist da schon verfügbar, aber die Initialisierung ist halt noch nicht durch. Dadurch kann es zu Problemen kommen a.la. eine Instanzvariable ist noch nicht initialisiert aber es wird bereits drauf zugegriffen und Du bekommst eine NPE.
Wenn dich der Ablauf bei der "Class Creation" interessiert: https://docs.oracle.com/javase/specs/jls/se16/html/jls-12.html#jls-12.5
Da findet sich auch die Reihenfolge, in der was passiert.

Oder benutze Gasübernahme.this nicht nur this im sicher zugehen das du das richtige übergibst.
Etwas in der Art ist nicht notwendig. So der Timer über den Konstruktor so erzeugt wird, würde es funktionieren. Das kann man so auch jederzeit austesten.
 
K

kneitzel

Gast
PS ich sehe gerade das du zwei fast gleiche construcktor in deinem timertask hast finde ich nicht gut. Bein Aufruf mit this ist nicht eindeutig welcher benutzt wird.
Warum ist das nicht eindeutig? Das ist eine normale Überladung. Aber das macht hier so keinen Sinn, weil Aufgabe zwingend eine Instanz von Gasübernahme braucht, d.h. jeder Konstruktor ohne Gasübernahme macht keinen Sinn. Aber überladene Konstruktoren sind ja nichts seltenes.
 

Jw456

Top Contributor
Ja aber nur tihs welcher von den beiden wird denn genommen?
Ich würde den nicht benutzen löschen um sicher du sein das der richtige benutzt wird.
 

Jw456

Top Contributor
Oder benutze Gasübernahme.this nicht nur this im sicher zugehen das du das richtige übergibst.
Wollte damit nur sicher stellen das in der Task Klasse auch der richtige construcktor benutzt wird.
Die Instanz ist da schon verfügbar, aber die Initialisierung ist halt noch nicht durch. Dadurch kann es zu Problemen kommen a.la. eine Instanzvariable ist noch nicht initialisiert aber es wird bereits drauf zugegriffen und Du bekommst eine NPE.
Und genau das wird er haben.
 
K

kneitzel

Gast
Ja aber nur tihs welcher von den beiden wird denn genommen?
Wenn eine Gasübernahme als Parameter angegeben wird (so wie in dem gezeigten Code), dann wird der Konstruktor mit der Gasübernahme genommen. Wenn eine Instanz von Gaszufuhr angegeben wird (in der Klasse wird es vermutlich auch einen ähnlichen Code geben), dann wird der andere Konstruktor genommen.

Wenn Du dir die main in Gasübernahme anschaust, dann wirst Du sehen, dass die Erstellung einer neuen Instanz auskommentiert wird. Daher wird der Fehler nicht durch den geposteten Code kommen... Daher meine Antwort. Darauf sollte der TE erst einmal reagieren. Weitere Schritte sind an der Stelle nicht notwendig.
 

Chefselber

Mitglied
Nabend,

kneitzel hatte Recht, ich habe vergessen den Aufruf aus "Gaszufuhr" (ähnlich zu Gasübernahme) - vorerst- auszukommentieren.:mad:

Exception in thread "Timer-1" java.lang.NullPointerException: Cannot invoke "Moka7Demo.Gasübernahme.Einlesen()" because "this.gasübernahme" is null
at Moka7Demo.Aufgabe.run(Aufgabe.java:56)
at java.base/java.util.TimerThread.mainLoop(Timer.java:556)
at java.base/java.util.TimerThread.run(Timer.java:506)

Warum hier der Fehler Richtung Gasübernahme zeigt, erschliesst sich mir nicht ganz.

Erstmal Danke für eure Mühen, hat mir sehr geholfen. Sehr lehrreich.

Übergaben mit this verwende ich gerne, auch bei ähnlichen Kontruktoren.
 

Neue Themen


Oben