Berechnung der Position von Kinderelemente von einem Elternknoten

beta20

Top Contributor
Hallo,

ich möchte gerne einen Entscheidungsbaum in einer Web-GUI erstellen. Hierfür habe ich einen Elternknoten und eben die Kinder davon...
Ich stehe nun gerade vor dem Problem, wie ich die Kinder anordnen kann, sodass es korrekt aussieht.

Ich habe dabei folgende Informationen von den Elementen:
- width
- x (Position der X-Achse)
- y
- height

Ich denke folgende Infos sind noch notwendig für die Kinder:
- definierte Breite (bspw. 60px)
- definierter Space zwischen den Kinder (bspw. 20px).

Was ich nun benötige, ist eine Funktion, die mir die Positionen (X-Achse) der Kinder ermittelt, abhängig von der Anzahl an Kindern, sodass alles schön zentriert ist und nicht mehr Elemente auf der rechten oder linken Seite sind...

Im Endeffekte, will ich die grünen generieren:


Folgenden Code habe ich bisher, aber es ist nicht korrekt - die Elemente fangen links an, passen aber nicht wirklich.
Kurze Info: am Anfang erstelle ich immer einen "Else" - Zweig, anschließend dann die "If / Else" - Zweige...

Java:
/**
     * Erstellt dem Tree
     * @param diagramElementBefore
     * @return
     */
    private DiagramElement createDiagramBranchTree(DiagramElement diagramElementBefore) {
       
        int numberOfBranch = diagramElementBefore.getAutomationElement().getDecisionComponent().getIfBranchList().size() + 1;
        int widthBranchElement = 100; // in Pixel
        int spaceBetweenElement = 20;
        int widthTotalAllBranches = ((widthBranchElement + spaceBetweenElement) * numberOfBranch);
        int widthToLeft = (widthTotalAllBranches / 2) - (diagramElementBefore.getWidth() / 2);

        // Else Tree als erstes erstellen
        diagramElementBefore.getAutomationElement().getDecisionComponent().getElseBranch();
        createDiagramBranchElement(diagramElementBefore, diagramElementBefore.getAutomationElement().getDecisionComponent().getElseBranch(), widthToLeft, widthBranchElement);
               
        // If Tree erstellen
        for(DecisionBranch decisionBranch : diagramElementBefore.getAutomationElement().getDecisionComponent().getIfBranchList()) {
            widthToLeft = widthToLeft + widthBranchElement;
            createDiagramBranchElement(diagramElementBefore, decisionBranch, widthToLeft, widthBranchElement);
        }
       
    }
    
    private DiagramElement createDiagramBranchElement(DiagramElement diagramElementBefore, DecisionBranch decisionBranch, int x, int widthBranchElement) {

        DiagramElement newDiagramElement = new DiagramElement();
   
        newDiagramElement.setHeight(20); // definierte Höhe
        newDiagramElement.setWidth(widthBranchElement);
        newDiagramElement.setX(diagramElementBefore.getX() - x);
        newDiagramElement.setY(diagramElementBefore.getY() + diagramElementBefore.getHeight() + 30); // definierter Abstand zum Elternknoten
               
        return newDiagramElement;
    }


Irgendwas stimmt nicht mit meiner Logik....
 

beta20

Top Contributor
Danke... Es kommt dem ganzen sehr nahe, aber ich glaube es passt noch nicht 100%, wenn man sich den mittleren Knoten ansieht:

Java:
    private DiagramElement createDiagramBranchTree(DiagramElement diagramElementBefore) {
        
        int numberOfBranch = diagramElementBefore.getAutomationElement().getDecisionComponent().getIfBranchList().size() + 1;
        int widthBranchElement = 250; // in Pixel
        int spaceBetweenElement = 20;
        
        int width = numberOfBranch * (spaceBetweenElement + widthBranchElement) - widthBranchElement;
        int widthToLeft = (diagramElementBefore.getWidth() / 2) - (width/2);

        // Else Tree erstellen
        diagramElementBefore.getAutomationElement().getDecisionComponent().getElseBranch();
        createDiagramBranchElement(diagramElementBefore, diagramElementBefore.getAutomationElement().getDecisionComponent().getElseBranch(), widthToLeft, widthBranchElement);
                
        // If Tree erstellen
        for(DecisionBranch decisionBranch : diagramElementBefore.getAutomationElement().getDecisionComponent().getIfBranchList()) {
            widthToLeft = widthToLeft + widthBranchElement + spaceBetweenElement;
            createDiagramBranchElement(diagramElementBefore, decisionBranch, widthToLeft, widthBranchElement);
        }
        
        // Andere erstellen
        return diagramElementBefore;
    }

    /**
     * Create Branch for Decision Tree
     *
     * @param diagramElementBefore
     * @return
     */
    private DiagramElement createDiagramBranchElement(DiagramElement diagramElementBefore, DecisionBranch decisionBranch, int x, int widthBranchElement) {

        DiagramElement newDiagramElement = new DiagramElement();
        newDiagramElement.setHeight(20);
        newDiagramElement.setWidth(widthBranchElement);
        newDiagramElement.setX(diagramElementBefore.getX() - x);
        newDiagramElement.setY(diagramElementBefore.getY() + diagramElementBefore.getHeight() + 30);

        return newDiagramElement;
    }


 

mihe7

Top Contributor
Oops, ich habe mich verschrieben: am Ende muss das Space abgezogen werden und nicht die Breite.

Gesamtbreite = n*(definierterSpace+definierteBreite) - definierterSpace;
 

beta20

Top Contributor
Ne, das passt noch weniger...


Ich habe diese Zeile bei mir geändert:

int width = numberOfBranch * (spaceBetweenElement + widthBranchElement) - spaceBetweenElement;
 

mihe7

Top Contributor
Ja, das ist korrekt: bei 3 Elementen hast Du 3 x die Breite der Elemente und 2 x den Abstand dazwischen. Das wäre die Gesamtbreite für 3 Elemente.


Die x-Koordinate der Mitte des Elements ganz links ist centerX-width/2, wobei centerX die x-Koordinate der Mitte des "Graphen" (bzw. des Elternelements) ist.
 

beta20

Top Contributor
hm, das mache ich doch hier?
int widthToLeft = (diagramElementBefore.getWidth() / 2) - (width / 2);

Oder wie sollte man die " x-Koordinate der Mitte des "Graphen" (bzw. des Elternelements) ist." berechnen?
 

mihe7

Top Contributor
Wenn diagramElementBefore das Elternelement ist, und es eine getX()-Methode gibt, die die x-Koordinate der linken Seite der BoundingBox des Elements angibt, dann wäre centerX=diagramElementBefore.getX() + diagramElementBefore.getWidth()/2
 

beta20

Top Contributor
Also das passt immer noch nicht, habe die Änderung hier vorgenommen

Code:
    private DiagramElement createDiagramBranchTree(DiagramElement diagramElementBefore) {

        int numberOfBranch = diagramElementBefore.getAutomationElement().getDecisionComponent().getIfBranchList().size()
                + 1;
        int widthBranchElement = 250; // in Pixel
        int spaceBetweenElement = 20;

        int width = numberOfBranch * (spaceBetweenElement + widthBranchElement) - spaceBetweenElement;
        int centerXParent = diagramElementBefore.getX() + diagramElementBefore.getWidth()/2;
        int widthToLeft = centerXParent - (width / 2);

    // Else Tree erstellen
        diagramElementBefore.getAutomationElement().getDecisionComponent().getElseBranch();
        createDiagramBranchElement(diagramElementBefore,
                diagramElementBefore.getAutomationElement().getDecisionComponent().getElseBranch(), widthToLeft,
                widthBranchElement);

        // If Tree erstellen
        for (DecisionBranch decisionBranch : diagramElementBefore.getAutomationElement().getDecisionComponent()
                .getIfBranchList()) {
            widthToLeft = widthToLeft + widthBranchElement + spaceBetweenElement;
            createDiagramBranchElement(diagramElementBefore, decisionBranch, widthToLeft, widthBranchElement);
        }

    }

    /**
     * Create Branch for Decision Tree
     *
     * @param diagramElementBefore
     * @return
     */
    private DiagramElement createDiagramBranchElement(DiagramElement diagramElementBefore,
            DecisionBranch decisionBranch, int x, int widthBranchElement) {

        DiagramElement newDiagramElement = new DiagramElement();
        newDiagramElement.setDiagramElementBefore(diagramElementBefore);

        newDiagramElement.setHeight(20);
        newDiagramElement.setWidth(widthBranchElement);
        newDiagramElement.setX(x);
        newDiagramElement.setY(diagramElementBefore.getY() + diagramElementBefore.getHeight() + 30);

        return newDiagramElement;
    }
 

