Swing 3 Buchstaben des Hasses aka EDT

Status
Nicht offen für weitere Antworten.

hdi

Top Contributor
hey Leute... mal wieeeeder steh ich vor einem Problem, das mit dem EDT zusammenhängt, und ich komme nicht weiter.

(Mal so nebenbei: Wenn einer von euch gute Literatur über dieses Thema kennt, also damit meine ich nicht 2 Seiten sondern eher 200, nur her damit!)

Ich schilder mal die Situation: Man drückt nen Knopf in meiner GUI und es wird ein undecorated modal Dialog eingeblendet.
Problem: Nach spätenstens 20-30 Klicks auf besagtem Button passiert es mindestens einmal, dass der Dialog nicht sichtbar wird.
Er ist aber "da", denn wenn ich dorthin klicke, wo im Dialog Buttons zu sehen sein sollten, werden deren Actions aufgerufen. Das heisst er malt den Dialog einfach nicht.

Programm-Logik:

1. actionPerformed() des Auslöser-Buttons
2. Aufruf einer Methode in einem neuen Thread, dann wird die actionPerformed gleich verlassen. Diese Methode sieht so aus:

Java:
       // lock GUI
		EventQueue.invokeLater(new Runnable() {
			@Override
			public void run() {
				MainFrame.getInstance().lock(); // macht nur setEnabled(false) auf ein paar Komponenten
			}
		});
		
		// some logical stuff (sehr wenig!)

		final DeletionConfirm dc = new DeletionConfirm(); // das is mein Dialog
		dc.setVisible(true); // Problem besteht auch wenn ich das hier auf den EDT leg mit invokeLater

		// diese zelle liegt übrigens GENAU an der stelle wo auch der dialog angezeigt wird. 
//Nach kurzem nachdenken, ob hier das Problem liegen könnte (Dialog darüber verliert Fokus?!) dachte ich: 
//Kann ja nicht sein, weil man hier erst ankommt wenn der Dialog geschlossen wurde, nicht wahr?
		MovieTable.getInstance().getColumnModel().getColumn(0).getCellEditor()
				.cancelCellEditing();

		// unlock GUI
		EventQueue.invokeLater(new Runnable() {
			@Override
			public void run() {
				MainFrame.getInstance().unlock();
			}
		});

Jo, Dialog wird ab und an eben nicht angezeigt. Er ist da, aber nicht sichtbar.

Meiner Meinung nach sollte der EDT doch frei sein, weil das ganze hier läuft doch in einem eigenen Thread. Übrigens hatte ich das lock() und unlock() meines MainFrames erst auch nicht auf dem EDT, habs dann reingetan weil ich dachte vllt liegt es daran. -> nicht!

... wie immer unschätzbar dankbar für eure Tipps :toll:
 
Zuletzt bearbeitet:

0x7F800000

Top Contributor
hey hdi! :)

Du weißt ja: von diesem kram verstehe ich noch weniger als du :D, aber wenn du zufälligerweise ein kompilierbares Beispiel hättest, würde ich damit gern ein bisschen rumspielen, vielleicht fällt mir ja doch was auf? :oops:
 
Zuletzt bearbeitet:

hdi

Top Contributor
Ok während ich das KKB gemacht habe bin ich schon soweit gekommen, dass ich nun weiss: Es liegt nicht am Dialog oder dem Table. Denn ich konnte jetzt den Fehler nicht reproduzieren. Allerdings ist das KKB auch vereinfacht, ich werde das jetzt nach und nach meinem richtigen Programm nähern, mal schauen wann ab wann es hängt.
Ich befürchte es hat was mit dem TableModel auch sich, weil das modifiziere ich...

Naja ich werd mich dann melden, danke schon mal für deine Hilfsbereitschaft.

PS: falls es interessiert, hier das KKB:
Java:
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;

public class KKB extends JFrame {

	public static void main(String[] args) {
		new KKB().setVisible(true);
	}

	private JTable table;

