Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > de.comp.lang.java > #12987 > unrolled thread

JUnit Test von JButton: Action wird nicht erkannt

Started by"Christian H. Kuhn" <qno-news@qno.de>
First post2016-07-14 01:09 +0200
Last post2016-07-17 16:02 +0200
Articles 9 on this page of 29 — 3 participants

Back to article view | Back to de.comp.lang.java


Contents

  JUnit Test von JButton: Action wird nicht erkannt "Christian H. Kuhn" <qno-news@qno.de> - 2016-07-14 01:09 +0200
    Re: JUnit Test von JButton: Action wird nicht erkannt "Christian H. Kuhn" <qno-news@qno.de> - 2016-07-14 18:26 +0200
    Re: JUnit Test von JButton: Action wird nicht erkannt Patrick Roemer <sangamon@netcologne.de> - 2016-07-14 19:47 +0200
      Re: JUnit Test von JButton: Action wird nicht erkannt "Christian H. Kuhn" <qno-news@qno.de> - 2016-07-15 00:08 +0200
        Re: JUnit Test von JButton: Action wird nicht erkannt Patrick Roemer <sangamon@netcologne.de> - 2016-07-15 22:04 +0200
          Re: JUnit Test von JButton: Action wird nicht erkannt "Christian H. Kuhn" <qno-news@qno.de> - 2016-07-15 22:53 +0200
          Re: JUnit Test von JButton: Action wird nicht erkannt "Christian H. Kuhn" <qno-news@qno.de> - 2016-07-15 23:09 +0200
            Re: JUnit Test von JButton: Action wird nicht erkannt Patrick Roemer <sangamon@netcologne.de> - 2016-07-15 23:44 +0200
              Countdown Timer Design (was: JUnit Test von JButton: Action wird nicht erkannt) "Christian H. Kuhn" <qno-news@qno.de> - 2016-07-16 23:44 +0200
                Re: Countdown Timer Design "Christian H. Kuhn" <qno-news@qno.de> - 2016-07-17 12:44 +0200
                Re: Countdown Timer Design "Christian H. Kuhn" <qno-news@qno.de> - 2016-07-17 15:49 +0200
                  Re: Countdown Timer Design "Christian H. Kuhn" <qno-news@qno.de> - 2016-07-17 17:03 +0200
                    Re: Countdown Timer Design "Christian H. Kuhn" <qno-news@qno.de> - 2016-07-19 15:59 +0200
          Re: JUnit Test von JButton: Action wird nicht erkannt "Christian H. Kuhn" <qno-news@qno.de> - 2016-07-19 14:59 +0200
            Re: JUnit Test von JButton: Action wird nicht erkannt "Christian H. Kuhn" <qno-news@qno.de> - 2016-07-19 16:06 +0200
            Re: JUnit Test von JButton: Action wird nicht erkannt Patrick Roemer <sangamon@netcologne.de> - 2016-07-19 18:59 +0200
              Re: JUnit Test von JButton: Action wird nicht erkannt "Christian H. Kuhn" <qno-news@qno.de> - 2016-07-19 22:35 +0200
                Re: JUnit Test von JButton: Action wird nicht erkannt Patrick Roemer <sangamon@netcologne.de> - 2016-07-20 13:00 +0200
                  Re: JUnit Test von JButton: Action wird nicht erkannt "Christian H. Kuhn" <qno-news@qno.de> - 2016-07-23 20:36 +0200
                    Re: JUnit Test von JButton: Action wird nicht erkannt "Christian H. Kuhn" <qno-news@qno.de> - 2016-07-23 23:15 +0200
            Re: JUnit Test von JButton: Action wird nicht erkannt Wanja Gayk <brixomatic@yahoo.com> - 2016-07-19 23:02 +0200
              Re: JUnit Test von JButton: Action wird nicht erkannt "Christian H. Kuhn" <qno-news@qno.de> - 2016-07-20 12:33 +0200
      GUI-Update über Swing-EDT (was: JUnit Test von JButton: Action wird nicht erkannt) "Christian H. Kuhn" <qno-news@qno.de> - 2016-07-15 12:03 +0200
        Re: GUI-Update über Swing-EDT Patrick Roemer <sangamon@netcologne.de> - 2016-07-15 22:43 +0200
          Re: GUI-Update über Swing-EDT "Christian H. Kuhn" <qno-news@qno.de> - 2016-07-15 23:18 +0200
          Re: GUI-Update über Swing-EDT "Christian H. Kuhn" <qno-news@qno.de> - 2016-07-16 15:24 +0200
            Re: GUI-Update über Swing-EDT Patrick Roemer <sangamon@netcologne.de> - 2016-07-16 16:42 +0200
              Re: GUI-Update über Swing-EDT "Christian H. Kuhn" <qno-news@qno.de> - 2016-07-16 23:05 +0200
                Re: GUI-Update über Swing-EDT "Christian H. Kuhn" <qno-news@qno.de> - 2016-07-17 16:02 +0200

