JPanel Formen paralell anordnen

lisaaa17

Mitglied
Ich schreibe gerade ein Programm, das verschiedene Formen miteinander kombiniert und in einem Fenster zeichnet.
Mit Formen sind Kreis und Quadrat gemeint. Mit kombiniert meine ich die Formen entweder nebeneinander (seriell) oder untereinander (paralell).

Das Klassendiagramm zu meinem Programm sieht wie folgt aus:

Klasse Form extends JPanel


Klasse Quadrat extends Form:
-> paint Methode, die ein Kreis zeichneit

Klasse Kreis extends Form:
-> paint Methode, die ein Quadrat zeichnet

Klasse Seriell extends Form:
-> FlowLayout bei dem die beiden übergebenen Formen geadded werden

Klasse Paralell extends Form:
-> spezielles Layout, bei dem die beiden übergebenen Formen geadded werden.

Klasse Verzweigung extends JPanel:
-> paint Methode, die eine Verzeigung (rote Linie) zeichnet (wird für Paralell gebraucht)


Klasse Main:
-> hier wird die Form angelegt. z.B. Kreis und Quadrat Paralell, dazu ein Quadrat in Serie geschalten.

Klasse Window extends JFrame:
-> zeichnet das Panel der übergegebenen Form

Hier eine kurze Grafik:
54345625.png



Hier der Source Code wie ich mir das ganze vorgestellt habe:


Mein Problem ist dass ich nicht weiß, wie ich die Berechnung des OffsetY und der Höhe für die Klasse Verzweigung durchführe.
OffsetY gibt an, wo die rote vertikale Linie beginnt, die Höhe gibt an, wie lange diese sein muss.

Java:
public class Main
{
  public static void main(String[] args)
  {
    Quadrat q = new Quadrat();
    Kreis k = new Kreis();

    Paralell s=new Paralell(q,k);
    Paralell p=new Paralell(s,new Kreis());
    new Window(p);
  }
}


Java:
public class Window extends JFrame
{
  public Window(Form form)
  {
    this.add(form);
    this.setVisible(true);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.pack();
  }
}


Java:
public abstract class Form extends JPanel
{
  Form f1, f2;

  public Form()
  {
  }
}


Java:
public class Seriell extends Form
{
  Form f1, f2;


  public Seriell(Form f1, Form f2)
  {
    this.f1 = f1;
    this.f2 = f2;

    this.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
    this.add(f1);
    this.add(f2);
  }
}


Java:
public class Paralell extends Form
{
    Form f1, f2;


  public Paralell(Form f1, Form f2)
  {
    this.f1 = f1;
    this.f2 = f2;

    JPanel panelForm = new JPanel(new GridLayout(2,1));
    panelForm.add(f1);
    panelForm.add(f2);

    this.setLayout(new FlowLayout(FlowLayout.CENTER, 0,0));

    Verzweigung Links=new Verzweigung(true, f1.GetStartPosition().y, f1.GetHeight()+f2.GetStartPosition().y);
    Verzweigung Rechts=new Verzweigung(false, f1.GetStartPosition().y, f1.GetHeight()+f2.GetStartPosition().y);
    this.add(Links);
    this.add(panelForm);
    this.add(Rechts);
  }
}


Java:
public class Verzweigung extends JPanel
{
  boolean Links;
  int Width = 20;
  int Height;
  int OffsetY


  public Verzweigung(boolean Links, int Height, int OffsetY)
  {
    this.Links = Links;
    this.Height=Height;
    this.OffsetY=OffsetY;
    this.setPreferredSize(new Dimension(Width, Height));
  }


  public void paintComponent(Graphics g)
  {
    super.paintComponent(g);
    g.setColor(Color.red);

    g.drawLine(0, OffsetY, Width, OffsetY);
    g.drawLine(0, OffsetY+Height, Width, OffsetY+Height);
    if (Links)
    {
      g.drawLine(0, OffsetY, 0, OffsetY+Height);
    }
    else
    {
      g.drawLine(Width-1, OffsetY, Width-1, OffsetY+Height);
    }
  }
}


Java:
public class Kreis extends Form
{
  int Width = 50, Height = 20;


  public Kreis()
  {
    this.setPreferredSize(new Dimension(Width, Height));
    System.out.println("Kreis: "+Width+"x"+Height);
  }


  public void paintComponent(Graphics g)
  {
    super.paintComponent(g);
    g.drawLine(0, Height / 2, Width, Height / 2);
    g.fillOval(Width / 2 - 5, Height / 2 - 5, 10, 10);
  }
}