mihe7

Top Contributor
widthToLeft deutet auf eine andere Bedeutung hin. Es geht um die absolute x-Koordinate. Das kann man ausrechnen: sagen wir mal das Elternelement befindet sich bei x=400 (linke Kante) und jedes Element hat eine Breite von 100. Dann ist centerX = 400 + 100/2 = 450.

Jetzt hast Du drei Kindelemente mit einem Abstand von 20. Macht eine Gesamtbreite von 3*(100+20)-20 = 340.

Dann fängt die Mitte(!) des linken Kindelements bei x = 450 - 340/2, also bei 280 an. Das zweite Element befindet sich bei 280+120 = 400 (== centerX) und das dritte bei 400+120=520. Jeweils Mitte!
 

beta20

Top Contributor
also, ich habe das jetzt mal mit den gleichen Zahlen durchgespielt....Das passt und sieht korrekt aus...
Wenn die Kinderelemente nun aber eine Breite von 150 bekommen (int widthBranchElement = 150;) dann passt es nicht mehr...
Das zweite Element sieht nicht korrekt aus...
Der Elternknoten hat immer noch eine Breite von 400...

Passt das hier in der Schleife?
widthToLeft = widthToLeft + widthBranchElement + spaceBetweenElement;

Java:
        // If Tree erstellen
        for (DecisionBranch decisionBranch : diagramElementBefore.getAutomationElement().getDecisionComponent()
                .getIfBranchList()) {
            widthToLeft = widthToLeft + widthBranchElement + spaceBetweenElement;
            createDiagramBranchElement(diagramElementBefore, decisionBranch, widthToLeft, widthBranchElement);
        }

Und in der createDiagramBranchElement() - Methode setze ich eben den Wert von Paramater

