# Timer oder Thread programmieren ?



## JavaUndC-Prog (4. Apr 2015)

Guten Tag zusammen,

Ich wollte mit JAVA gerne in die GUI Programmierung einsteigen, 
zuvor habe ich schon reichlich in C und Basic gemacht. Ich weiß, dass man in Visual Studio beispielsweise 
einen Timer in seine Form ziehen kann und diesen dann starten kann via Button oder dergleichen.

Mein Vorhaben ist eigentlich folgendes, ich möchte in JAVA eine Form erzeugen, auf der sich ein Button und ein Label befinden. Beim klicken auf den Button soll dann angefangen werden von 0 an hochzuzählen. Automatisch versteht sich. In Basic würde ich zunächst einen Timer in die Form ziehen und diesen mit dem Button verknüpfen und dann sowas wie Timer { i = i +1  label1.text = i}....... (Ganz grob). 

Wie würde das in Java gemacht werden ? muss dazu ein Timer oder ein Thread implementiert werden ? und wie genau sieht das dann aus ? 

(Nochmal eine generelle Frage für GUI Programmierung ist da der JAVA Editor besser oder Netbeans oder eine andere IDE ?)

Danke für kommende Antworten !


----------



## javampir (4. Apr 2015)

Hi,
ich verwende netbeans oder eclipse, das ist geschmackssache.
es ist hier beides möglich, sowohl timer als auch eigener thread (wo du ja einen timer nur selber implementieren würdest).
also, mit oberfläche würde das so aussehen:


```
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.Timer;

public class TimerUI implements ActionListener {
    
    public static void main(String[] args) {
        new TimerUI();
    }
    
    private int cnt = 0;
    private final JFrame f = new JFrame("TimerUI");
    private final JButton b = new JButton("Start");
    private final JLabel l = new JLabel("" + cnt);
    private final Timer t = new Timer(1000, this);
    
    public TimerUI() {
        l.setHorizontalAlignment(JLabel.CENTER);
        b.addActionListener(this);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(l, "Center");
        f.add(b, "South");
        f.pack();
        f.setLocationRelativeTo(f.getParent());
        f.setVisible(true);
    }
    
    @Override
    public void actionPerformed(ActionEvent e) {
        if(e.getSource().equals(b)) {
            if(t.isRunning()) {
                b.setText("Start");
                t.stop();
            } else {
                b.setText("Pause");
                t.start();
            }
        } else if(e.getSource().equals(t)) {
            cnt++;
            l.setText("" + cnt);
        }
    }
}
```

zugegeben, der Lerneffekt ist hier nicht sonderlich groß. Du solltest dich unbedingt mit GUI-Programmierung allgemein beschäftigen. In meinen Augen das schlimmst, was du am anfang machen kannst ist die Verwendung eines graphischen Editors, wo du die oberflächenelemente platzieren kannst. ohne verstandene konzepte kommst du nicht weiter.
Dazu muss gesagt werden, dass Gui-Programmierung eher fortgeschritten ist, also du solltest fundierte Grundkenntnisse in Objektorientierung / Vererbung haben und in den Kontrollstrukturen und datentypen auf und ab spazieren ohne groß nachdenken zu müssen.
Und in java gibts keine Forms 
gruß,
javampir


----------



## JavaUndC-Prog (5. Apr 2015)

Danke für deine Antwort und Entschuldigung, dass ich es jetzt erst schaffe zu antworten.

Deine Lösung hat nicht ganz funktioniert, ich habe es dann selbst noch irgendwie geschafft. Meine Frage ist jetzt, wie kann ich den timer starten, wenn die Applikation startet ? Aktuell geht dies nur, durch Betätigen eines Buttons. PS: Wie läuft das denn unter Netbeans ? In Visual Studio gibt es ja sowas wie Form1.Load da packt man das dann rein, aber gibt es so etwas auch in Netbeans ? oder im Java-Editor ?