Java:
public class Quadrat extends Form
{
  int Width = 50, Height = 20;


  public Quadrat()
  {
    this.setPreferredSize(new Dimension(Width, Height));
    System.out.println("Quadrat: "+Width+"x"+Height);
  }


  public void paintComponent(Graphics g)
  {
    super.paintComponent(g);
    g.drawLine(0, Height / 2, Width, Height / 2);
    g.fillRect(Width / 2 - 5, Height / 2 - 5, 10, 10);
  }
}
 
Hallo lisaaa17,

ich glaube das ist vor allem ein Layout Problem. Mit GridBagLayout könnte es gehen, siehe angehängte Grafik. Wir müssen dann nur noch bei der Verzweigung eine Option vorsehen für das Malen einer Anschlusslinie (bei den zwei rot eingekreisten Stellen).

Gruß,
André

EDIT: Hier noch ein Beispiel:
Java:
import java.awt.*;
import javax.swing.*;

public class SchemaDemo {

    public static void main(final String[] args) {
        Runnable gui = new Runnable() {

            public void run() {
                Quadrat q = new Quadrat();
                Kreis k = new Kreis();
                final Paralell p1 = new Paralell(q, k);
                Quadrat q2 = new Quadrat();
                Kreis k2 = new Kreis();
                final Paralell p2 = new Paralell(q2, k2);
                final Paralell p3 = new Paralell(p1, p2);
                verzweigen(p1, p2, p3);
                Window window = new Window(p3);
            }
        };
        SwingUtilities.invokeLater(gui);
    }

    public static void verzweigen(final Form... formen) {
        SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                for (Form form : formen) {
                    form.verzweigen();
                }
            }
        });
    }
}

class Paralell extends Form {

    private final JPanel panelForm;
    private final Verzweigung links;
    private final Verzweigung rechts;
    private boolean left;//wegen der Klarheit

    public Paralell(final Form f1, final Form f2) {
        panelForm = new JPanel(new GridLayout(2, 1));
        panelForm.add(f1);
        panelForm.add(f2);
        this.setLayout(new GridBagLayout());
        links = new Verzweigung(left = true);
        rechts = new Verzweigung(left = false);
        GridBagConstraints constraints = new GridBagConstraints();
        constraints.gridx = 1;
        constraints.gridy = 1;
        add(links, constraints);
        constraints.gridx = 2;
        constraints.gridy = 1;
        add(panelForm, constraints);
        constraints.gridx = 3;
        constraints.gridy = 1;
        add(rechts, constraints);
    }

    @Override
    public void verzweigen() {
        Dimension sizePanelForm = panelForm.getPreferredSize();
        links.setHeight(sizePanelForm.height);
        rechts.setHeight(sizePanelForm.height);
    }
}

class Verzweigung extends JPanel {

    private boolean left;
    private int width = 20;
    private int height;
    private int offsetY;
    private int offsetYBottom;
    private Component neighbourTop;
    private Component neighbourBottom;

    public Verzweigung(final boolean links) {
        left = links;
    }

    @Override
    public Dimension getPreferredSize() {
        Dimension preferredSize = super.getPreferredSize();
        preferredSize.height = height;
        preferredSize.width = width;
        return preferredSize;
    }

    public void setHeight(final int height) {
        this.height = height;
        revalidate();
    }

    @Override
    public void paintComponent(final Graphics g) {
        super.paintComponent(g);
        if (neighbourTop == null) {
            neighbourTop = SwingUtilities.getDeepestComponentAt(getParent(),
                    width + 1, 0);
        }
        offsetY = neighbourTop.getHeight() / 2;
        if (neighbourBottom == null) {
            neighbourBottom = SwingUtilities.getDeepestComponentAt(getParent(),
                    width + 1, getHeight() - 1);
        }
        offsetYBottom = neighbourBottom.getHeight() / 2;
        g.setColor(Color.red);
        g.drawLine(width / 2, offsetY, width / 2, height - offsetYBottom);
        if (left) {
            g.drawLine(width / 2, offsetY, width, offsetY);
            g.drawLine(width / 2, height - offsetYBottom, width, height - offsetYBottom);
            g.drawLine(0, (offsetY + height - offsetYBottom) / 2, width / 2, (offsetY + height - offsetYBottom) / 2);
        } else {
            g.drawLine(0, offsetY, width / 2, offsetY);
            g.drawLine(0, height - offsetYBottom, width / 2, height - offsetYBottom);
            g.drawLine(width / 2, (offsetY + height - offsetYBottom) / 2, width, (offsetY + height - offsetYBottom) / 2);
        }
    }
}

