Timingproblem

Status
Nicht offen für weitere Antworten.

niemand

Bekanntes Mitglied
Hi,

ich hab mich die Nacht wieder ein wenig mit Swing beschäftigt, weil ich immer noch eine Möglichkeit suchte, meine Sachen vernünftig zu strukturieren. Dabei bin ich bei den inneren Klassen hängengeblieben, wobei mir ein Problem aufgefallen ist, was in späteren Anwendungen zu gemeinen Fehlern führen kann: Ich habe die Hauptklasse von JFrame und die inneren Klassen mit je einem Element (zum Spielen halt) von JPanel abgeleitet, konkret sind das zwei JButtons und ein JTextField. Beide Buttons sollen das Textfeld verändern, was auch erstmal ohne Probleme funktioniert.

Das Problem liegt beim zweiten Button, dieser sollte ursprünglich den Text des Textfeldes neu setzen, danach sollte drei Sekunden gewartet werden und anschließend sollte sich das Programm beenden. Dazu wird die Methode setText() des Textfeldes mit dem neuen Text aufgerufen, anschließend mittels Thread.sleep() drei Sekunden gewartet und anschließend mittels System.exit() ausgestiegen. Dummerweise wurde das Textfeld erst nach Ablauf der drei Sekunden neu gesetzt und anschließend sofort das Programm beendet. Meine Überlegungen gingen nun dahin, die Methode aus einem eigenen Thread aufzurufen. Nachdem das auch nicht funktionierte, versuchte ich, den Thread mit synchronized zu schützen, doch auch das brachte nicht den gewünschten Erfolg. Das Seltsame ist dabei, dass die Zeilen, in denen ich zur Kontrolle etwas auf der Konsole ausgeben lasse, seit dem synchronized einwandfrei funktionieren, nur eben mein Textfeld wird erst nach Ablauf der drei Sekunden neu gesetzt.

Hier einmal der komplette Code, wäre super, wenn mich jemand auf meinen Denkfehler stoßen könnte ;)
Code:
import javax.swing.*;
import java.awt.event.*;

public class InnerButton extends JFrame {
    TextFeld t;
    InnerButton() {
        super("Just for fun");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        Knopf k=new Knopf();
        t=new TextFeld();
        Quit q=new Quit();
        JPanel pane=new JPanel();
        setContentPane(pane);
        pane.add(k.getKnopf());
        pane.add(t.getFeld());
        pane.add(q.getQuit());
        pack();
        setVisible(true);
    }
    class Knopf extends JPanel implements ActionListener{
        Knopf() {
            JButton b=new JButton("Knopf");
            this.add(b);
            b.addActionListener(this);
        }
        JPanel getKnopf() {
            return this;
        }
        public void actionPerformed(ActionEvent ae){
            String command=ae.getActionCommand();
            if(command=="Knopf")
                t.setContent("funzt");
        }
    }
    class TextFeld extends JPanel {
        JTextField tf;
        TextFeld(){
            tf=new JTextField(10);
            this.add(tf);
        }
        void setContent(String text){
            tf.setText(text);
        }
        JPanel getFeld() {
            return this;
        }
    }
    class Quit extends JPanel implements ActionListener, Runnable {
        JButton quit;
        Quit(){
            quit=new JButton("Ende");
            this.add(quit);
            quit.addActionListener(this);
        }
        JPanel getQuit(){
            return this;
        }
        public void actionPerformed(ActionEvent ae){
            String command=ae.getActionCommand();
            if(command=="Ende") {
                new Thread(this).start();
                System.out.println("Eigentlich ...");
                try {
                    Thread.sleep(3000);
                }
                catch (InterruptedException ie){
                }
                System.out.println("... ist die Zeit um");
//                System.exit(0);
            }
        }
        public void run (){
            synchronized(getClass()){
                System.out.println("Im Thread");
                t.setContent("Bye");
            }
        }
    }
    public static void main(String[] args) {
        InnerButton b=new InnerButton();
    }
}

Was mich weiterhin interessieren würde: Ist die grundsätzliche Strukturierung mit den inneren Klassen mit eigenen Listenern ok so, oder ist das eher schlechter Stil? Ich finde es so recht übersichtlich. Hier ist es zwar sinnlos, aber bei größeren Sachen erhoffe ich mir davon leichter verständlichen Code. Wenn das allerdings als schlechter Stil angesehen wird, oder zu ressourcenfressend ist, gewöhne ich mir das gar nicht erst an.


Dank im Voraus
 

dotlens

Top Contributor
dann lagere alles in den Thread aus:$
Code:
import javax.swing.*;
import java.awt.event.*;

public class InnerButton extends JFrame {

	TextFeld t;

	InnerButton() {
		super("Just for fun");
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		Knopf k = new Knopf();
		t = new TextFeld();
		Quit q = new Quit();
		JPanel pane = new JPanel();
		setContentPane(pane);
		pane.add(k.getKnopf());
		pane.add(t.getFeld());
		pane.add(q.getQuit());
		pack();
		setVisible(true);
	}

	class Knopf extends JPanel implements ActionListener {

		Knopf() {
			JButton b = new JButton("Knopf");
			this.add(b);
			b.addActionListener(this);
		}

		JPanel getKnopf() {
			return this;
		}

		public void actionPerformed(ActionEvent ae) {
			String command = ae.getActionCommand();
			if(command == "Knopf")
				t.setContent("funzt");
		}
	}

	class TextFeld extends JPanel {

		JTextField tf;

		TextFeld() {
			tf = new JTextField(10);
			this.add(tf);
		}

		void setContent(String text) {
			tf.setText(text);
		}

		JPanel getFeld() {
			return this;
		}
	}

	class Quit extends JPanel implements ActionListener, Runnable {

		JButton quit;

		Quit() {
			quit = new JButton("Ende");
			this.add(quit);
			quit.addActionListener(this);
		}

		JPanel getQuit() {
			return this;
		}

		public void actionPerformed(ActionEvent ae) {
			String command = ae.getActionCommand();
			if(command == "Ende") {
				new Thread(this).start();
				System.out.println("Eigentlich ...");
			}
		}

		public void run() {
			synchronized (getClass()) {
				System.out.println("Im Thread");
				t.setContent("Bye");
				try {
					Thread.sleep(3000);
				}
				catch (InterruptedException ie) {}
				System.out.println("... ist die Zeit um");
				System.exit(0);
			}
		}
	}

	public static void main(String[] args) {
		InnerButton b = new InnerButton();
	}
}
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Oben