Page 2 of 2 — ← Prev page 1 [2]


#13024

FromWanja Gayk <brixomatic@yahoo.com>
Date2016-07-19 23:02 +0200
Message-ID<MPG.31f8b3c652434e639896bf@news.aioe.org>
In reply to#13019
In article <dv6mjhFqq9cU1@mid.individual.net>, Christian H. Kuhn (qno-
news@qno.de) says...
> Den Gedanken habe ich aufgegriffen und mal implementiert. Die TimeSource
> darf sich dabei aussuchen, welche Zeiteinheit sie verwendet; es muss nur
> ein ganzzahliger Bruchteil einer Sekunde sein.
> 
> public interface QTimeSource {
>     long getFactorToSeconds(); // erlaubt versch. time units
>     long getNow();
> }
> 

Ich schätze die Klasse "TimeUnit" könnte dich interessieren.

Siehe: 
https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/TimeUnit.
html

Gruß,
-Wanja-

-- 
..Alesi's problem was that the back of the car was jumping up and down 
dangerously - and I can assure you from having been teammate to 
Jean Alesi and knowing what kind of cars that he can pull up with, 
when Jean Alesi says that a car is dangerous - it is. [Jonathan Palmer]

[toc] | [prev] | [next] | [standalone]


#13025

From"Christian H. Kuhn" <qno-news@qno.de>
Date2016-07-20 12:33 +0200
Message-ID<dv92dbFdj54U1@mid.individual.net>
In reply to#13024
Am 19.07.2016 um 23:02 schrieb Wanja Gayk:
> Ich schätze die Klasse "TimeUnit" könnte dich interessieren.

Allerdings. Bin mir nur nicht sicher, ob sie mir hier hilft.
Entsprechend ihrem Package sind die Funktionen sleep(), timedJoin() und
timedWait() wohl die Kernpunkte, die Umwandlungen sind „Zugabe“. Und an
der Stelle brauche ich wohl hauptsächlich die Umrechnungen. Bei denen
bin ich aber bislang flexibler. Ich kann problemlos in
Achtel-Millisekunden arbeiten :-) Ob mir das was bringt, ist was anderes ...

lg
QNo

[toc] | [prev] | [next] | [standalone]


#12992 — GUI-Update über Swing-EDT (was: JUnit Test von JButton: Action wird nicht erkannt)

From"Christian H. Kuhn" <qno-news@qno.de>
Date2016-07-15 12:03 +0200
SubjectGUI-Update über Swing-EDT (was: JUnit Test von JButton: Action wird nicht erkannt)
Message-ID<durqo5F8hcgU1@mid.individual.net>
In reply to#12989
Topic adapted.

Am 14.07.2016 um 19:47 schrieb Patrick Roemer:
> Responding to Christian H. Kuhn:
> Das muss alles über den Swing-EDT laufen.

Ich habe ne Nacht drüber geschlafen. Und die Doku zu SwingUtilities
gelesen :-)

Um herauszufinden, was wie arbeitet, lasse ich das GUI-Modell als
autonomous view mal unangetastet. Ja, presentation model ist besser und
kommt auch noch. Ein Schritt nach dem anderen.

