[Java] Slider

P13RR3

Lt. Commander
Registriert
Juli 2003
Beiträge
1.148
Hi,

habe in einem Array einige Angaben (zB 0 und 1). Dieses wird in einer FOR-Schleife Feld für Feld abgearbeitet. In dieser wird per IF-Abfragen abgefragt, was nun grade ausgelesen worden ist. Bei zB 0 wird folgendes ausgeführt:

Code:
sliderHalt.setValue(sliderHalt.getValue() - 25);
System.out.println("0");
Bei eins halt des gleiche, bloß wird die Scrollbar nach rechts bewegt und eine 1 ausgegeben.

Also die Ausgabe auf der Konsole stimmt seltsamerweise! Bloß verändert der slider seinen Zustand nur einmal (und da nimmt er des was im letzten Feld steht). Also er rutscht nicht ständig hin und her, sondern nur beispielsweise 25-schritte nach links wenn das letzte im Array eine Null ist.
Hab auch mal versucht, am Ende von der IF-Abfrage des Swing-Fenster mit repaint(); zu "refreshen". -> Kein Erfolg.

Hat einer von euch vielleicht ne Idee?
 
Zuletzt bearbeitet:
Hast du mal ein Sleep in deine Schleife eingebaut ?
Ich meine ein Array mit nen paar Zahlen geht der so schnell durch das du nur das Resultat siehst.
 
Jo, hab ich. Die Ausgabe ist auch _sehr_ langsam ... Bloß verändert sich die Scrollbar nicht :(
 
Kannst du mal einen vollständigen Sourcecode zu testen posten, damit man sich das mal näher anschaunen kann ?
 
Code:
import java.awt.event.*;
import javax.swing.*;

public class SliderZeugs extends JFrame implements ActionListener {

	JSlider derSlider;

	JButton test;

	public SliderZeugs() {
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setLayout(null);

		derSlider = new JSlider(0, 0, 270, 135);
		derSlider.setBounds(30, 45, 180, 20);
		derSlider.setEnabled(false);
		add(derSlider);
		test = new JButton("test");
		test.addActionListener(this);
		test.setBounds(30, 100, 100, 20);
		add(test);
	}

	public static void main(String[] args) {
		SliderZeugs main = new SliderZeugs();
		main.setVisible(true);
		main.setSize(300, 300);
		main.setResizable(true);
	}

	public void actionPerformed(ActionEvent event) {
		String cmd = event.getActionCommand();
		if (cmd.equalsIgnoreCase("test")) {
			ausgabe();
		}
	}

	public void ausgabe() {
		String[] gesplittetes = { "neNull", "neEins", "neNull", "neNull",
				"neEins" };
		for (String blubb : gesplittetes) {
			if (blubb.equalsIgnoreCase("neNull")) {
				System.out.println("neNull");
				derSlider.setValue(derSlider.getValue() - 100);
				repaint();
				try {
					Thread.sleep(788);
				} catch (InterruptedException e) {
				}
			}
			if (blubb.equalsIgnoreCase("neEins")) {
				System.out.println("neEins");
				derSlider.setValue(derSlider.getValue() + 100);
				repaint();
				try {
					Thread.sleep(788);
				} catch (InterruptedException e) {
				}
			}
		}
	}
}

Ne kleine Testklasse, in dem sich des Problem befindet ... ;)
 
Zuletzt bearbeitet:
Ja das ist ein grundlegendes Problem bezüglich der GUI Programmierung gewesen.

Dein GUI-Programm hat einen Thread der alle Operationen für die GUI ausführt, auf Events wie Maus, Tastatur und die Anforderung ein Control neu zu zeichnen reagiert. Dafür läuft im Hintergrund eine Schleife.

Wenn du nun mit einer rechenintensiven Operation diesen Thread blockiert reagiert die GUI nicht mehr, da diese Schleife nicht mehr zu Ausführung kommt. Selbst den repaint wird auf eine Liste gesetzt und dann irgentwann von dieser Schleife abgearbeitet.

Der Schlüssel ist nun diese rechenintensive Operation in einen eigenen Thread auszulagern.
Wichtig dabei ist aber das eine GUI Operation NUR im Hauptthread stattfinden darf. Wenn als dein Rechenthread etwas auf der GUI aktualisieren will muss er den Hauptthread sagen das er das machen soll.

Im Code ist der erste Runnable der Thread für den rechenintensiven Code. Innerhalb dieses Threads wird dann für den Slider ein 2tes Runnable erstellt was dem Hauptthread übergeben und von ihm ausgeführt wird.

Code:
import java.awt.event.*;
import java.lang.reflect.InvocationTargetException;

import javax.swing.*;

public class SliderZeugs extends JFrame implements ActionListener {

	JSlider derSlider;
	JButton test;
	int mod = 0;

	public SliderZeugs() {
		super();
	
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setLayout(null);

		derSlider = new JSlider(0, 0, 270, 135);
		derSlider.setBounds(30, 45, 180, 20);
		derSlider.setEnabled(true);
		this.getContentPane().add(derSlider);
		test = new JButton("test");
		test.addActionListener(this);
		test.setBounds(30, 100, 100, 20);
		this.getContentPane().add(test);
	}

	public static void main(String[] args) {
		SliderZeugs main = new SliderZeugs();
		main.setVisible(true);
		main.setSize(300, 300);
		main.setResizable(true);
	}

	public void actionPerformed(ActionEvent event) {
		String cmd = event.getActionCommand();
		if (cmd.equalsIgnoreCase("test")) {
			//Eigener Thread für die rechenintensive Berechnung
			Runnable runnable = new Runnable() {
				public void run() {
					demo();
				}
			};
			
			Thread t = new Thread(runnable);
			t.start();
		}
	}

	public void demo() {
		String[] gesplittetes = { "neNull", "neEins", "neNull", "neNull",
				"neEins" };
		
		for (String blubb : gesplittetes) {
			try {
				Thread.sleep(788);
			} catch (InterruptedException e) {
			
			}
			
			if (blubb.equalsIgnoreCase("neNull")) {
				System.out.println("neNull");
				mod = -100;
			} else if (blubb.equalsIgnoreCase("neEins")) {
				System.out.println("neEins");
				mod = 100;
			}
			
			//Threadsicher Fufruf für die GUI
			Runnable runnable = new Runnable() {
				public void run() {
					derSlider.setValue(derSlider.getValue() + mod);
				}
			};
			
			try {
				SwingUtilities.invokeAndWait(runnable);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}
 
Zurück
Oben