```
import xdev.lang.EventHandlerDelegate;
import xdev.ui.XdevButton;
import xdev.ui.XdevLabel;
import xdev.ui.XdevWindow;

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Date;

import javax.swing.BorderFactory;
import javax.swing.Timer;
public class Uhrenanzeige
extends XdevWindow 
{
public static int i = 0;

private static Timer timer1 = new Timer(1000, null);	

	@EventHandlerDelegate void this_windowClosing(WindowEvent arg0) 
	{
		close();
	}




public void timer1_ActionPerformed(ActionEvent evt) {
    // TODO hier Quelltext einfügen
  } // end of timer1_ActionPerformed
  
  
  
	@EventHandlerDelegate void button_mouseClicked(MouseEvent arg0) 
	{
		// Zählervariable für Button Visible (NEIN !)...
		int aus = 0;
		aus = aus +1;
		if(aus == 1)
		{
			button.setVisible(false);	
		}
		
		timer1.start();
		timer1.addActionListener(new ActionListener() { 
		  public void actionPerformed(ActionEvent evt) { 
		    timer1_ActionPerformed(evt);
		    i = i + 1;
		    label.setText("Timer:   " + i);
		    //DATUM
		    Date date = new Date();
		    label2.setText("Systemzeit:   " + date);
		    }
		    });		
	}



	@EventHandlerDelegate void button2_mouseClicked(MouseEvent arg0) 
	{
				timer1.stop();
				button.setVisible(false);
	}


	@EventHandlerDelegate void button3_mouseClicked(MouseEvent arg0) 
	{
				timer1.restart();	
				button.setVisible(false);	
	}


	@EventHandlerDelegate void this_windowOpened(WindowEvent arg0) 
	{

	}


	
	XdevButton	button3, button2, button;
	XdevLabel	label2, label;
	

	

	{
		label2 = new XdevLabel();
		button3 = new XdevButton();
		button2 = new XdevButton();
		label = new XdevLabel();
		button = new XdevButton();
		
		this.setPreferredSize(new Dimension(443,201));
		label2.setText("Systemzeit:");
		label2.setName("label2");
		button3.setTabIndex(3);
		button3.setText("TIMER RESTART");
		button2.setTabIndex(2);
		button2.setText("TIMER PAUSIEREN");
		button2.setBorder(BorderFactory.createEtchedBorder());
		button2.setName("button2");
		label.setText("Uhrzeit:   ");
		button.setTabIndex(1);
		button.setText("TIMER STARTEN");
		button.setBorder(BorderFactory.createEtchedBorder());
		
		label2.saveState();
		label.saveState();
		
		label2.setBounds(35,45,56,15);
		this.add(label2);
		button3.setBounds(155,174,130,23);
		this.add(button3);
		button2.setBounds(3,174,148,23);
		this.add(button2);
		label.setBounds(343,45,49,15);
		this.add(label);
		button.setBounds(292,174,148,23);
		this.add(button);
		
		this.addWindowListener(new WindowAdapter()
		{
			@Override
			public void windowClosing(WindowEvent arg0)
			{
				this_windowClosing(arg0);
			}
			@Override
			public void windowOpened(WindowEvent arg0)
			{
				this_windowOpened(arg0);
			}
		});
		button3.addMouseListener(new MouseAdapter()
		{
			@Override
			public void mouseClicked(MouseEvent arg0)
			{
				button3_mouseClicked(arg0);
			}
		});
		button2.addMouseListener(new MouseAdapter()
		{
			@Override
			public void mouseClicked(MouseEvent arg0)
			{
				button2_mouseClicked(arg0);
			}
		});
		button.addMouseListener(new MouseAdapter()
		{
			@Override
			public void mouseClicked(MouseEvent arg0)
			{
				button_mouseClicked(arg0);
			}
		});
	}

}
```


----------



## javampir (5. Apr 2015)