class Quadrat extends Form {

    private int width = 50, height = 20;

    public Quadrat() {
        this.setPreferredSize(new Dimension(width, height));
    }

    @Override
    public void paintComponent(final Graphics g) {
        super.paintComponent(g);
        height = getHeight();
        width = getWidth();
        g.drawLine(0, height / 2, width, height / 2);
        g.fillRect(width / 2 - 5, height / 2 - 5, 10, 10);
    }
}

class Kreis extends Form {

    private int width = 50, height = 20;

    public Kreis() {
        this.setPreferredSize(new Dimension(width, height));
    }

    @Override
    public void paintComponent(final Graphics g) {
        super.paintComponent(g);
        height = getHeight();
        width = getWidth();
        g.drawLine(0, height / 2, width, height / 2);
        g.fillOval(width / 2 - 5, height / 2 - 5, 10, 10);
    }
}

abstract class Form extends JPanel {

    public Form() {
    }

    public void verzweigen() {
    }
}

class Window extends JFrame {

    public Window(final Form form) {
        this.add(form);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.pack();
        this.setVisible(true);
    }
}

class Seriell extends Form {

    public Seriell(final Form f1, final Form f2) {
        this.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
        this.add(f1);
        this.add(f2);
    }
}
EDIT2: Es funktioniert aber auch mit deinem ursprünglichen FlowLayout (ich hatte deine Verschachtelungen am Anfang noch nicht so überblickt). Der Unterschied ist lediglich, dass die Grafik beim GridBagLayout zentriert bleibt, wenn man das Fenster vergrößert.
 

Anhänge

  • schema.JPG
    schema.JPG
    12,9 KB · Aufrufe: 38
Zuletzt bearbeitet:
herzlichen dank!
das funktioniert eigentlich schon ganz gut, allerdings stört mich, dass bei mehreren formen, die man paralell schaltet die höhe der entstehenden form sehr hoch wird. (verdoppelt sich mit jeder neuen form, die paralell geschalten wird).

ich denke das liegt an der eigenschaft des gridlayouts, deswegen habe ich nun das gridlayout(2,1) in ein boxlayout(Y_AXIS) verwandelt.
nun funktioniert das verzweigen nicht mehr???
 
deswegen habe ich nun das gridlayout(2,1) in ein boxlayout(Y_AXIS) verwandelt.
nun funktioniert das verzweigen nicht mehr???

Hallo lisaaa17,

versuch's mal so:
Java:
    public Paralell(final Form f1, final Form f2) {
        panelForm = new JPanel();
        BoxLayout boxLayout = new BoxLayout(panelForm, BoxLayout.Y_AXIS);
        panelForm.setLayout(boxLayout);
        panelForm.add(f1);
        panelForm.add(f2);
        this.setLayout(new GridBagLayout());
        links = new Verzweigung(left = true);
        rechts = new Verzweigung(left = false);
        GridBagConstraints constraints = new GridBagConstraints();
        constraints.gridx = 1;
        constraints.gridy = 1;
        constraints.fill = GridBagConstraints.BOTH;
        constraints.weightx = 0.0;
        constraints.weighty = 1.0;
        add(links, constraints);
        constraints.gridx = 2;
        constraints.gridy = 1;
        constraints.weightx = 1.0;
        constraints.weighty = 0.0;
        add(panelForm, constraints);
        constraints.gridx = 3;
        constraints.gridy = 1;
        constraints.weightx = 0.0;
        constraints.weighty = 1.0;
        add(rechts, constraints);
    }
Java:
class Window extends JFrame {

    public Window(final Form form) {
        //setAlwaysOnTop(true);
        setTitle("SchemaDemo");
        JPanel mainpanel = new JPanel(new GridBagLayout());
        mainpanel.add(form);
        add(mainpanel);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        pack();
        setSize(400,300);
        setLocationRelativeTo(null);
        setVisible(true);
    }
}

Gruß,
André
 
Zuletzt bearbeitet:
das funktioniert ab der 3. parallell schaltung nicht mehr:

2087859d5c.png