Java:
private DiagramElement createDiagramBranchElement(DiagramElement diagramElementBefore,
            DecisionBranch decisionBranch, int x, int widthBranchElement) {
...
newDiagramElement.setX(x);
 

mihe7

Top Contributor
Wenn die Kinderelemente nun aber eine Breite von 150 bekommen (int widthBranchElement = 150;) dann passt es nicht mehr...
Das spielt keine Rolle, da Du die Kindelemente komplett unter dem Parent zentrierst.

Was macht denn createDiagramBranchElement? Setzt das das Element oder nur den Strich? Wenn das Element, dann musst Du natürlich berücksichtigen, dass das x die Mitte ist.
 

mihe7

Top Contributor
Hab mal schnell was zusammengeschustert.
Java:
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;

import javax.swing.*;

import java.util.*;
import java.util.function.Consumer;


public class Test {
    static class Node {
        private Rectangle bbox;
        private List<Node> children = new ArrayList<>();

        public Node(Rectangle bbox) { this.bbox = bbox; }
        public void add(Node child) { children.add(child); }
        public int getX() { return bbox.x; }
        public int getY() { return bbox.y; }
        public int getWidth() { return bbox.width; }
        public int getHeight() { return bbox.height; }

        public void draw(Graphics2D g) {
            g.draw(bbox);
        }

        public void forEachChild(Consumer<Node> c) {
            children.forEach(c);
        }
    }

    static class Canvas extends JComponent {
        Node root;

        public void setRoot(Node root) {
            this.root = root;
            repaint();
        }

        @Override
        protected void paintComponent(Graphics g) {
            Graphics2D g2 = (Graphics2D) g;
            paint(g2, root);
        }

        private void paint(Graphics2D g, Node node) {
            if (node != null) {
                node.draw(g);
                node.forEachChild(child -> paint(g, child));
            }
        }
    }

    private Canvas canvas;

    public Test() {
        Rectangle r = new Rectangle(300, 10, 600, 20);
        Node root = new Node(r);
        addChildren(root, 3, 150, 50, 10, 50);
        canvas = new Canvas();
        canvas.setRoot(root);
    }

    private void addChildren(Node node, int count, int width, int height, int hGap, int vGap) {
        int totalWidth = count*(width + hGap) - hGap;
        int centerX = node.getX() + node.getWidth() / 2;
        int cx = centerX - totalWidth / 2;
        int cy = node.getY() + node.getHeight() + vGap;        
        for (int i = 0; i < count; i++) {
            Rectangle rect = new Rectangle(cx, cy, width, height);
            node.add(new Node(rect));
            cx += width + hGap;
        }
    }


    public void run() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.add(canvas);
        frame.setSize(1000, 600);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new Test().run());
    }
}
 

beta20

Top Contributor
Also irgendwas passt einfach nicht...
Hier mal von meinem Debugger:

int numberOfBranch = 2
int widthBranchElement = 150; // in Pixel
int spaceBetweenElement = 20;

totalWidth = 2 * ( 150 + 20) - 20;
-> 320

centerX = 400 + 400 / 2;
-> 600

cx = 600 - 320/2;
-> 440

Heißt das erste Kindelement ist bei:
x = 440