Aufrufe zur Änderung des GUI-Zustands aus den Tests können mit
SwingUtilities.invokeAndWait() auf den Swing-EDT gelegt werden.

QChessClock greift auf die GUI ausschließlich per notifyObservers() und
darin implementiert über die verschiedenen update() zu. QChessClock
weiss nichts über die Art seiner Oberfläche. Deshalb kommt ein Aufruf
von notifyObservers() (sowieso nicht, ist zu lang und zu komplex und
könnte den EDT blockieren) oder der einzelnen update() per
invokeAndWait() nicht infrage.

QChessClockJavaAVTest greift nur an einer Stelle anders als per
notifyObservers() direkt schreibend auf die GUI zu. Die Stelle ist auf
invokeAndWait() geändert. Alle anderen Schreibzugriffe erfolgen über
notifyObservers(). Die Testklasse darf wissen, dass das Testobjekt in
Swing realisiert ist; es wäre möglich, notifyObservers() (eher nicht,
s.o.) oder update() mit invokeAndWait() aufzurufen. Da das Problem aber
ohnehin in der GUI gelöst werden muss, s.o., brauche ich am Test nichts
zu ändern.

Ich merke, dass ich immer noch in der Vorstellung lebe, dass Objekte und
mit ihnen alle ihre Eigenschaften und Methoden in einem Thread leben.
Für Objekt und Felder mag das gelten, Methoden leben aber in dem Thread,
der sie aufruft. Das übersehe ich gerne. In QChessClockJavaAV betrifft
das die verschiedenen update()-Methoden. Die werden nicht unbedingt in
dem Thread ausgeführt, in dem die GUI angelegt wird. Und selbst wenn:
Sie verändern den GUI-Zustand und gehören daher in den Swing-EDT. Also
ändere ich alle update()-Methoden so, dass sie ihre Schreibzugriffe über
invokeAndWait() ausführen. v0.8.5

Die Zeitprobleme kommen extra.

lg
QNo

[toc] | [prev] | [next] | [standalone]


#12994 — Re: GUI-Update über Swing-EDT

FromPatrick Roemer <sangamon@netcologne.de>
Date2016-07-15 22:43 +0200
SubjectRe: GUI-Update über Swing-EDT
Message-ID<nmbhss$ub4$1@newsreader4.netcologne.de>
In reply to#12992
Responding to Christian H. Kuhn:
> QChessClock greift auf die GUI ausschließlich per notifyObservers() und
> darin implementiert über die verschiedenen update() zu. QChessClock
> weiss nichts über die Art seiner Oberfläche. Deshalb kommt ein Aufruf
> von notifyObservers() (sowieso nicht, ist zu lang und zu komplex und
> könnte den EDT blockieren) oder der einzelnen update() per
> invokeAndWait() nicht infrage.

Natürlich soll QChessClock nichts von Swing wissen. Aber irgendwo musst
Du für den Zugriff auf die GUI halt in den EDT. Und das wäre bei Deinem
aktuellen Codestand halt in den Implementierungen der
#update()-Methoden, wo auf die GUI-Komponenten zugegriffen wird.

> QChessClockJavaAVTest greift nur an einer Stelle anders als per
> notifyObservers() direkt schreibend auf die GUI zu.

Was ist mit #doClick()? Ich bin äußerst zuversichtlich, dass das auch in
den EDT gehört - sonst hätte ich ja auch keine "lost clicks" gesehen. :)
Im von Dir angesprochenen JW-Artikel wird das auch so gemacht. Und auch,
wenn die das nicht so machen: #getChildIndexed() & Co. gehören auch
dahin. Einfach alles, was irgendwie auf GUI-Komponenten zugreift
und/oder GUI-Zustandsänderungen triggert.

> Ich merke, dass ich immer noch in der Vorstellung lebe, dass Objekte und
> mit ihnen alle ihre Eigenschaften und Methoden in einem Thread leben.
> Für Objekt und Felder mag das gelten, Methoden leben aber in dem Thread,
> der sie aufruft.

Das ist eine sehr eigenwillige Beschreibung, und allerspätestens für
Felder grundfalsch. :)