Java:
        Quadrat q = new Quadrat();
        Kreis k = new Kreis();
        final Paralell p1 = new Paralell(q, k);
        Quadrat q2 = new Quadrat();
        final Paralell p2 = new Paralell(p1, q2);
        Kreis k3 = new Kreis();
        final Paralell p3 = new Paralell(p2, k3);
        Quadrat q3 = new Quadrat();
        final Paralell p4 = new Paralell(p3, q3);
        verzweigen(p1, p2, p3, p4);
        Window window = new Window(p4);
 
Zuletzt bearbeitet:
das funktioniert ab der 3. parallell schaltung nicht mehr

Hallo lisaaa17,

die Berechnung von "offsetY" war noch nicht ausgereift. Versuch's mal hiermit (ich habe noch eine DEBUG Option in der Klasse "Verzweigung" eingebaut):
Java:
import java.awt.*;
import javax.swing.*;

public class SchemaDemo {

    public static void main(final String[] args) {
        Runnable gui = new Runnable() {

            @Override
            public void run() {
                Quadrat q = new Quadrat();
                Kreis k = new Kreis();
                final Paralell p1 = new Paralell(q, k, "p1");
                Quadrat q2 = new Quadrat();
                final Paralell p2 = new Paralell(p1, q2, "p2");
                Kreis k3 = new Kreis();
                final Paralell p3 = new Paralell(p2, k3, "p3");
                Quadrat q3 = new Quadrat();
                final Paralell p4 = new Paralell(p3, q3, "p4");
                verzweigen(p1, p2, p3, p4);
                Window window = new Window(p4);
                window.setAlwaysOnTop(true);
            }
        };
        SwingUtilities.invokeLater(gui);
    }

    private static void verzweigen(final Form... formen) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                for (Form form : formen) {
                    form.verzweigen();
                }
            }
        });
    }
}

class Paralell extends Form {

    private final JPanel panelForm;
    private final Verzweigung links;
    private final Verzweigung rechts;
    private boolean left;//wegen der Klarheit
    private final String name;

    public Paralell(final Form f1, final Form f2, final String name) {
        panelForm = new JPanel();
        BoxLayout boxLayout = new BoxLayout(panelForm, BoxLayout.Y_AXIS);
        panelForm.setLayout(boxLayout);
        panelForm.add(f1);
        panelForm.add(f2);
        this.setLayout(new GridBagLayout());
        links = new Verzweigung(left = true, name);
        rechts = new Verzweigung(left = false, name);
        GridBagConstraints constraints = new GridBagConstraints();
        constraints.gridx = 1;
        constraints.gridy = 1;
        constraints.fill = GridBagConstraints.BOTH;
        constraints.weightx = 0.0;
        constraints.weighty = 1.0;
        add(links, constraints);
        constraints.gridx = 2;
        constraints.gridy = 1;
        constraints.weightx = 1.0;
        constraints.weighty = 0.0;
        add(panelForm, constraints);
        constraints.gridx = 3;
        constraints.gridy = 1;
        constraints.weightx = 0.0;
        constraints.weighty = 1.0;
        add(rechts, constraints);
        this.name = name;
    }

    @Override
    public void verzweigen() {
        Dimension sizePanelForm = panelForm.getPreferredSize();
        links.setHeight(sizePanelForm.height);
        rechts.setHeight(sizePanelForm.height);
    }

    @Override
    public String toString() {
        return "Paralell{" + "name=" + name + '}';
    }
}

class Verzweigung extends JPanel {

    private boolean left;
    private int width = 20;
    private int height;
    private int offsetY;
    private int offsetYBottom;
    private Component neighbourTop;
    private Component neighbourBottom;
    private final String name;
    private boolean DEBUG = false;

    public Verzweigung(final boolean links, final String name) {
        left = links;
        this.name = name;
    }

    @Override
    public Dimension getPreferredSize() {
        Dimension preferredSize = super.getPreferredSize();
        preferredSize.height = height;
        preferredSize.width = width;
        return preferredSize;
    }

    public void setHeight(final int height) {
        this.height = height;
        revalidate();
    }