	public KKB() {
		setDefaultCloseOperation(EXIT_ON_CLOSE);

		// setup table
		table = new JTable(100, 3);
		TableColumn firstColumn = table.getColumnModel().getColumn(0);
		SpecialCellRenderer renderer = new SpecialCellRenderer();
		firstColumn.setCellRenderer(renderer);
		firstColumn.setCellEditor(renderer);

		// add table to frame
		add(new JScrollPane(table));
		pack();
		setLocationRelativeTo(null);
	}

	class SpecialCellRenderer extends DefaultCellEditor implements
			TableCellRenderer, TableCellEditor {

		private JButton button;

		public SpecialCellRenderer() {
			super(new JCheckBox());

			button = new JButton("show dialog");

			// add action
			button.addActionListener(new ActionListener() {

				@Override
				public void actionPerformed(ActionEvent e) {
					MyDialog dialog = new MyDialog();
					
					// set location relative to currently pressed button (row)
					Point p = button.getLocationOnScreen();
					dialog.setLocation(p);
					
					// show it
					dialog.setVisible(true);
					
				}
			});
		}

		@Override
		public Component getTableCellRendererComponent(JTable table,
				Object value, boolean isSelected, boolean hasFocus, int row,
				int column) {

			if (isSelected) {
				return button;
			} else {
				return null;
			}

		}

		public Object getCellEditorValue() {
			return null;
		}

		public boolean stopCellEditing() {
			return super.stopCellEditing();
		}

		protected void fireEditingStopped() {
			super.fireEditingStopped();
		}

		public Component getTableCellEditorComponent(JTable table,
				Object value, boolean isSelected, int row, int column) {

			if (isSelected) {
				return button;
			}
			return null;
		}
	}

	class MyDialog extends JDialog {

		private JButton close;

		public MyDialog() {
			super(KKB.this, true);
			setUndecorated(true);

			// close button
			close = new JButton("close dialog");
			close.addActionListener(new ActionListener() {

				@Override
				public void actionPerformed(ActionEvent e) {
					MyDialog.this.dispose();
				}
			});
			close.setBackground(new Color(150, 150, 255));
			close.setPreferredSize(new Dimension(150, 15));

			add(close);
			pack();
		}
	}
}
 

0001001

Bekanntes Mitglied
Kann dein Problem gerade nicht nachvollziehen, in deinem KKB funktioniert das bei mir einwandfrei.
 

Marco13

Top Contributor
Ähm - du solltest, wenn der Dialog gekillt wird, auch
dialog.dispose();
aufrufen - sonst müllt man sich ggf. den Speicher zu, mit Resourcen für Dialoge, die eigentlich schon nicht mehr exisitieren....
 
J

JohannisderKaeufer

Gast
Ist es eventuell möglich, dass sich irgendwo noch ein paar AWT-Geschichten in deine Swing-Anwendung eingeschlichen haben?
 

hdi

Top Contributor
@Marco 13: Das mach ich doch, siehe Button im Dialog
@Johannis: Kein AWT

...aber ich hab was rausgefunden: Das von mir gepostete KKB hat den gleichen Fehler! Man muss ne gute Minute rumklicken bis es passiert, aber dann tritt der gleiche Effekt auf wie in meinem Programm.

...ich bilde mir ein, dass das vorallem sehr oft dann passiert, wenn man eine Zelle anklickt, die nicht vollständig im ScrollPane angezeigt wird (lässt sich erreichen wenn man per Hand etwas scrollt). Alleine schon hier zeigt die Pane/Table ein komisches Verhalten:
Manchmal snappt die ScrollPane sodass eine nur halb angezeigte Zeile voll sichtbar wird, wenn man draufklickt. Manchmal tut sie es aber auch nicht.

Und manchmal erscheint dann eben nicht mal der Dialog.

Also... wer quizzen will, bitte nur zu :) Das KKB ist gegeben, die Frage ist warum der Dialog nicht immer angezeigt wird, und warum die ScrollPane nicht immer snappt sondern nur manchmal.

Danke an jeden mit nem Tipp! :idea:
 

0x7F800000

