# Mehrere Linien zeichnen



## Karu (17. Okt 2017)

Ich versuche mehrere Linien in einem Panel zeichnen zu lassen. Das zeichnen an sich funktioniert auch, mein Problem ist nur, dass die Linien immer nebeneinander dargestellt werden, obwohl sie sich in einem normalen Koordinatensystem überschneiden würden (so will ich es haben).
Ein Beispiel:
Ich habe versucht diese Linien zeichnen zu lassen:
Linie1: P1(1/1)   P2(4/9)
Linie2: P1(1/3)   P2(16/5)
Linie3: P1(2/9)   P2(15/2)
das sollte dann etwa so aussehen:

aber es sieht so aus:


Ich habe 4 Listen zur Speicherung der Koordinaten (werden durch User eingegeben) 

```
static ArrayList<Float> wertex1= new ArrayList<>();
        static ArrayList<Float> wertey1= new ArrayList<>();
        static ArrayList<Float> wertex2= new ArrayList<>();
        static ArrayList<Float> wertey2= new ArrayList<>();
```

Auf Button-Klick sollen dann alle Linien gezeichnet werden

```
public void actionPerformed (ActionEvent ae){
        if(ae.getSource() == b2){
            for(int i = 0; i < wertex1.size(); i++) {
                int x1 = Math.round(wertex1.get(i));
                int y1 = Math.round(wertey1.get(i));
                int x2 = Math.round(wertex2.get(i));
                int y2 = Math.round(wertey2.get(i));
           
                linie = new MyPanel(x1, y1, x2, y2);
                panel3.add(linie, BorderLayout.CENTER);
                revalidate();
                repaint();
            } 
           
        }
```


```
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;

import javax.swing.JPanel;

public class MyPanel extends JPanel{
   
    int x1, y1, x2, y2;

    public MyPanel(int x1, int y1, int x2, int y2){
       
        this.x1 = x1;
        this.x2 = x2;
        this.y1 = y1;
        this.y2 = y2;
    }
    public void paint(Graphics gr){
        super.paintComponents(gr);
        Graphics2D g = (Graphics2D)gr;
        g.setColor(Color.BLACK);
        g.drawLine(x1, y1, x2, y2);
    }

}
```

Hat jemand vielleicht eine Idee, wie ich es schaffe, dass sie Linien auch übereinander dargestellt werden?
Danke schon mal im voraus.


----------



## JCODA (17. Okt 2017)

Vermutlich liegen die Panels nebeneinander.
Benutze ein einzelnes Panel, welches eine Liste aller Linien beinhaltet und alle Linien per for-Schleife zeichnet.


----------



## Karu (17. Okt 2017)

Ok, klingt logisch. Und wie mache ich das am besten? :x


----------



## JCODA (18. Okt 2017)

```
// Irgendwo vorher:
MyPanel linePanel = new MyPanel();
panel3.add(linePanel, BorderLayout.CENTER);

public void actionPerformed (ActionEvent ae){
        if(ae.getSource() == b2){
            for(int i = 0; i < wertex1.size(); i++) {
                int x1 = Math.round(wertex1.get(i));
                int y1 = Math.round(wertey1.get(i));
                int x2 = Math.round(wertex2.get(i));
                int y2 = Math.round(wertey2.get(i));
        
                linePanel.addLine(new Line(x1,y1,x2,y2));
                revalidate();
                repaint();
            }
        
        }
```


```
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;

import javax.swing.JPanel;

public class MyPanel extends JPanel{
 
    private List<Line> lines = new ArrrayList<Line>();

    public MyPanel(){    
    }
    public void addLine(Line l){
          lines.add(l);
    }

    public void paintComponent(Graphics gr){
        super.paintComponent(gr);
        Graphics2D g = (Graphics2D)gr;
        g.setColor(Color.BLACK);
        for(Line line : lines){
             g.drawLine(line.getX1(),line.getY1(),line.getX2(),line.getY2());
        }
    }

}
```


```
class Line{
     private int x1,y1,x2,y2;
     public Line(int x1,int y1, int x2, int y2){
         this.x1 = x1;
         this.y1 = y1;
         this.x2 = x2;
         this.y2 = y2;
     }
//alle Getter für die Attribute.

}
```

Benutze am besten keine statischen Listen, das sieht ziemlich unschön aus...


----------



## Karu (18. Okt 2017)