    @Override
    public void paintComponent(final Graphics g) {
        super.paintComponent(g);
        if (neighbourTop == null) {
            neighbourTop = SwingUtilities.getDeepestComponentAt(getParent(),
                    width + 1, 0);
        }
        offsetY = getOffsetY(neighbourTop, false);
        if (neighbourBottom == null) {
            neighbourBottom = SwingUtilities.getDeepestComponentAt(getParent(),
                    width + 1, getHeight() - 1);
            if (DEBUG && left) {
                offsetYBottom = getOffsetY(neighbourBottom, true);
                System.out.println(this);
            }
        }
        offsetYBottom = getOffsetY(neighbourBottom, true);
        g.setColor(Color.red);
        //vertical line:
        g.drawLine(width / 2, offsetY, width / 2, height - offsetYBottom);
        if (left) {//left horizontal lines
            //top:
            g.drawLine(width / 2, offsetY, width, offsetY);
            //bottom:
            g.drawLine(width / 2, height - offsetYBottom, width, height - offsetYBottom);
            //middle:
            g.drawLine(0, (offsetY + height - offsetYBottom) / 2, width / 2, (offsetY + height - offsetYBottom) / 2);
        } else {//right horizontal lines
            //top:
            g.drawLine(0, offsetY, width / 2, offsetY);
            //bottom:
            g.drawLine(0, height - offsetYBottom, width / 2, height - offsetYBottom);
            //middle:
            g.drawLine(width / 2, (offsetY + height - offsetYBottom) / 2, width, (offsetY + height - offsetYBottom) / 2);
        }
        if (DEBUG) {
            g.drawString(name, 0, 16);
            g.setColor(Color.BLACK);
            g.drawOval(0, 0, 1, 1);
            g.drawOval(0, height - 2, 1, 1);
        }
    }

    private int getOffsetY(final Component neighbour, final boolean bottom) {
        int offset = neighbour.getHeight() / 2;
        if (neighbour instanceof Verzweigung) {
            Verzweigung n = (Verzweigung) neighbour;
            offset = (bottom ? n.offsetYBottom : n.offsetY)
                    + (n.height - n.offsetY - n.offsetYBottom) / 2;
        }
        return offset;
    }

    @Override
    public String toString() {
        return "Verzweigung{" + "name=" + name
                + ", width=" + width + ", height=" + height
                + ", offsetY=" + offsetY
                + ", offsetYBottom=" + offsetYBottom
                + ", \n  neighbourTop=" + neighbourTop
                + ", \n  neighbourBottom=" + neighbourBottom + '}';
    }
}

class Quadrat extends Form {

    private int width = 50, height = 20;

    public Quadrat() {
        this.setPreferredSize(new Dimension(width, height));
    }

    @Override
    public void paintComponent(final Graphics g) {
        super.paintComponent(g);
        height = getHeight();
        width = getWidth();
        g.drawLine(0, height / 2, width, height / 2);
        g.fillRect(width / 2 - 5, height / 2 - 5, 10, 10);
    }

    @Override
    public String toString() {
        return "Quadrat{" + "width=" + width + ", height=" + height + '}';
    }
}

class Kreis extends Form {

    private int width = 50, height = 20;

    public Kreis() {
        this.setPreferredSize(new Dimension(width, height));
    }

    @Override
    public void paintComponent(final Graphics g) {
        super.paintComponent(g);
        height = getHeight();
        width = getWidth();
        g.drawLine(0, height / 2, width, height / 2);
        g.fillOval(width / 2 - 5, height / 2 - 5, 10, 10);
    }

    @Override
    public String toString() {
        return "Kreis{" + "width=" + width + ", height=" + height + '}';
    }
}

abstract class Form extends JPanel {

    public Form() {
    }

    public void verzweigen() {
    }
}

class Window extends JFrame {

    public Window(final Form form) {
        //setAlwaysOnTop(true);
        setTitle("SchemaDemo");
        JPanel mainpanel = new JPanel(new GridBagLayout());
        mainpanel.add(form);
        add(mainpanel);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        pack();
        setSize(400, 300);
        setLocationRelativeTo(null);
        setVisible(true);
    }
}

class Seriell extends Form {

    public Seriell(final Form f1, final Form f2) {
        this.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
        this.add(f1);
        this.add(f2);
    }
}
 
Zuletzt bearbeitet:
Hallo lisaaa17,

die Berechnung von "offsetY" war noch nicht ausgereift. Versuch's mal hiermit (ich habe noch eine DEBUG Option in der Klasse "Verzweigung" eingebaut):
Java:
import java.awt.*;
import javax.swing.*;