Top Contributor
Man muss ne gute Minute rumklicken bis es passiert, aber dann tritt der gleiche Effekt auf wie in meinem Programm.
hab jetzt 3x a 5minuten lang fleißig an deinem KKB rumgeklickt, konnte nichts auffälliges feststellen.
...ich bilde mir ein, dass das vorallem sehr oft dann passiert, wenn man eine Zelle anklickt, die nicht vollständig im ScrollPane angezeigt wird (lässt sich erreichen wenn man per Hand etwas scrollt).
läst sich hier imho nicht erreichen...
Alleine schon hier zeigt die Pane/Table ein komisches Verhalten:
Manchmal snappt die ScrollPane sodass eine nur halb angezeigte Zeile voll sichtbar wird, wenn man draufklickt. Manchmal tut sie es aber auch nicht.
..eben deswegen lässt sich das nicht erreichen: hir schnappt's immer, soweit ich das experimentell überprüfen kann.

Und manchmal erscheint dann eben nicht mal der Dialog.
tut er hier immer :bahnhof:

Danke an jeden mit nem Tipp! :idea:
Sicher, dass du während des Annäherns an dein ursprüngliches Programm in dein KKB nicht den fehler irgendwo schon eingebaut hast? Mir scheint's wirklich komplett in ordnung zu sein.
 

hdi

Top Contributor
Ich hab noch die gleiche Version wie du.

Zu dem Snappen: Klick mal eine Zeile an, dann scroll ein wenig an der Bar, sodass diese Zeile nur noch halb sichtbar ist. Jetzt klick auf den Button.
Es sollte nicht lange dauern bis es mal NICHT snappt... Also bei mir passiert das relativ schnell.

Und wenn du eben mit dieser Sache etwas rumspielst, mal ne halb-sichtbare Zelle oben anklicken und auf den Button, dann eine unten, bisschen rumscrollen usw...
Dann sollte bei dir irgendwann auch der Dialog nicht angezeigt werden.

Ich hab auch überprüft was passiert wenn man in diesem Moment (der Dialog ist ja da, nur nicht sichtbar) das Fenster wegmacht und neu herholt. Der Dialog ist dann aber noch immer nicht da.

Was man als nächstes probieren könnte: Den Dialog NICHT auf der Table anzeigen, sondern zB einfach links oben auf dem Desktop.

.. aber bitte versuch erstmal zu rekonstruieren was ich gerade sagte. Kann ja eig nicht möglich sein dass es bei dir nie zum Fehler kommt mit dem selben Code ?!

DANKE!
 

0x7F800000

Top Contributor
Zu dem Snappen: Klick mal eine Zeile an, dann scroll ein wenig an der Bar, sodass diese Zeile nur noch halb sichtbar ist. Jetzt klick auf den Button.
Es sollte nicht lange dauern bis es mal NICHT snappt... Also bei mir passiert das relativ schnell.
Bei mir passiert es relativ immer: wenn man eine markierte zeile halb-rausscrollt, und dann darauf rumklickt, "snappt" es überhaupt nicht: die zeile bleibt stets teilweise versteckt. Snappen passiert nur, wenn man eine halb-versteckte unmarkierte Zeile anklickt. Das Dialog erscheint stets dann wenn man den erwartet... ???:L
Und wenn du eben mit dieser Sache etwas rumspielst, mal ne halb-sichtbare Zelle oben anklicken und auf den Button, dann eine unten, bisschen rumscrollen usw...
Dann sollte bei dir irgendwann auch der Dialog nicht angezeigt werden.
nein, immer noch nichts unauffälliges...
Was man als nächstes probieren könnte: Den Dialog NICHT auf der Table anzeigen, sondern zB einfach links oben auf dem Desktop.
keep it simple & stupid klingt gut...
.. aber bitte versuch erstmal zu rekonstruieren was ich gerade sagte. Kann ja eig nicht möglich sein dass es bei dir nie zum Fehler kommt mit dem selben Code ?!
Wieso nicht? Die Umsetzung von Swing und AWT ist irgendwo früher oder später Betriebssystem & JRE-versionsabhängig, vielleicht snappt da schon irgendwo der eine oder der andere Bit irgendwie anders als gewünscht. :bahnhof:
 

Schandro

Top Contributor
bei mir (Win XP, JRE 1.6.0_14) verliert das Fenster den Focus sobald ich auf den Button drücke, und friert komplett ein. Es öffnet sich kein weiteres Fenster/Dialog/...
 