Du hast Dir mit der Schachuhr ein Projekt ausgesucht, wo Du Concurrency
verstehen musst. Mit wolkigen Metaphern kommst Du nicht weit, die
Thematik ist eher wenig intuitiv. Schau vielleicht mal in die
entsprechende Lesson im Oracle-Tutorial:

https://docs.oracle.com/javase/tutorial/essential/concurrency/index.html

Viele Grüße,
Patrick

[toc] | [prev] | [next] | [standalone]


#12997 — Re: GUI-Update über Swing-EDT

From"Christian H. Kuhn" <qno-news@qno.de>
Date2016-07-15 23:18 +0200
SubjectRe: GUI-Update über Swing-EDT
Message-ID<dut2afFi2muU1@mid.individual.net>
In reply to#12994
Am 15.07.2016 um 22:43 schrieb Patrick Roemer:
> Was ist mit #doClick()? Ich bin äußerst zuversichtlich, dass das auch in
> den EDT gehört - sonst hätte ich ja auch keine "lost clicks" gesehen. :)
> Im von Dir angesprochenen JW-Artikel wird das auch so gemacht. Und auch,
> wenn die das nicht so machen: #getChildIndexed() & Co. gehören auch
> dahin. Einfach alles, was irgendwie auf GUI-Komponenten zugreift
> und/oder GUI-Zustandsänderungen triggert.

Ja. Frag mich nicht, wo ich gelesen habe, dass nur Schreibzugriffe
wichtig sind. Oracle sagt: alles.
https://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html

Alle Setter sind inzwischen im edt angekommen. Der Rest schaffts am WE.
Und dann werde ich mal notifyObservers aufsplitten. Zeitanzeige und
Fallblättchen müssen getaktet werden, die beiden anderen Funktionen
haben konkrete Auslöser in verschiedenen Methoden und können von dort
aus aufgerufen werden. Und wenn das läuft, gehe ich das Zeitproblem an.

> Du hast Dir mit der Schachuhr ein Projekt ausgesucht, wo Du Concurrency
> verstehen musst. 

Ich suche mir immer „ganz einfache“ Projekte aus, um was über Tools zu
lernen. Und dann laufen die Tools ganz flott, und 99% des Lerninhalts
beinhalten, dass ich falsche Vorstellungen von „ganz einfach“ habe. Aber
das ist gut so. Dann kann ich das, wenn ich später mal beruflich drüber
stolpere.

> https://docs.oracle.com/javase/tutorial/essential/concurrency/index.html

WE.

lg
QNo

[toc] | [prev] | [next] | [standalone]


#13000 — Re: GUI-Update über Swing-EDT

From"Christian H. Kuhn" <qno-news@qno.de>
Date2016-07-16 15:24 +0200
SubjectRe: GUI-Update über Swing-EDT
Message-ID<duuqu9F1a5U1@mid.individual.net>
In reply to#12994
Am 15.07.2016 um 22:43 schrieb Patrick Roemer:
> https://docs.oracle.com/javase/tutorial/essential/concurrency/index.html

Ich hab nachher ne Stunde S-Bahn vor mir, da lese ich das. Bis dahin
machen mich Zugriffsrechte wahnsinnig.

> #getChildIndexed() & Co. gehören auch
> dahin. 

Genau. getName() ist in meiner Anwendung unkritisch, weil Namen von
GUI-Komponenten nur im Konstruktor gesetzt und nie mehr verändert
werden, da entstehen keine Konflikte, solange nicht lesend auf ein noch
nicht fertig konstruiertes Objekt zugegriffen wird. Ich hoffe, dass die
VM sowas verhindert und ein Objekt erst da ist, wenn der Konstruktor
fertig ausgeführt ist?

Aber TestUtils soll ja allgemeint verwendbar sein, also muss auch
getName() abgesichert werden.