public class SchemaDemo {
...

super, das paralell schalten funktioniert perfekt. beim seriell schalten gibt es aber noch einen bug.
und zwar, wenn man 3 formen paralell schaltet, und eine 4. form seriell wird die 4. form in der halben Höhe, der bisherigen form gezeichnet. ich hab einfach einmal ein screen erstellt, der wird wohl aussagekräftiger sein:

1dc029dd66.png


hier noch der code:
Java:
        Quadrat q = new Quadrat();
        Kreis k = new Kreis();
        final Paralell p1 = new Paralell(q, k, "p1");
        Quadrat q2 = new Quadrat();
        final Paralell p2 = new Paralell(p1, q2, "p2");
        Kreis k3 = new Kreis();
        final Seriell p3 = new Seriell(p2, k3);
        Quadrat q3 = new Quadrat();
        final Paralell p4 = new Paralell(p3, q3, "p4");
        Quadrat q4 = new Quadrat();
        final Paralell p5 = new Paralell(p3, q3, "p4");
        Quadrat q5 = new Quadrat();
        final Paralell p6 = new Paralell(p3, q3, "p4");
        verzweigen(p1, p2, p3, p4, p5, p6);
        Window window = new Window(p6);



ps. möchte mich nocheinmal für deine mühe bedanken.
 
Hallo lisaaa17,

wir können zum Beispiel die vertikale Position mit "GridBagConstraints.insets" anpassen.

Gruß,
André


ich werde nocheinmal das Problem erörtern.

Bei bestimmten Konstellationen, (z.B. 3 Paralell geschaltene Formen werden mit 1 Form in Serie geschalten) ist der vertikale Mittelpunkt der Serienschaltung nicht gleich der Mittelpunkt der Form.
Siehe Bild
71212414.png



Meine Lösung des Problems wäre, vor dem Seriell schalten zu überprüfen, ob die Verbindungsstücke (roten mittleren Striche einer Paralellschaltung) die gleiche Y Position haben.
Es gibt also für jede Form eine Methode GetMiddlePosY(), die genau diese Y Positon zurückliefert.

Bei einer Kreis, Quadratform, wäre die Y_GetMiddlePosY() also Height/2.
Bei der Paralellschaltung ist nicht die Halbe Höhe entscheidend, sondern die Position des Mittleren horizontalen Strich der Verzweigung.
Siehe Bild
73146309.png


Diese Position ist auch bekannt, denn diese wird in der Klasse Verzweigung mit getOffsetY(neighbourBottom, true) berechnet.



Um auf die gleiche GetMiddlePosY() zu kommen, wird ein JPanel mit einer bestimmten Höhe über die 2. Form eingefügt, wodurch der Mittelpunkt künstlich verschoben wird.
siehe Bild
86866940.png


Die Höhe des eingefügten Panels errechnet sich aus:
Form1.GetMiddlePos()=Form2.GetMiddlePos()+x
x=Form1.GetMiddlePos()-Form2.GetMiddlePos();

Es wird also ein JPanel der Höhe x über Form2 gezeichnet.


Ich habe das ganze schon so weit umgesetzt, allerdings bekomme ich eine JavaNullPointer Error Meldung.

Die GetMiddlePos() einer Paralellschaltung ist:

Java:
public int GetMiddlePos()
{
    if (neighbourTop == null)
    {
      neighbourTop = SwingUtilities.getDeepestComponentAt(getParent(), width + 1, 0);
    }
    offsetY = getOffsetY(neighbourTop, false);
    if (neighbourBottom == null)
    {
      neighbourBottom = SwingUtilities.getDeepestComponentAt(getParent(), width + 1, getHeight() - 1);
    }
    offsetYBottom = getOffsetY(neighbourBottom, true);
    
    return (offsetY + height - offsetYBottom) / 2;
}

Das habe ich 1:1 von der Berechnung in der paintComponent Methode der Klasse Verzweigung übernommen.


Hier das gesamte Program:

Java:
package form2;

import java.awt.*;
import javax.swing.*;


public class Main
{
  public static void main(final String[] args)
  {
    Runnable gui = new Runnable()
    {
      @Override
      public void run()
      {
        Quadrat q = new Quadrat();
        Kreis k = new Kreis();
        final Paralell p1 = new Paralell(q, k, "p1");
        Quadrat q2 = new Quadrat();
        final Paralell p2 = new Paralell(p1, q2, "p2");
        Kreis k3 = new Kreis();
        final Seriell p3 = new Seriell(p2, k3);
        Quadrat q3 = new Quadrat();
        final Paralell p4 = new Paralell(p3, q3, "p4");
        Quadrat q4 = new Quadrat();
        final Paralell p5 = new Paralell(p3, q3, "p4");
        Quadrat q5 = new Quadrat();
        final Paralell p6 = new Paralell(p3, q3, "p4");
        verzweigen(p1, p2, p4, p5, p6);
        Window window = new Window(p6);
        window.setAlwaysOnTop(true);
      }
    };
    SwingUtilities.invokeLater(gui);
  }