ModellbahnerTT

Bekanntes Mitglied
bei mir (Win XP, JRE 1.6.0_14) verliert das Fenster den Focus sobald ich auf den Button drücke, und friert komplett ein. Es öffnet sich kein weiteres Fenster/Dialog/...
Bei mir auch, ersetz mal das pack() durch ein setSize(), dann funktioniert's.

@hdi: mehr als maximal 2 Seiten gibts zu dem thema EDT auch nicht zu schreiben :rolleyes:
 

0x7F800000

Top Contributor
bei mir (Win XP, JRE 1.6.0_14) verliert das Fenster den Focus sobald ich auf den Button drücke, und friert komplett ein. Es öffnet sich kein weiteres Fenster/Dialog/...

hmm... Dann hat man wohl von XP auf Vista doch irgendwas verbessert, oder von JRE 1.6.0_7 auf 1.6.0_14 irgendwas verschlimmbessert :autsch:
 

Illuvatar

Top Contributor
bei mir (Win XP, JRE 1.6.0_14) verliert das Fenster den Focus sobald ich auf den Button drücke, und friert komplett ein. Es öffnet sich kein weiteres Fenster/Dialog/...

Das dachte ich anfangs auf, dann ist mir aber aufgefallen dass der Dialog ganz einfach direkt über dem Button erscheint, ich hab nur nicht gemerkt dass da jetzt ein anderer Button ist. Vielleicht ist das bei dir ja auch so ;)

@topic
Komisch ich hab da vorhin auch kurz rumprobiert und kein Fehlverhalten gefunden. Jetzt hab ichs grad nochmal probiert - und es passiert, so wie 0x7F800000 es sagt, fast immer. Was mir noch auffällt: Anfangs dachte ich, das Verhalten wäre immer gleich in Abhängigkeit von der Scrollweite. Ist es aber doch nicht, und vor allem nach einem Programmneustart verhält es sich schon wieder ganz anders.
Dass kein Dialog auftaucht hab ich aber glaub noch nicht gesehen.

(Windows 7, Java 1.6.0_15)
 

hdi

Top Contributor
mehr als maximal 2 Seiten gibts zu dem thema EDT auch nicht zu schreiben
ich vermisse zB. eine komplette Auflistung aller API-Methoden, die vom EDT aufgerufen werden. Dann müsste man das nicht immer mit currentThread() prüfen müssen. Soweit ich weiss steht dazu in der API nix.

Also dass es irgendwie bei jedem anders ist, ist mal krass. Zum "übersehen" vom Button: Der sollte eigentlich auch blau sein, ich glaube nicht dass man das übersehen kann. Ist der Dialog-Button etwa bei euch nicht blau?

...Nagut.. also ich versuch das mal von vorne, und zieh es anders auf. Vorallem: Ich teste jetzt ab jeder neuen Code-Zeile, das hab ich bisher leider nicht getan...

so far, danke für eure Hilfe!
 

0x7F800000

Top Contributor
...Nagut.. also ich versuch das mal von vorne, und zieh es anders auf. Vorallem: Ich teste jetzt ab jeder neuen Code-Zeile, das hab ich bisher leider nicht getan...
kannst ja mal den button knallrot machen und alles automatisch mit robot clicks+screenshots testen oder so ;)
oder einfach keine zu abgefahrene guis basteln, wie du siehst konnten damit einige leute auch nichts anfangen :bae:
 

hdi

Top Contributor
Java:
oder einfach keine zu abgefahrene guis basteln
Aber ich wollte mal einfach ne schöne GUI machen, nicht so 0815. In meinem Programm sieht das auch alles ziemlich geil aus, nicht so wie im Test natürlich ;) Ich bin soweit auch zufrieden, saß schon fast 50 Stunden dran, aber dieser Schmarrn nervt halt jetzt. Wie gerne würd ich das Problem finden wollen =(.

Also Fakt ist, es existiert schon in dem KKB, und das ist ja nicht sonderlich kompliziert. Also muss man doch irgendwie rausfinden können, woran das hängt.

Ich bin noch immer der Meinung, dass ihr nicht oft genug rumgeklickt habt, wenn der Dialog IMMER angezeigt wird ;) Oder aber ihr feuert mit der Maustaste einfach drauf los, und klickt den (unsichtbaren!) Dialog-Button sofort, sodass ihr es nicht mitkriegt.

