BlueJ Methodenliste ordnen?

1 Antwort

Vom Fragesteller als hilfreich ausgezeichnet

Da es meines Wissens nach bisher keine Einstellung oder Extension dafür gibt, müsstest du wohl selbst Hand anlegen.

Ich habe einmal kurz in den Quellcode zu BlueJ geschaut. In bluej.pkgmgr.target.ClassTarget.getContextOperations wird wohl das gesamte Kontextmenü zusammengebaut und bluej.views.View.getAllMethods ermittelt die Methoden dafür.

Für die Sortierung der Methodeneinträge wird die innere Klasse ElementComparer genutzt:

Collections.sort(methods, new ElementComparer());

Es müsste folglich ein anderer Comparator eingesetzt werden, in dem definiert wird, wie die Sortierung nun aussehen soll.

Emi011 
Fragesteller
 05.07.2021, 20:25

okay, wie mache ich das am besten? kann ja schwer in den Quellcode reinschreiben oder?

0
regex9  05.07.2021, 23:50
@Emi011

Das wäre der direkteste / schnellste Weg. Danach kompilierst du BlueJ neu und testest, ob die Änderung erfolgreich war und keine anderen Funktionalitäten ungewollt beeinflusst hat. Von neuen BlueJ-Versionen könntest du jedoch nicht so leicht profitieren bzw. du müsstest je Version deine eigene geänderte BlueJ-Version zusammenbauen.

Die weitsichtigere Lösung wäre dahingehend der Bau einer Extension. Wie das geht, wird in der BlueJ-Dokumentation angeführt. Der Guide stellt sogar eine Möglichkeit vor, wie man eigene Menüs ergänzen kann. Ob deswegen auch eine Änderung eines bestehenden Menüs möglich ist, kann ich nicht sagen.

Du müsstest erst einmal herausfinden, ob bspw. getObjectMenuItem das richtige Menü anspricht und wenn ja, welche Zugriffsoptionen dir BObject liefert. Am besten analysierst du das Objekt einmal zur Laufzeit via Debugger. Im besten Fall erlangst du Zugriff auf die Oberflächenkomponente für das Kontextmenü und könntest somit auch die jeweiligen Menüitems anfassen.

Als Ausweichweg müsstest du eine normale Extension schreiben. Den Comparator dürfte man via ClassLoader ersetzen können. Dieser Prozess bedeutet im Prinzip: Den Code der äußeren Klasse (View) als String/Byte-Array einlesen, ändern, neuladen.

Das könnte ungefähr so aussehen:

static class ReloadViewClass extends ClassLoader {
  @Override
  public Class<?> loadClass(String name) throws ClassNotFoundException {
    if (!name.equals("bluej.views.View")) {
      return getParent().loadClass(name);
    }

    try (InputStream stream = ReplaceComparator.class.getClassLoader().getResourceAsStream("path/to/View.class")) {
      // read code and replace ElementComparer ...
      return defineClass(name, newCode, 0, numberOfChars);
    }
    catch (IOException ex) {
      throw new ClassNotFoundException("", ex);
    }

    return getParent().loadClass(name);
  }
}

// with extension initialization:
new ReloadViewClass().loadClass("bluej.views.View");

Bevor du solche Änderungen vornimmst, würde ich allerdings prüfen, wofür der Comparator alles benutzt wird. Ansonsten beeinflusst du dir möglicherweise ungewollt noch andere Auflistungen in der Reihenfolge.

Statt dem Comparator könnte man auch die getAllMethods-Methode überschreiben.

0