public final class TestUtils {
   private static String staticName;
   public static Component getChildNamed(final Component _parent, final
String _name) {
        class Test {
            private Object object;
            public void setObject(final Object _object) {
                object = _object;
            }
        }
	String name;
	StringBuilder nameBuilder = new StringBuilder();
        try {
            SwingUtilities.invokeAndWait(new Runnable() {

                @Override
                public void run() {
                    _parent.getName(); // das geht
                    name = _parent.getName(); // das geht nicht
		    test.setObject(_parent.getName()); // das geht
		    staticName = _parent.getName(); // das geht
		    nameBuilder.append(_parent.getName()); // das geht
                }
            });
        } catch (InvocationTargetException | InterruptedException e) {
            // TODO
        }
        if (_name.equals(_parent.getName())) {
            return _parent;
        }
   (...)
   }
}

run() kann also auf die Variablen der Umgebung, aus der invokeAndWait()
aufgerufen wird, lesend zugreifen, nicht aber nicht zuweisen.

run() kann statischen Variablen der Klasse zuweisen. Ergebnisausgabe in
eine statische Variable der Klasse versorgt mich wieder mit eben den
Konkurrenzsituationen, die ich eigentlich lösen möchte.

Ansonsten kann run() anscheinend Variablen von außerhalb keinen Wert
zuweisen. Es können aber deren Methoden aufgerufen werden. Also muss ich
außerhalb ein geeignetes Objekt instantiieren und dem einen Wert
zuweisen (hier einen leeren Stringbuilder, Wert wird mit append()
gesetzt; für einen int fällt mir schon nichts einfaches mehr ein). Gibt
es kein geeignetes Objekt, funktioniert die o.g. Klasse Test.

Gibt es da denn keinen einfachen Weg?

lg
QNo

[toc] | [prev] | [next] | [standalone]


#13001 — Re: GUI-Update über Swing-EDT

FromPatrick Roemer <sangamon@netcologne.de>
Date2016-07-16 16:42 +0200
SubjectRe: GUI-Update über Swing-EDT
Message-ID<nmdh3u$91j$1@newsreader4.netcologne.de>
In reply to#13000
Responding to Christian H. Kuhn:
> Genau. getName() ist in meiner Anwendung unkritisch, weil Namen von
> GUI-Komponenten nur im Konstruktor gesetzt und nie mehr verändert
> werden, da entstehen keine Konflikte, solange nicht lesend auf ein noch
> nicht fertig konstruiertes Objekt zugegriffen wird. Ich hoffe, dass die
> VM sowas verhindert und ein Objekt erst da ist, wenn der Konstruktor
> fertig ausgeführt ist?

Wenn es keine happens-before-Beziehung gibt: Nein. Beispiel:

"The most obvious reason is that the writes which initialize instance
and the write to the instance field can be reordered by the compiler or
the cache, which would have the effect of returning what appears to be a
partially constructed Something. The result would be that we read an
uninitialized object."
https://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#dcl