  private static void verzweigen(final Form... formen)
  {
    SwingUtilities.invokeLater(new Runnable()
    {
      @Override
      public void run()
      {
        for (Form form : formen)
        {
          form.verzweigen();
        }
      }
    });
  }
}


class Paralell extends Form
{
  private final JPanel panelForm;
  private final Verzweigung links;
  private final Verzweigung rechts;
  private boolean left;//wegen der Klarheit
  private final String name;


  public Paralell(final Form f1, final Form f2, final String name)
  {
    panelForm = new JPanel();
    BoxLayout boxLayout = new BoxLayout(panelForm, BoxLayout.Y_AXIS);
    panelForm.setLayout(boxLayout);
    panelForm.add(f1);
    panelForm.add(f2);
    this.setLayout(new GridBagLayout());
    links = new Verzweigung(left = true, name);
    rechts = new Verzweigung(left = false, name);
    GridBagConstraints constraints = new GridBagConstraints();
    constraints.gridx = 1;
    constraints.gridy = 1;
    constraints.fill = GridBagConstraints.BOTH;
    constraints.weightx = 0.0;
    constraints.weighty = 1.0;
    add(links, constraints);
    constraints.gridx = 2;
    constraints.gridy = 1;
    constraints.weightx = 1.0;
    constraints.weighty = 0.0;
    add(panelForm, constraints);
    constraints.gridx = 3;
    constraints.gridy = 1;
    constraints.weightx = 0.0;
    constraints.weighty = 1.0;
    add(rechts, constraints);
    this.name = name;
  }


  @Override
  public void verzweigen()
  {
    Dimension sizePanelForm = panelForm.getPreferredSize();
    links.setHeight(sizePanelForm.height);
    rechts.setHeight(sizePanelForm.height);
  }


  @Override
  public String toString()
  {
    return "Paralell{" + "name=" + name + '}';
  }


  public int getMiddlePosY()
  {
    return links.getMiddlePosY();
  }
}


class Verzweigung extends JPanel
{
  private boolean left;
  private int width = 20;
  private int height;
  private int offsetY;
  private int offsetYBottom;
  private Component neighbourTop;
  private Component neighbourBottom;
  private final String name;
  private boolean DEBUG = true;


  public Verzweigung(final boolean links, final String name)
  {
    left = links;
    this.name = name;
  }


  @Override
  public Dimension getPreferredSize()
  {
    Dimension preferredSize = super.getPreferredSize();
    preferredSize.height = height;
    preferredSize.width = width;
    return preferredSize;
  }


  public void setHeight(final int height)
  {
    this.height = height;
    revalidate();
  }


  @Override
  public void paintComponent(final Graphics g)
  {
    super.paintComponent(g);
    if (neighbourTop == null)
    {
      neighbourTop = SwingUtilities.getDeepestComponentAt(getParent(),
                                                          width + 1, 0);
    }
    offsetY = getOffsetY(neighbourTop, false);
    if (neighbourBottom == null)
    {
      neighbourBottom = SwingUtilities.getDeepestComponentAt(getParent(),
                                                             width + 1, getHeight() - 1);
      if (DEBUG && left)
      {
        offsetYBottom = getOffsetY(neighbourBottom, true);
        System.out.println(this);
      }
    }
    offsetYBottom = getOffsetY(neighbourBottom, true);
    g.setColor(Color.red);
    //vertical line:
    g.drawLine(width / 2, offsetY, width / 2, height - offsetYBottom);
    if (left)
    {//left horizontal lines
      //top:
      g.drawLine(width / 2, offsetY, width, offsetY);
      //bottom:
      g.drawLine(width / 2, height - offsetYBottom, width, height - offsetYBottom);
      //middle:
      g.drawLine(0, (offsetY + height - offsetYBottom) / 2, width / 2, (offsetY + height - offsetYBottom) / 2);
    }
    else
    {//right horizontal lines
      //top:
      g.drawLine(0, offsetY, width / 2, offsetY);
      //bottom:
      g.drawLine(0, height - offsetYBottom, width / 2, height - offsetYBottom);
      //middle:
      g.drawLine(width / 2, (offsetY + height - offsetYBottom) / 2, width, (offsetY + height - offsetYBottom) / 2);
    }
    if (DEBUG)
    {
      g.setColor(Color.BLACK);
      g.drawString(name, 0, 16);
      g.drawOval(0, 0, 1, 1);
      g.drawOval(0, height - 2, 1, 1);
    }
  }