Das zweite bei:
x = 610;
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
I File Uploader... Statusanzeige, Berechnung des Status etc. Java Basics - Anfänger-Themen 0
Bugs Bunny Fehlerhafte Berechnung beim erneuten Durchlaufen der Schleife Java Basics - Anfänger-Themen 5
Jamie logische Verknüpfung zur Schaltjahr-Berechnung Java Basics - Anfänger-Themen 30
Stephan_kl Reihenwert-Berechnung, Ergebnis mit vorherigem Ergebnis vergleichen Java Basics - Anfänger-Themen 11
Abraham42 Berechnung der Kühlung Java Java Basics - Anfänger-Themen 12
S Hashcode-Berechnung + ^ Java Basics - Anfänger-Themen 2
J Median-Berechnung von 2D-Teilarrays Java Basics - Anfänger-Themen 56
F Tabelle - Berechnung Rang Java Basics - Anfänger-Themen 2
S Berechnung der sleep time ist falsch Java Basics - Anfänger-Themen 46
S Switch-Case zur Berechnung der Einkommensteuer Java Basics - Anfänger-Themen 15
F Berechnung der Rektaszension und Deklination eines Sterns Java Basics - Anfänger-Themen 7
2 Taschenrechner mit GUI Problem bei der Berechnung Java Basics - Anfänger-Themen 8
V Erste Schritte Pi Berechnung Java Basics - Anfänger-Themen 47
M Berechnung der Reststrecke bei Graphen Java Basics - Anfänger-Themen 1
V Algorithmus zur fortlaufenden Berechnung des duechscjnt Java Basics - Anfänger-Themen 1
B Berechnung zu einer Schleife formen Java Basics - Anfänger-Themen 6
B Berechnung Median mit Methode Java Basics - Anfänger-Themen 7
CptK Methoden Berechnung von Anfangsgeschwindigkeit und Winkel Java Basics - Anfänger-Themen 27
K Erste Schritte Berechnung der Summe zweier Arrays Java Basics - Anfänger-Themen 15
S Erste Schritte Berechnung des Paketportos - Problem/Frage Java Basics - Anfänger-Themen 52
J Gleitkommazahlen, Berechnung von pi Java Basics - Anfänger-Themen 4
J Berechnung liefert falsches Ergebnis Java Basics - Anfänger-Themen 2
kilopack15 Verzweiflung wegen Berechnung mit Multithreading Java Basics - Anfänger-Themen 1
A Die Werte zur Berechnung müssen als Parameter übergeben werden? Java Basics - Anfänger-Themen 7
Salo Berechnung von Winkeln Java Basics - Anfänger-Themen 28
M Restbuchwert Berechnung geht nicht Java Basics - Anfänger-Themen 45
Ghostman1711 Pi berechnung Methode aufrufen Java Basics - Anfänger-Themen 2
L Rekursive Methode zur Berechnung der Potenz q hoch p Java Basics - Anfänger-Themen 17
beatles Operatoren Operatoren - Berechnung Java Basics - Anfänger-Themen 40
K Best Practice Algorithmus für Berechnung von Zahlenreihenfolge Java Basics - Anfänger-Themen 12
N Verzögerte Berechnung "Lazy" Java Basics - Anfänger-Themen 8
J Erste Schritte Rundungsproblem - Berechnung Notendurchschnitt Java Basics - Anfänger-Themen 13
S Variablen Vektor zur Berechnung verwenden Java Basics - Anfänger-Themen 4
T Java double berechnung fehler Java Basics - Anfänger-Themen 2
M Berechnung in Java Java Basics - Anfänger-Themen 4
S Berechnung der Arbeitstage in einem Zeitraum Java Basics - Anfänger-Themen 9
E Problem bei rekursiver Berechnung des Binomialkoeffizienten Java Basics - Anfänger-Themen 5
T Iterative Pi Berechnung in Rekursive Java Basics - Anfänger-Themen 2
S Double, int, Berechnung Java Basics - Anfänger-Themen 3
C Nach Berechnung runden und Wert ausgeben Java Basics - Anfänger-Themen 7
E Berechnung für Shop einbinden Java Basics - Anfänger-Themen 8
S Klassen Formel zur Berechnung .... Bitte um Hilfe Java Basics - Anfänger-Themen 7
S Euklid Algorithmus zur Berechnung des GGTs Java Basics - Anfänger-Themen 2
OnDemand Berechnung in die start und paint Methode eines Applets Java Basics - Anfänger-Themen 28
P Schleife zur Berechnung von einer Summe Java Basics - Anfänger-Themen 16
F Berechnung einer linearen Abschreibung Java Basics - Anfänger-Themen 5
E Berechnung von Punkten Java Basics - Anfänger-Themen 4
D Berechnung des Abstandes von zwei Punkten in einem Koordinatensystem Java Basics - Anfänger-Themen 14
A Methoden PI-Berechnung Java Basics - Anfänger-Themen 22
S Erste Schritte Berechnung mit Daten aus CSV und Date Objekt Java Basics - Anfänger-Themen 2
C Programm zur Berechnung der Spur einer Matrix Java Basics - Anfänger-Themen 4
P Pythagoras Baum - Berechnung der Punkte Java Basics - Anfänger-Themen 9
A Erste Schritte Steuer Berechnung, Alters Abhängig Java Basics - Anfänger-Themen 5
T Erste Schritte Berechnung von gerade und ungerade Zahlen Java Basics - Anfänger-Themen 10
J Erste Schritte Berechnung Ratten vermehrung Java Basics - Anfänger-Themen 4
P falsches ergebnis bei einfacher berechnung Java Basics - Anfänger-Themen 3
T Iterative Berechnung einer Satellitenbahn Java Basics - Anfänger-Themen 20
M Java Berechnung mit mehreren Lösungen? Java Basics - Anfänger-Themen 9
D Nullstellen-Berechnung Java Basics - Anfänger-Themen 10
L Fehlermeldung bei falscher Berechnung anzeigen Java Basics - Anfänger-Themen 31
A berechnung multiplikatives inverses Java Basics - Anfänger-Themen 5
J Berechnung des aktuellen Alters auf Basis des Geburtstags Java Basics - Anfänger-Themen 45
J Datentypen Fehler bei Berechnung mit Double und Int-Werten Java Basics - Anfänger-Themen 22
G Berechnung von Winkeln mit Cosinussatz Java Basics - Anfänger-Themen 2
B Arrays verwenden für Berechnung Java Basics - Anfänger-Themen 3
R Merkwürdige Modulo Berechnung Java Basics - Anfänger-Themen 7
B Hausaufgabe Berechnung quadratischer Funktion Java Basics - Anfänger-Themen 16
U Alter Berechnung + sortierung Java Basics - Anfänger-Themen 6
P Berechnung wird nicht durchgeführt Java Basics - Anfänger-Themen 2
D Berechnung von Ostern und Ramadan! Java Basics - Anfänger-Themen 24
N Algorithmus für Berechnung einer Quersumme Java Basics - Anfänger-Themen 9
D Berechnung von Geldausgabe Java Basics - Anfänger-Themen 22
F Berechnung von Kugeln! Java Basics - Anfänger-Themen 9
M rekursive Funktion zur Berechnung der Spiegelzahl Java Basics - Anfänger-Themen 7
S Hausaufgabe: Java-Programm schreiben zur Berechnung von x und y Java Basics - Anfänger-Themen 9
Y Ergebnis einer Berechnung an die Main Methode übergeben Java Basics - Anfänger-Themen 11
Semox Ersten Wert eines Intervalls bei Berechnung einschließen Java Basics - Anfänger-Themen 8
J Logarithmische Berechnung und Arrays Java Basics - Anfänger-Themen 2
B LinkedList - Berechnung des Produkts Java Basics - Anfänger-Themen 6
B Berechnung von Preisen per Java-Programm Java Basics - Anfänger-Themen 27
M Alters berechnung aus Geburtsjahr aus dem Buch Java Basics - Anfänger-Themen 5
O Fehler in der String-Distanz-Berechnung Java Basics - Anfänger-Themen 5
-horn- "Berechnung vorwärts, Optimierung rückwärts?" - Wie würdet ihr das machen? Java Basics - Anfänger-Themen 8
P iterative Berechnung Java Basics - Anfänger-Themen 9
1 Berechnung von PI mithilfe von Buffons Nadelproblem Java Basics - Anfänger-Themen 2
G Berechnung zwei Komplexen Zahlen Java Basics - Anfänger-Themen 34
N Rekursive Berechnung der Höhe eines binären Baumes Java Basics - Anfänger-Themen 4
J Programm für interaktive Berechnung von Temperaturverläufen Java Basics - Anfänger-Themen 9
K Annährende ganzzahlige Berechnung der Wurzel Java Basics - Anfänger-Themen 8
L Berechnung von Perioden Java Basics - Anfänger-Themen 4
D einfach berechnung einer onlinezeit Java Basics - Anfänger-Themen 25
S Euklid Klasse mit Methoden zur Berechnung des ggT Java Basics - Anfänger-Themen 23
G Frage zur Primzahlen berechnung Java Basics - Anfänger-Themen 11
G Berechnung von N-Tageslinien von Aktienkursen Java Basics - Anfänger-Themen 13
G Rekursive Berechnung von n über k schlägt fehl Java Basics - Anfänger-Themen 5
G Einfache Berechnung liefert falsches Ergebnis Java Basics - Anfänger-Themen 2
W Schaltjahr Berechnung Java Basics - Anfänger-Themen 24
A Probleme mit Programm zur Pi-Berechnung Java Basics - Anfänger-Themen 6
X Temperatur-Berechnung /Array(?) Java Basics - Anfänger-Themen 5
L Berechnung Summe Java Basics - Anfänger-Themen 3

Ähnliche Java Themen

Neue Themen


Oben