> 	StringBuilder nameBuilder = new StringBuilder();
>         try {
>             SwingUtilities.invokeAndWait(new Runnable() {
> 
>                 @Override
>                 public void run() {
>                     _parent.getName(); // das geht
>                     name = _parent.getName(); // das geht nicht
> 		    test.setObject(_parent.getName()); // das geht
> 		    staticName = _parent.getName(); // das geht
> 		    nameBuilder.append(_parent.getName()); // das geht
>                 }
>             });

Die letzten drei gehen alle nicht, weil wieder nicht garantiert ist,
dass der main-Thread die Resultate der im EDT ausgeführten Aktion je zu
sehen bekommt. (Schlimmstenfalls bekommt er sie nur teilweise zu sehen.)

public static <T> T fromEDT(Supplier<T> block)
    throws InterruptedException {
  final AtomicReference<T> ret = new AtomicReference<>();
  try {
    SwingUtilities.invokeAndWait(() -> ret.set(block.get()));
  }
  catch (InvocationTargetException exc) {
    Throwable cause = exc.getCause();
    if(cause instanceof Error) {
      throw (Error)cause;
    }
    if(cause instanceof RuntimeException) {
      throw (RuntimeException)cause;
    }
    // shouldn't happen - no checked exceptions from Supplier/Runnable
    throw new RuntimeException(cause);
  }
  return ret.get();
}

String name = SwingHelper.fromEDT(() -> _parent.getName());

Viele Grüße,
Patrick

[toc] | [prev] | [next] | [standalone]


#13002 — Re: GUI-Update über Swing-EDT

From"Christian H. Kuhn" <qno-news@qno.de>
Date2016-07-16 23:05 +0200
SubjectRe: GUI-Update über Swing-EDT
Message-ID<duvlupF6chgU1@mid.individual.net>
In reply to#13001
Am 16.07.2016 um 16:42 schrieb Patrick Roemer:
> Responding to Christian H. Kuhn:
>> Ich hoffe, dass die
>> VM sowas verhindert und ein Objekt erst da ist, wenn der Konstruktor
>> fertig ausgeführt ist?
> 
> Wenn es keine happens-before-Beziehung gibt: Nein.

Google hat mir erzählt, dass ab (oder nach, egal, ich nutze 1.8) Java
1.5 volatile den von mir gewünschten Effekt ergibt, wenn der Konstruktor
sich nicht vor fertigem Aufbau des Objekts in externe Listen o.ä. einträgt.

> public static <T> T fromEDT(Supplier<T> block)
>     throws InterruptedException {
>   final AtomicReference<T> ret = new AtomicReference<>();
>   try {
>     SwingUtilities.invokeAndWait(() -> ret.set(block.get()));
>   }
>   catch (InvocationTargetException exc) {
>     Throwable cause = exc.getCause();
>     if(cause instanceof Error) {
>       throw (Error)cause;
>     }
>     if(cause instanceof RuntimeException) {
>       throw (RuntimeException)cause;
>     }
>     // shouldn't happen - no checked exceptions from Supplier/Runnable
>     throw new RuntimeException(cause);
>   }
>   return ret.get();
> }
> 
> String name = SwingHelper.fromEDT(() -> _parent.getName());

Zuerst nur übernommen, inzwischen auch verstanden. Lambda expressions
sind schon c00l :-)

v0.8.6

lg
QNo

[toc] | [prev] | [next] | [standalone]


#13009 — Re: GUI-Update über Swing-EDT

From"Christian H. Kuhn" <qno-news@qno.de>
Date2016-07-17 16:02 +0200
SubjectRe: GUI-Update über Swing-EDT
Message-ID<dv1hhfFjgv4U1@mid.individual.net>
In reply to#13002
Am 16.07.2016 um 23:05 schrieb Christian „Ingrid“ Kuhn:

> v0.8.6

Und voll über’s Ziel hinausgeschossen.

In der Swing-GUI liegen echte Clicks (und inzwischen auch doClick() aus
den Tests) auf dem EDT. Die entsprechenden Methoden von QChessClock
werden nie niemals nicht von woanders direkt aufgerufen und liegen
ebenfalls auf dem EDT. Diese Methoden rufen notifyXY auf, was wieder
updateXY der GUI aufruft. Immer noch alles auf dem EDT. Damit muss
SwingUtilities.invoke...() in allen diesen Funktionen NICHT benutzt
werden. (G)UI ohne Swing und Tests, die QChessClockInterface
implementieren, müssen da halt aufpassen. Fehlschlagende Tests haben mir
jedenfalls gut gezeigt, wo noch ein notify oder update in den Thread
hineinmuss. Damit werfen diese ganzen Methoden auch nicht mehr die
Exceptions von invoke...(), und das uncaughtExceptions-Gehampel um
actionPerformed() entfällt.

Etwas Anderes ist es mit dem notifyObservers(), das getaktet ausgelöst
wird. Das läuft definitiv auf einem anderen Thread. Hier wird aber nur
Zeit und Blättchenfall kontrolliert. Da gibt es dann eine
Methodendoppelung. QChessClockObserver müssen dann für Zeit und Flags
eine weitere Update-Methode anbieten, in der sie sich z.B. in Swing
darum kümmern, dass die Zugriffe auf den GUi-Status auf den EDT gelegt wird.

Jetzt sortiere ich noch ein wenig. Das wird v0.8.7

lg
QNo

[toc] | [prev] | [standalone]


Page 2 of 2 — ← Prev page 1 [2]

Back to top | Article view | de.comp.lang.java


csiph-web