Swing - Blackscreen

programmierer12

Bekanntes Mitglied
Hallo zusammen,
Ich habe ein kleines Programm zusammengebastelt, das
am Ende des Bearbeitens das fertige Bild wieder abspeichert.
Das ganze funktioniert auch, jedoch reagiert das Fenster
beim abspeichern nicht mehr und wird schwarz.
Nachdem das Speichern erledigt ist funktioniert auch
die Benutzeroberfläche wunderbar!
Wie kann ich das machen, dass dieser kleiner "Buck"
nicht auftritt?
PS: Wenn ich den Code posten soll sagts mir bitte.

MFG
programmierer12
 
Java:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.IOException;

import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;

public class Main{
	
	public static File file;

	public static void main(String[] args) throws IOException {
		
		final JFrame f = new JFrame("AB Cleaner");
		f.setSize(340, 220);
		f.setLocationRelativeTo(null);
		f.setDefaultCloseOperation(3);
		f.setUndecorated(false);
		f.setLayout(null);
		f.setResizable(false);
		f.setVisible(true);
		f.addWindowListener(new WindowAdapter() {			
			
			public void windowClosing(WindowEvent e){
				
				if (JOptionPane.showConfirmDialog(null, "Möchten Sie das Programm beenden"," Programm beenden ", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
					
					System.exit(0);
					
				}
			
			}
			
		});
		
		JMenuBar mb = new JMenuBar();
		f.setJMenuBar(mb);
		
		JMenu start = new JMenu("Start");
		mb.add(start);
		
		JMenu hilfe = new JMenu("Hilfe");
		mb.add(hilfe);
		
		JMenuItem open = new JMenuItem("Öffnen");
		start.add(open);
		
		final JMenuItem beginn = new JMenuItem("Starten");
		start.add(beginn);
		
		JMenuItem close = new JMenuItem("Beenden");
		start.add(close);
		
		JMenuItem help = new JMenuItem("Hilfe");
		hilfe.add(help);
		
		JMenuItem infos = new JMenuItem("Informationen über AB Cleaner");
		hilfe.add(infos);
		
		final JLabel hilfeText = new JLabel();
		hilfeText.setBounds(12, 13, 298, 123);
		f.add(hilfeText);
		hilfeText.setVisible(false);
		
		open.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {

				JFileChooser fc = new JFileChooser();
				int state = fc.showOpenDialog(null);
				if (state == JFileChooser.APPROVE_OPTION) {
					
					file = fc.getSelectedFile();
					
				}
				
				else {
					
					
					
				}
				
			}
		
		});
		
		beginn.addActionListener(new ActionListener() {
			
			@SuppressWarnings("unused")
			@Override
			public void actionPerformed(ActionEvent e) {

				try {
					
					RET ret = new RET(file, "C:\\Users\\User\\Desktop\\BearbeitetesBild.png");
					JOptionPane.showMessageDialog(f, "Das Bearbeitete Bild wurde auf dem Desktop abgelegt");
					
				} catch (Exception e2) {

					JOptionPane.showMessageDialog(null, "Wählen Sie erst die zu bearbeitende Datei aus!");
					
				}
				
			}
		});
		
		close.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {

				System.exit(0);
				
			}
		});
 
Für eine bestimmte Zeit legst du dein Programm lahm, da das Speichern offensichtlich viele Rescourcen benötigt. Du müsstest also dein Speichern irgendwie mithilfe eines Threads "bremsen". Dazu empfielt es sich sleep(0); und dann yield(); zu setzen. yield(); reiht den Thread wieder ganz hinten in die Eventliste vom Betriebssystem ein.

Das wäre jetzt meine spontane Idee dazu, denn das Fenster reagiert nicht, was für mich ein klares Zeichen für eine anderweitige, ungebremste Aktivitär ist.
 
Während. 😀
Dazu müsstest du die Klasse, die speichert kopieren, in eine neue Klasse einfügen und dann dort den sleep und den yield einbauen.
Ich gehe davon aus, dass du etwas aus der API verwendest.
Dazu könntest du eine interne Klasse da einbauen, die von Thread erbt, darin eine Methode einbauen, die nur den sleep und den yield aufruft. Aber dann reicht der yield. Diese Methode rufst du aus der Schleife, die speichert auf.

Klingt sehr kompliziert aber das ist die einzige Möglichkeit, die ich sehe, da du Probleme mit einer Methode aus der API hast.
 
Hallo nochmal ich habe deinen Beitrag gerade im Moment gelesen und muss
schon sagen, dass ich nicht wirklich weiß was du meinst und ob ich das so
hinbekomme.
Ich benutze zum speichern des Bildes
Code:
ImageIO.write(img, "png", file);
.
Wenn ich das richtig verstanden habe muss ich die Klasse ImageIO verändern
dahingehend, dass
Code:
Thread.sleep(0);
und
Code:
Thread.yield();
eingefügt werden? Wenn ja könntest du mir das noch ein bisschen genauer erklären.
Wenn es hilft ich habe mal aus Langeweile die komplette Java Systembibliothek decompiliert.

MFG
programmierer12
 
Das hast du vollkommen richtig verstanden. In der Methode write müsste irgendwo der Zyklische Aufruf von etwas sein. Dort kommt der yield rein.

Nur zur Absicherung, dass wir hier auch grade wirklich dieses Problem haben: Kannst du noch mal mit System.out.println()s testen, ob es wirklich diese Methode ist, die das Programm aufhält?
 
Für eine bestimmte Zeit legst du dein Programm lahm, da das Speichern offensichtlich viele Rescourcen benötigt. Du müsstest also dein Speichern irgendwie mithilfe eines Threads "bremsen". Dazu empfielt es sich sleep(0); und dann yield(); zu setzen. yield(); reiht den Thread wieder ganz hinten in die Eventliste vom Betriebssystem ein.
[...]

Die vorgeschlagene Idee ist einfach grober Unfug. Das Standardvorgehen wäre den langlaufenden Teil, hier das Speichern, aus der actionPerformed-Methode in einen eigenen Thread auszulagern und den Verwender (den Starter des Threads) benachrichtigen zu lassen wenn die Aufgabe erledigt ist. Damit man sich dieses "Eventhandling" oder Gefummel mit Callbacks nicht selbst basteln muss wurde vor längerer Zeit die Hilfsklasse SwingWorker eingeführt.

Eine kurze Erläuterung samt Beispiel findet sich hier SwingWorker - Wikipedia, the free encyclopedia und Google spuckt mit java swingworker example noch viel mehr aus.
 
Zuletzt bearbeitet:
Die vorgeschlagene Idee ist einfach grober Unfug. Das Standardvorgehen wäre den langlaufenden Teil, hier das Speichern, aus der actionPerformed-Methode in einen eigenen Thread auszulagern und den Verwender (den Starter des Threads) benachrichtigen zu lassen wenn die Aufgabe erledigt ist. Damit man sich dieses "Eventhandling" oder Gefummel mit Callbacks nicht selbst basteln muss wurde vor längerer Zeit die Hilfsklasse SwingWorker eingeführt.

Eine kurze Erläuterung samt Beispiel findet sich hier SwingWorker - Wikipedia, the free encyclopedia und Google spuckt mit java swingworker example noch viel mehr aus.


Wäre auch ne Möglichkeit. Danke für die Korrektur. 😀
 

Zurück
Oben