Also der Fehler ist da, nur wo???
 

0x7F800000

Top Contributor
Ich bin noch immer der Meinung, dass ihr nicht oft genug rumgeklickt habt
ne, komm, dann schreib mal gleich nen bot^^ ;)
Oder aber ihr feuert mit der Maustaste einfach drauf los, und klickt den (unsichtbaren!) Dialog-Button sofort, sodass ihr es nicht mitkriegt.
Hab mir diese tasten extra rot und grün angemalt, da ist so viel bewegung beim klicken, das zu übersehen ist imho unmöglich.
 

Illuvatar

Top Contributor
Zum "übersehen" vom Button: Der sollte eigentlich auch blau sein, ich glaube nicht dass man das übersehen kann. Ist der Dialog-Button etwa bei euch nicht blau?

Der blaue Button sieht eben ziemlich ähnlich aus wie der "normale" Button im Zustand wenn er gerade gedrückt ist. So hatte ich eben anfangs das Gefühl, das Programm wäre komplett eingefroren gerade in dem Zustand wo der Button noch unten ist.
 

hdi

Top Contributor
So, ich habe einige weitere Dinge ausprobiert:

1) Dialog nicht-modal machen -> same
2) Dialog nicht auf der Table angezeigt, sondern weit weg vom Frame -> same
3) JFrame statt Dialog -> AHA!

es ist wie folgt: Das Frame hat das gleiche Problem: Manchmal wird der Button nicht angezeigt. Aber da das Frame einen Rahmen hatte (liegt also wohl nicht am Frame, sondern am undecorated(false)), hat man zumindest diesen gesehen.
Beim resize des Frames erschien dann plötzlich der Button.

D.h.: Manchmal (warum gilt herauszufinden) werden die Komponenten nicht gemalt. Es wundert mich ein wenig dass nach Resize der Button da war, denn sowas in der Art dachte ich schon beim Dialog. Da hab ich dann das Fenster weggeklickt und neugeholt, da müsste er ja eig. repainten, so wie beim resize. Allerdings erschien da der Dialog nach wie vor nicht.. Naja ein undecorated modal dialog repainted sich vllt anders als ein normales JFrame.

..ich hab dann mal den ultimativen Test gemacht:

Java:
public class KKB extends JFrame {

	public static void main(String[] args) {
		new KKB().setVisible(true);
	}

	public KKB() {
		setDefaultCloseOperation(EXIT_ON_CLOSE);

		JButton b = new JButton("open");
		b.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				new TestFrame().setVisible(true);
			}
		});

		add(b);
		pack();
		setLocationRelativeTo(null);
	}

	class TestFrame extends JFrame {
		public TestFrame() {
			add(new JButton("If you can't see this, java sucks big time"));
			pack();
		}
	}
}

Ergebnis: Das scheint zu funktionieren :toll:... :lol:

Naja, also ich vermute mal stark es liegt irgendwo beim JTable/ScrollPane.
Irgendwas überfordert den EDT da...

Ich versuch weiter und bin um jede Hilfe weiterhin dankbar.

PS: An alle, bei denen das KKB einwandfrei funktioniert: Ich hoffe nicht, dass das stimmt ;) Vllt versucht ihr ja doch noch mal, den Fehler hinzukriegen. Sonst hab ich wirklich ein Problem, wenn es irgendwie OS-abhängig ist...

Danke

edit: Eig. kann es ja jetzt nur noch an dem CellEditor&Renderer von dem JTable liegen. Schaut euch doch das mal bitte an, in dem KKB. Ansonsten wüsste ich nicht wo das Problem jetzt noch liegen kann, außer es ist in java einfach so, dass man sowas in nem JTable besser nicht tun sollte xD Aber das wär ja doof... glaub ich jetzt auch nicht wirklich.
 
Zuletzt bearbeitet:
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen


Oben