Irgendwie hilft mir das nicht weiter... da kommen nur tausend Fehlermeldungen, wenn ich versuche das in meinen Code zu übernehmen


----------



## JCODA (18. Okt 2017)

Ja, ich hab's gerade ohne IDE gemacht, d.h. da fehlen wohl noch die Importe. 
Wenn du den kompletten Code postest, dann kann ich das einfach in meine IDE kopiere und es richtig eingliedern.


----------



## Karu (19. Okt 2017)

```
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.WindowConstants;

public class view extends JFrame implements ActionListener{
   
        JButton b1 = new JButton();
        JButton b2 = new JButton();
        ArrayList<Float> wertex1= new ArrayList<>();
        ArrayList<Float> wertey1= new ArrayList<>();
        ArrayList<Float> wertex2= new ArrayList<>();
        ArrayList<Float> wertey2= new ArrayList<>();
        ImageIcon icon = new ImageIcon ("C:\\Users\\Maus\\Documents\\A3Listen\\src\\achtung.png");
        JLabel feld = new JLabel(icon);
        JTextField tf1 = new JTextField();
        JTextField tf2 = new JTextField();
        JTextField tf3 = new JTextField();
        JTextField tf4 = new JTextField();
        JTextField tf5 = new JTextField();
        int zahl = 0;
        int dreiecke = 0;
        float maxXWert = 0;
        float maxYWert = 0;
        int faktorX = 1;
        int faktorY = 1;
        JPanel panel3 = new JPanel();
        MyPanel linie;

    public view() {
        super("Aufgabe 3");
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setSize(550, 621);
        setLocationRelativeTo(null);
        setVisible(true);
        setLayout(null);
       
        JPanel panel1 = new JPanel();
        JPanel panel2 = new JPanel();
       
        b1.addActionListener(this);
        b2.addActionListener(this);

        this.add(panel1);
        this.add(panel2);
        this.add(panel3, BorderLayout.CENTER);

        panel1.setSize(550, 42);
        panel1.setBackground(Color.RED);
        panel2.setBackground(Color.PINK);
        panel2.setBounds(0, 42, 550, 29);
        panel3.setBackground(Color.WHITE);
        panel3.setBounds(0, 71, 550, 550);
        panel1.setLayout(null);
        panel2.setLayout(null);
        panel3.setLayout(new GridLayout(1, 1));
       
        panel1.add(feld);
        panel1.add(tf1);
        panel1.add(tf2);
        panel1.add(tf3);
        panel1.add(tf4);
        panel2.add(tf5);
        panel1.add(b1);
        panel1.add(b2);
       
        feld.setBounds(25, 5, 25, 32);
        tf1.setBounds(55, 11, 50, 20);
        tf1.setText("x1");
        tf2.setBounds(110, 11, 50, 20);
        tf2.setText("y1");
        tf3.setBounds(165, 11, 50, 20);
        tf3.setText("x2");
        tf4.setBounds(220, 11, 50, 20);
        tf4.setText("y2");
        b1.setBounds(280, 11, 100, 20);
        b1.setText("hinzufügen");
        b2.setBounds(390, 11, 100, 20);
        b2.setText("fertig");
        tf1.setHorizontalAlignment(SwingConstants.CENTER);
        tf2.setHorizontalAlignment(SwingConstants.CENTER);
        tf3.setHorizontalAlignment(SwingConstants.CENTER);
        tf4.setHorizontalAlignment(SwingConstants.CENTER);
        tf5.setBounds(0, 0, 550, 29);
        tf5.setHorizontalAlignment(SwingConstants.CENTER);
       
        tf5.setText("Anzahl:");
        tf5.setEditable(false);
        feld.setVisible(false);
    }
    //-------------------------------------------------------------------------------------------------------//

    public void actionPerformed (ActionEvent ae){
        if(ae.getSource() == b1){
            //Überprüfen ob Inhalt Textfelder in umwandelbar sind -> wenn ja: Werte in Listen aufnehmen
            if(!(isNumeric(tf1.getText())==false) && !(isNumeric(tf2.getText())==false) && !(isNumeric(tf3.getText())==false) && !(isNumeric(tf4.getText())==false)) {
                feld.setVisible(false);
                float a,b,c,d;
                a = Float.parseFloat(tf1.getText());
                wertex1.add((float)a);
                b = Float.parseFloat(tf2.getText());
                wertey1.add((float)b);
                c = Float.parseFloat(tf3.getText());
                wertex2.add((float)c);
                d = Float.parseFloat(tf4.getText());
                wertey2.add((float)d);
                tf1.setText("");
                tf2.setText("");
                tf3.setText("");
                tf4.setText("");
                zahl= zahl +1;
                tf5.setText("Anzahl:" + zahl);
            }
            //wenn nicht umwandelbar: lasse ein Ausrufezeichen neben den Eingabefeldern erscheinen
            else {
                feld.setVisible(true);
            }
            }
        if(ae.getSource() == b2){
            //Auswertung
            tf1.setEditable(false);
            tf2.setEditable(false);
            tf3.setEditable(false);
            tf4.setEditable(false);
            b1.setEnabled(false);
           
            dreieckeZaehlen(wertex1, wertey1, wertex2, wertey2);
            if(dreiecke==0) {tf5.setText("Es konnten keine Dreiecke gefunden werden.");}
            else {tf5.setText("Anzahl Dreiecke:" + (dreiecke/6));}
           
            //Anpassen der Zeichenfläche an Werte -> Möglichst große Ansicht
            maxWerteErmitteln(wertex1, wertey1, wertex2, wertey2);
           
            //zeichne alle Linien
            for(int i = 0; i < wertex1.size(); i++) {
                int x1 = Math.round(wertex1.get(i));
                int y1 = Math.round(wertey1.get(i));
                int x2 = Math.round(wertex2.get(i));
                int y2 = Math.round(wertey2.get(i));
           
                linie = new MyPanel(x1, 510-y1, x2*faktorX, 510-y2*faktorY);
                panel3.add(linie);
                revalidate();
                repaint();
            } 
           
        }
    }
   
    public static boolean isNumeric(String value) {
        try {
            float number = Float.parseFloat(value);
            return true;
        }
        catch(NumberFormatException e) {
            return false;
        }
    }

    public void dreieckeZaehlen(ArrayList<Float> wertex1, ArrayList<Float> wertey1, ArrayList<Float> wertex2, ArrayList<Float> wertey2) {
        for(int i = 0; i < wertex1.size(); i++) {
            for(int j = 0; j < wertex1.size(); j++) {
                if(!(j==i)) {
                    if(schneidenSich((wertex1.get(i)),(wertey1.get(i)),(wertex2.get(i)),(wertey2.get(i)),(wertex1.get(j)),(wertey1.get(j)),(wertex2.get(j)),(wertey2.get(j)))==true) {
                        for(int k = 0; k < wertex1.size(); k++) {
                            if(!(k==j) && !(k==i)) {
                                if(schneidenSich((wertex1.get(j)),(wertey1.get(j)),(wertex2.get(j)),(wertey2.get(j)),(wertex1.get(k)),(wertey1.get(k)),(wertex2.get(k)),(wertey2.get(k)))==true && schneidenSich((wertex1.get(k)),(wertey1.get(k)),(wertex2.get(k)),(wertey2.get(k)),(wertex1.get(i)),(wertey1.get(i)),(wertex2.get(i)),(wertey2.get(i)))==true) {
                                    dreiecke = dreiecke + 1;
                                }
                            }
                           
                        }
                    }
                }
               
            }
        }
    }
   
    public boolean schneidenSich(float a,float b,float c,float d, float e, float f, float g, float h) {
        float x;
        float m1, m2, n1, n2;
        m1=((d-b)/(c-a));
        m2=((h-f)/(g-e));
        n1=d-m1*c;
        n2=f-m2*e;
        x=-1*((n1-n2)/(m1-m2));
        if(x>=a && x>=e && x<=c && x<=g) {
            return true;
        }
        else {return false;}
       
    }

    public void maxWerteErmitteln(ArrayList<Float> wertex1, ArrayList<Float> wertey1, ArrayList<Float> wertex2, ArrayList<Float> wertey2) {
        for(int i = 0; i < (wertex1.size()); i++) {
            if(wertex1.get(i)>maxXWert) {maxXWert=wertex1.get(i);}
        }
        for(int i = 0; i < (wertex1.size()); i++) {
            if(wertex2.get(i)>maxXWert) {maxXWert=wertex2.get(i);}
        }
        for(int i = 0; i < (wertex1.size()); i++) {
            if(wertey1.get(i)>maxYWert) {maxYWert=wertey1.get(i);}
        }
        for(int i = 0; i < (wertex1.size()); i++) {
            if(wertey2.get(i)>maxYWert) {maxYWert=wertey2.get(i);}
        }
       
        if(maxXWert>=0 && maxXWert<=50) {faktorX=10;}
            if(maxXWert>50 && maxXWert<=100) {faktorX=5;}
            if(maxXWert>100 && maxXWert<=180) {faktorX=3;}
            if(maxXWert>180 && maxXWert<=270) {faktorX=2;}
            if(maxYWert>=0 && maxYWert<=50) {faktorY=10;}
            if(maxYWert>50 && maxYWert<=100) {faktorY=5;}
            if(maxYWert>100 && maxYWert<=180) {faktorY=3;}
            if(maxYWert>180 && maxYWert<=270) {faktorY=2;}
    }
}
```