  private int getOffsetY(final Component neighbour, final boolean bottom)
  {
    int offset = neighbour.getHeight() / 2;
    if (neighbour instanceof Verzweigung)
    {
      Verzweigung n = (Verzweigung) neighbour;
      offset = (bottom ? n.offsetYBottom : n.offsetY)
               + (n.height - n.offsetY - n.offsetYBottom) / 2;
    }
    return offset;
  }

  public int getMiddlePosY()
  {
    if (neighbourTop == null)
    {
      neighbourTop = SwingUtilities.getDeepestComponentAt(getParent(), width + 1, 0);
    }
    offsetY = getOffsetY(neighbourTop, false);
    if (neighbourBottom == null)
    {
      neighbourBottom = SwingUtilities.getDeepestComponentAt(getParent(), width + 1, getHeight() - 1);
    }
    offsetYBottom = getOffsetY(neighbourBottom, true);
    return (offsetY + height - offsetYBottom) / 2;
  }


  @Override
  public String toString()
  {
    return "Verzweigung{" + "name=" + name
           + ", width=" + width + ", height=" + height
           + ", offsetY=" + offsetY
           + ", offsetYBottom=" + offsetYBottom
           + ", \n  neighbourTop=" + neighbourTop
           + ", \n  neighbourBottom=" + neighbourBottom + '}';
  }
}


class Quadrat extends Form
{
  private int width = 50, height = 20;


  public Quadrat()
  {
    this.setPreferredSize(new Dimension(width, height));
  }


  @Override
  public void paintComponent(final Graphics g)
  {
    super.paintComponent(g);
    height = getHeight();
    width = getWidth();
    g.drawLine(0, height / 2, width, height / 2);
    g.fillRect(width / 2 - 5, height / 2 - 5, 10, 10);
  }


  @Override
  public String toString()
  {
    return "Quadrat{" + "width=" + width + ", height=" + height + '}';
  }

  public int getMiddlePosY()
  {
    return height / 2;
  }
}


class Kreis extends Form
{
  private int width = 50, height = 20;


  public Kreis()
  {
    this.setPreferredSize(new Dimension(width, height));
  }


  @Override
  public void paintComponent(final Graphics g)
  {
    super.paintComponent(g);
    height = getHeight();
    width = getWidth();
    g.drawLine(0, height / 2, width, height / 2);
    g.fillOval(width / 2 - 5, height / 2 - 5, 10, 10);
  }


  @Override
  public String toString()
  {
    return "Kreis{" + "width=" + width + ", height=" + height + '}';
  }


  public int getMiddlePosY()
  {
    return height / 2;
  }
}


abstract class Form extends JPanel
{
  public Form()
  {
  }


  public void verzweigen()
  {
  }

  abstract public int getMiddlePosY();
}


class Window extends JFrame
{
  public Window(final Form form)
  {
    //setAlwaysOnTop(true);
    setTitle("SchemaDemo");
    JPanel mainpanel = new JPanel(new GridBagLayout());
    mainpanel.add(form);
    add(mainpanel);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    pack();
    setSize(400, 300);
    setLocationRelativeTo(null);
    setVisible(true);
  }
}


class Seriell extends Form
{
  Form f1, f2;
  int MiddlePosY;

  public Seriell(final Form f1, final Form f2)
  {
    this.f1=f1;
    this.f2=f2;
    
    int Diff=0;
    JPanel panelDiff=new JPanel();
    if(f1.getMiddlePosY()!=f2.getMiddlePosY())
    {
      Diff=f1.getMiddlePosY()-f2.getMiddlePosY();
    }

    panelDiff.setPreferredSize(new Dimension(f1.getPreferredSize().width+f2.getPreferredSize().width, Diff));
    JPanel panelAdapted=new JPanel();  // neues Größen-angepasstes Panel
    panelAdapted.setLayout(new BoxLayout(panelAdapted, BoxLayout.Y_AXIS));
    panelAdapted.add(panelDiff);

    this.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));

    if(Diff<0)
    {
      panelAdapted.add(f2);
      this.add(f1);
      this.add(panelAdapted);

      MiddlePosY=f2.getPreferredSize().height/2+Diff;
    }
    else
    {
      panelAdapted.add(f1);
      this.add(panelAdapted);
      this.add(f2);

      MiddlePosY=f1.getPreferredSize().height/2+Diff;
    }

  }


  public int getMiddlePosY()
  {
    return MiddlePosY;
  }
}
 

Zurück
Oben