JTree - sehr individuell

Boreallis

Mitglied
Hey,

habe einige Probleme bei meinem aktuellen Projekt.
Es geht um ein Plugin, das ich für den EJE (Editing Java Easily) schreibe. Dabei sollen JUnit Test Ergebnisse "grafisch ansprechend" präsentiert werden.

Das Tests ausführen etc funktioniert; ein Teil der Ergebnisse wird mit einer Progressbar und ein paar Labels gezeigt, aber der wirklich wichtige Punkt, die Anzeige der fehlgeschlagenen Tests, fehlt noch. Dazu wollte ich gerne einen JTree verwenden.

Ein Ergebnis eines fehlgeschlagenen Tests mal als Beispiel:
setHourTestRight1(TimeOfDayTest)
java.lang.AssertionError: hour_<=_23
at TimeOfDaySpecContract.pre_setHour(TimeOfDaySpecContract.java:13)
at TimeOfDay.pre_setHour(TimeOfDay.java)
at TimeOfDay.setHour(TimeOfDay.java)
at TimeOfDayTest.setHourTestRight1(TimeOfDayTest.java:41)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:24)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
at org.junit.runner.JUnitCore.run(JUnitCore.java:136)
at org.junit.runner.JUnitCore.run(JUnitCore.java:117)
at de.kuestermann.eje.plugins.junitactions.JUnitStartButtonAction.<init>(JUnitStartButtonAction.java:74)
at de.kuestermann.eje.plugins.junitgui.JUnitToolBar$1.actionPerformed(JUnitToolBar.java:42)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.AbstractButton.doClick(Unknown Source)
at javax.swing.plaf.basic.BasicMenuItemUI.doClick(Unknown Source)
at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(Unknown Source)
at java.awt.AWTEventMulticaster.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)

Jetzt hätte ich den JTree gerne folgendermaßen aufgebaut:
- Wurzel: Testklassenname (hier: TimeOfDayTest)
- Kinder: die fehlerhaften Testmethoden (hier: setHourTestRight1) zusammen mit der Exception (hier: java....AssertionError), wobei ich das gerne in 2 Zeilen hätte.
- Kinder darunter: Ausgabe des gesamten Trace in einem ScrollPane, damit das nicht den Tree so extrem "auseinanderreißt"..
- Vor die ersten beiden Sachen ein roter Punkt als Icon, um das Fehlschlagen zu markieren..

Jetzt mein Vorgehen / meine Probleme:
- Ich hab das erstmal ganz banal probiert mit DefaultCellRenderer etc und hab die 2 Zeilen oben einfach mit html Code eingefügt und das Icon davor gesetzt.. (bekommt man es hin, dass das Icon nicht zentriert in der Mitte der beiden Zeilen sondern bündig an der ersten ist?)
- Dann hab ich einen eigenen CellRenderer gebaut, weil ich ja eigentlich ein JScrollPane als Node haben will.. jetzt gilt ja aber das dann für jeden Knoten.. gibt es da einen Ausweg bzw eine Möglichkeit mehrere "Styles" parallel zu nutzen?
- Ich hab es auch schon hinbekommen, die Nodes als ScrollPanes darzustellen.. allerdings sind die vollkommen "tot" .. ich kann also nicht scrollen.. woran könnte das liegen?

Hier noch ein (sehr schlechtes) Bild davon, wie ich es mir erträume..


Ist es ungefähr verständlich was ich versuche und wo es scheitert?
Wenn ja, wäre ich für jede Hilfe dankbar. 😉
 
Es geht um ein Plugin, das ich für den EJE (Editing Java Easily) schreibe.
Was es nicht alles gibt. Für sowas gibt jemand Geld aus? :noe:
Ein Scrollpane in einem Tree? Das ist schon etwas merkwürdig.
Ich denke du wirst dir sehr viel leichter tun (und den User weniger verwirren) wenn du es wie bei Eclipse zweigeteilt machst.
8.jpg
 
Ne keine Angst, dafür gibt keiner Geld aus. 😉
Bin Student und das ist ein Projekt, an dem ich teilnehme.. (als Alternative zu ner Prog Vorlesung).

Das mit dem ScrollPane werd ich wohl wirklich verwerfen, das scheint sehr kompliziert und nicht besonders schick zu sein.
Aber die Art, wie es in Eclispe ist, gefällt mir auch nicht. Wollte es schon gerne "zusammen" haben.. also ein einem Baum.

Ich bin jetzt doch wieder beim "Trace Kürzen" Ansatz.. wenn ich den kürze, geht es ja, dass ich die paar Zeilen mit html an einen Knoten hänge.
Dazu ein paar Fragen:
- Nochmal wegen dem Icon, das vorne dran soll: Gibt es da eine Möglichkeit, dass dieses in der ersten Zeile bleibt?
- Trace kürzen: Irgendwelche Ideen, wie man das sinnvoll machen könnte? Bei dem Beispiel oben wären bspw. die ersten 4 Zeilen interessant zu sehen.. bei einem anderen Test sieht es anders aus:
getListenElementTestErrorCondition2(ListeDVTest)
java.lang.AssertionError: Expected exception: java.lang.AssertionError
at org.junit.internal.runners.statements.ExpectException.evaluate(ExpectException.java:32)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:24)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
at org.junit.runner.JUnitCore.run(JUnitCore.java:136)
at org.junit.runner.JUnitCore.run(JUnitCore.java:117)
at de.kuestermann.eje.plugins.junitactions.JUnitStartButtonAction.<init>(JUnitStartButtonAction.java:74)
at de.kuestermann.eje.plugins.junitgui.JUnitToolBar$1.actionPerformed(JUnitToolBar.java:42)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.AbstractButton.doClick(Unknown Source)
at javax.swing.plaf.basic.BasicMenuItemUI.doClick(Unknown Source)
at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(Unknown Source)
at java.awt.AWTEventMulticaster.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)

Da finde ich eigentlich gar nicht interessantes am Trace. (das Plugin soll vor allem für die Ersties sein.. denk die können damit auch nicht viel anfangen)

Meine Frage also: Wie würdet ihr den Trace versuchen sinnvoll zu kürzen? Dachte daran den Ordner, in dem der Test ist zu durchsuchen und die Namen mit den Namen hinten in der Klammer abzugleichen.. und dann eben nur ausgeben, wenn da die Klassen vorkommen, die man dann auch öffnen kann und nachschauen kann, wo der Fehler liegt.
Ist das so umsetzbar? Ist das sinnvoll? Gibt es alternative Ideen?
 
Hey,

habe das nun so umgesetzt.
Hier ein Foto vom aktuellen Stand bei "Mülltrace":



Und mit sinnvollem Trace:




Als nächsten Schritt will ich folgendes bauen:
Wenn der Trace so sinnvolle Infos enthält wie die Vertragsklasse und die Zeile in der dort was schiefgeht, soll durch Klick auf diese Stelle die entsprechende Klasse ggf. geöffnet und die entsprechende Zeile markiert werden.
Um das im EJE zu machen brauch ich logischerweise den Klassennamen und die Zeile..

Jetzt hab ich aber den ganzen Trace ja als einen Node gespeichert.. das heißt ich kann die nicht einzeln ansprechen oder?
Ich kann die Zeilen auch einzeln speichern.. dann sollte das irgendwie gehen, aber wie bekomme ich sie dann so schön im Block ausgegeben wie bisher?

Verständlich? Jemand ne Idee oder eine Anregung, was ich mir mal genauer anschauen wollte?
 

Neue Themen


Zurück
Oben