Das ist alles und der Code vom MyPanel steht ja ganz oben schon.


----------



## JCODA (19. Okt 2017)

Ich hab einiges geändert, so ganz zufrieden bin ich zwar immer noch nicht, allerdings hab' ich jetzt auch nicht mehr allzuviel Lust noch mehr dran zu ändern... 


Spoiler: MyPanel.java





```
package lines;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JPanel;

public class MyPanel extends JPanel {

    private final List<Line> lines = new ArrayList<Line>();

   
    float maxXWert = 0;
    float maxYWert = 0;
    int faktorX = 1;
    int faktorY = 1;
   
   
    public MyPanel() {
    }

    public void addLine(Line l) {
        lines.add(l);
        maxWerteErmitteln(l);
        repaint();
    }

   
   
   
    public void paintComponent(Graphics gr) {
        super.paintComponent(gr);
        Graphics2D g = (Graphics2D) gr;
        g.setColor(Color.BLACK);
        for (Line line : lines) {
            g.drawLine(line.getX1()*faktorX, 510-line.getY1()*faktorY, line.getX2()*faktorX, 510-line.getY2()*faktorY);
        }
    }
   
   
    public void maxWerteErmitteln(Line l) {

       
        maxXWert = Math.max(maxXWert, l.getX1());
        maxXWert = Math.max(maxXWert, l.getX2());

        maxYWert = Math.max(maxYWert, l.getY1());
        maxYWert = Math.max(maxYWert, l.getY2());
       
        if (maxXWert >= 0 && maxXWert <= 50) {
            faktorX = 10;
        }
        if (maxXWert > 50 && maxXWert <= 100) {
            faktorX = 5;
        }
        if (maxXWert > 100 && maxXWert <= 180) {
            faktorX = 3;
        }
        if (maxXWert > 180 && maxXWert <= 270) {
            faktorX = 2;
        }
        if (maxYWert >= 0 && maxYWert <= 50) {
            faktorY = 10;
        }
        if (maxYWert > 50 && maxYWert <= 100) {
            faktorY = 5;
        }
        if (maxYWert > 100 && maxYWert <= 180) {
            faktorY = 3;
        }
        if (maxYWert > 180 && maxYWert <= 270) {
            faktorY = 2;
        }
        System.out.print(faktorX  + " " + faktorY);
    }

    public List<Line> getLines() {
        return lines;
    }
   
   

}
```