hi,
also, bei mir hat es funktioniert.
den timer kannst du bei programmstart straten, wenn du t.start im konstruktor aufrufst.
musst du xdevwindow verwenden? davon habe ich noch nie gehört. mit swing gehts doch recht komfortabel.
ja, also in netbeans hast du den java editor. dort hast du klassen geöffnet, die in einem projekt sind. am besten tut man sie auch noch in ein package rein (das habe ich hier nicht im code, damit man ihn eig. mit copy&paste direkt einfügen und ausführen kann)
gruß,
javampir


----------



## JavaUndC-Prog (6. Apr 2015)

Danke nochmals, 

Ich bin noch selbst auf die Lösung gekommen und es ist, wie du sagtest einfach timer1.start(); in den Konstruktor packen und alles funktioniert. Danke !

XDEV ist ein kurzfristiger Einfall von mir gewesen, da ich von Visual Studio sehr verwöhnt bin und ich habe so etwas auch für die Java Programmierung gesucht. Ich habe dann zwischen dem Java Editor und XDEV gewechselt, um zusehen ob beides funktioniert. Aber ich habe so das Gefühl, dass der Java Editor einem da etwas mehr unter die Arme greift.


----------



## jeegeek (8. Apr 2015)

JavaUndC-Prog hat gesagt.:


> XDEV ist ein kurzfristiger Einfall von mir gewesen, da ich von Visual Studio sehr verwöhnt bin und ich habe so etwas auch für die Java Programmierung gesucht. Ich habe dann zwischen dem Java Editor und XDEV gewechselt, um zusehen ob beides funktioniert. Aber ich habe so das Gefühl, dass der Java Editor einem da etwas mehr unter die Arme greift.



Ich kann es nachvollziehen das grafische Hilfsmittel schon eine nette Sache sind, aber gerade zu Anfang solltest du sie nicht benutzen. Diese GUI Baukästen erzeugen dir in der Regel einen Java Code der deine Oberfläche baut, wenn du aber die Grundlagen nicht verstehst wie Swing, AWT oder was auch immer für eine Gui funktioniert kommst du nicht weit. Nebenbei sieht der Code einer von Hand erstellten GUI oft schöner aus 

Die Lösung von javampir ist nur eine Möglichkeit von vielen. Es gibt viele verschiedene Timer die du verwenden kannst und je nach Anwendung macht es mehr oder weniger viel Sinn einen bestimmten zu verwenden. Beispiel der von dir verwendete javax.swing.Timer ist für deine Aufgabe gut geeignet, der Timer kann aber wenn er umfangreiche Aufgaben ausführt deine Oberfläche beeinträchtigen. Dann wäre z.B ein Timer der in einem eigenen Thread läuft die bessere Wahl. Die Konsequenz dabei wäre aber das du dich auch um die Threadsicherheit kümmern musst.

Das war jetzt nur ein Beispiel, wenn du wirklich mit Java Oberflächen erstellen willst schau dir trotzdem die Grundlagen der Sprache an da du sonst früher oder später, vermutlich aber früher an die Grenzen stoßen wirst.


----------



## JavaUndC-Prog (8. Apr 2015)

Danke jeegeek,

Ich verstehe was du meinst. Das macht ja auch Sinn vorher etwas selbst zu erstellen und dann ggf. auf die IDE zurückgreifen mit der das automatisiert werden kann.



Mich würde noch interessieren, wie dies hier noch programmiert wird:



> Dann wäre z.B ein Timer der in einem eigenen Thread läuft die bessere Wahl. Die Konsequenz dabei wäre aber das du dich auch um die Threadsicherheit kümmern musst.


----------



## jeegeek (8. Apr 2015)

Schau mal hier: Rheinwerk Computing :: Java ist auch eine Insel – 14.7 Zeitgesteuerte Abläufe
 Nebenbei eine ausgezeichnete Dokumentation die du dir merken solltest und wenn du Java intensiver nutzen möchtest auch kaufen solltest.

Kurz erklärt erstellst du eine Klasse z.B eine innere Klasse die vom TimerTask erbt. Hier ein kurzes Beispiel:

```
//Innere Klasse für den Timer
	class AnimationsTask extends TimerTask
	{
		@Override
		public void run() {
			//Mache irgendwas
		}
	}
```

Am Ende erzeugst du dir einen Timer und startest diesen:

```
Timer myTimer = new Timer();	//Timer erstellen
myTimer.schedule(new AnimationsTask(), 0, 50); //Timer starten, erster Start nach 0 Sekunden und dann alle 50 ms
```


----------



## JavaUndC-Prog (9. Apr 2015)

Danke,

das hat mir gut weitergeholfen, ich hab den Thread nun implementiert. Danke sehr.

Ich habe noch zwei Fragen, 

1. In wie fern unterscheiden sich denn timer und thread ?
2. gibt es Verbesserungen am Code ?   

// Kann man in Java nicht 
private static int x;
x = 0;
? In C funktioniert dies. // ohne private und static natürlich
Geht dies nur über den Konstruktor ?


```
import xdev.lang.EventHandlerDelegate;
import xdev.ui.XdevButton;
import xdev.ui.XdevLabel;
import xdev.ui.XdevWindow;

import java.awt.Dimension;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Timer;
import java.util.TimerTask;


public class klasse

extends XdevWindow 
{

	private static int erh = 15;
	private static Timer myTimer = new Timer();	//Timer erstellen
	

	@EventHandlerDelegate void this_windowClosing(WindowEvent arg0) 
	{
		close();
	}


	@EventHandlerDelegate void button_mouseClicked(MouseEvent arg0) 
	{
		
		label.setText("Timer:   " + erh);
		myTimer.schedule(new AnimationsTask(), 0, 1000);
		label.setText("Timer:   " + erh);
		
	}


	@EventHandlerDelegate void this_windowOpened(WindowEvent arg0) 
	{

	}


class AnimationsTask extends TimerTask
{
	
	@Override
	public void run() {	
		label.setText("Timer:   " + erh);
		erh = erh +1;
		label.setText("Timer:   " + erh);
	}
}

	
	XdevButton	button;
	XdevLabel	label;
	


	{
		label = new XdevLabel();
		button = new XdevButton();
		
		this.setPreferredSize(new Dimension(375,159));
		label.setText("Label");
		button.setTabIndex(1);
		button.setText("Button");
		
		label.saveState();
		
		label.setBounds(49,67,27,15);
		this.add(label);
		button.setBounds(211,119,69,23);
		this.add(button);
		
		this.addWindowListener(new WindowAdapter()
		{
			@Override
			public void windowClosing(WindowEvent arg0)
			{
				this_windowClosing(arg0);
			}
			@Override
			public void windowOpened(WindowEvent arg0)
			{
				this_windowOpened(arg0);
			}
		});
		button.addMouseListener(new MouseAdapter()
		{
			@Override
			public void mouseClicked(MouseEvent arg0)
			{
				button_mouseClicked(arg0);
			}
		});
	}

}
```


----------



## javampir (9. Apr 2015)

hi,
zuweisungen wie x=0 kannst du nur innerhalb eines anweisungblockes schreiben, bei final muss das im konstruktor sein. alternative ist nur 

```
private static final int x = 0;
```

javampir


----------



## JavaUndC-Prog (25. Dez 2016)

Hi ich habe nochmal eine bestimmte Frage. Diesesmal bezieht sich das auf das Pausieren und wieder starten des Timers.


```
Timer timer01 = new Timer();
        timer01.schedule(new TimerTask() {
              @Override
              public void run() {
if (pause == true){ // Mache Pause
}else{
//mache keine Pause
}
                  }
            }, 70,70);
```

Ich möchte eigentlich nur hochzählen und bei einem Button Klick pausieren. Bis jetzt habe ich das in meinen Projekten mit einer Variable gemacht, die ich dann auf true/false gesetzt habe um zu Pausieren. Ist dass gängige Praxis oder gibt es da einen besseren Ansatz? vllt in Bezug auf meinen Code


----------