Spoiler: View.java





```
package lines;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.WindowConstants;

public class View extends JFrame {

    private JButton b1 = new JButton();
    private JButton b2 = new JButton();
    private MyPanel linePanel = new MyPanel();
    private JLabel feld = new JLabel(new ImageIcon("C:\\Users\\Maus\\Documents\\A3Listen\\src\\achtung.png"));
    private JTextField tf[] = new JTextField[4];
    private JLabel label = new JLabel();   
   

    public View() {
        super("Aufgabe 3");
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setSize(550, 621);
        setLocationRelativeTo(null);
        setVisible(true);
        setLayout(null);

        JPanel panel1 = new JPanel();
        JPanel panel2 = new JPanel();

        b1.addActionListener(ae -> clickAdd(ae));
        b2.addActionListener(ae -> clickCalc(ae));

        this.add(panel1);
        this.add(panel2);
        this.add(linePanel, BorderLayout.CENTER);

        panel1.setSize(550, 42);
        panel1.setBackground(Color.RED);
        panel2.setBackground(Color.PINK);
        panel2.setBounds(0, 42, 550, 29);
        linePanel.setBackground(Color.WHITE);
        linePanel.setBounds(0, 71, 550, 550);
        panel1.setLayout(null);
        panel2.setLayout(null);
        linePanel.setLayout(new GridLayout(1, 1));

        panel1.add(feld);

        String tf_content[] = { "x1", "y1", "x2", "y2" };

        for (int i = 0; i < tf.length; i++) {
            tf[i] = new JTextField(tf_content[i]);
            tf[i].setBounds(55 * (i + 1), 11, 50, 20);
            tf[i].setHorizontalAlignment(SwingConstants.CENTER);
            panel1.add(tf[i]);
        }

        panel2.add(label);
        panel1.add(b1);
        panel1.add(b2);

        feld.setBounds(25, 5, 25, 32);
        b1.setBounds(280, 11, 100, 20);
        b1.setText("hinzufügen");
        b2.setBounds(390, 11, 100, 20);
        b2.setText("fertig");
        label.setBounds(0, 0, 550, 29);
        label.setHorizontalAlignment(SwingConstants.CENTER);

        label.setText("Anzahl:");
        feld.setVisible(false);
    }
    // -------------------------------------------------------------------------------------------------------//

    private void clickCalc(ActionEvent ae) {
        for (JTextField jtf : tf) {
            jtf.setEditable(false);
        }
        b1.setEnabled(false);

        int dreiecke = dreieckeZaehlen();
        if (dreiecke == 0) {
            label.setText("Es konnten keine Dreiecke gefunden werden.");
        } else {
            label.setText("Anzahl Dreiecke:" + (dreiecke / 6));
        }

    }

    private void clickAdd(ActionEvent ae) {

        try {
            feld.setVisible(false);
            float a = Float.parseFloat(tf[0].getText());
            float b = Float.parseFloat(tf[1].getText());
            float c = Float.parseFloat(tf[2].getText());
            float d = Float.parseFloat(tf[3].getText());
            linePanel.addLine(new Line(a, b, c, d));
            for (JTextField jtf : tf) {
                jtf.setText("");
            }

            label.setText("Anzahl:" + linePanel.getLines().size());
           
        } catch (NumberFormatException e) {
            feld.setVisible(true);
        }
        repaint();

    }

    public int dreieckeZaehlen() {

        int dreiecke = 0;
        for (Line line1 : linePanel.getLines()) {
            for (Line line2 : linePanel.getLines()) {
                if (line1.equals(line2)) {
                    continue;
                }
                if (line1.schneidenSich(line2)) {
                    for (Line line3 : linePanel.getLines()) {
                        if (line1.equals(line3) || line2.equals(line3)) {
                            continue;
                        }
                        if (line2.schneidenSich(line3) && line1.schneidenSich(line3)) {
                            dreiecke++;
                        }
                    }
                }
            }
        }

        return dreiecke;
    }

   
}
```






Spoiler: Line.java





```
package lines;

public class Line {
    private int x1, y1, x2, y2;

    public Line(int x1, int y1, int x2, int y2) {
        this.x1 = x1;
        this.y1 = y1;
        this.x2 = x2;
        this.y2 = y2;
    }

    public Line(float a, float b, float c, float d) {
        this(Math.round(a),Math.round(b),Math.round(c),Math.round(d));
    }

    public int getX1() {
        return x1;
    }

    public int getY1() {
        return y1;
    }

    public int getX2() {
        return x2;
    }

    public int getY2() {
        return y2;
    }

    public boolean schneidenSich(Line other) {
        float a=x1,b=y1,c=x2,d=y2;
        float e=other.x1,f=other.y1,g=other.x2,h=other.y2;
        float m1 = ((d - b) / (c - a));
        float m2 = ((h - f) / (g - e));
        float n1 = d - m1 * c;
        float n2 = f - m2 * e;
        float x = -1 * ((n1 - n2) / (m1 - m2));
        return x >= a && x >= e && x <= c && x <= g;

    }
   
   
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + x1;
        result = prime * result + x2;
        result = prime * result + y1;
        result = prime * result + y2;
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Line other = (Line) obj;
        if (x1 != other.x1)
            return false;
        if (x2 != other.x2)
            return false;
        if (y1 != other.y1)
            return false;
        if (y2 != other.y2)
            return false;
        return true;
    }

}
```







Spoiler: RunApp.java





```
package lines;

public class RunApp {

    public static void main(String[] args) {
        new View().setVisible(true);

    }

}
```


----------



## Karu (19. Okt 2017)

Solange es funktioniert  bin ich glücklich 
Ich danke dir schon mal, werde es morgen testen.


----------

