# Java Swing Rechteck in JPanel zeichnen



## fiber (7. Dez 2015)

Hallo,

Ich möchte ein GUI für elevator model zeichnen. Für Schaft möchte ich hinter die Türe einen Rechteck zeichnen. wie kann ich das Recheck in Panel zeichnen, sodass das hinter der ImageIcon zu sehen ist?


```
package elevatorgui;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class ElevatorGui extends JFrame {
    private static final long serialVersionUID = 1L;

   
     public static void main(String[] args) {
        new ElevatorGui();  
    }
   
    public ElevatorGui(){
        JFrame frame = new JFrame("Elevator");
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(360, 700);

        // change path for Door icon...
        JLabel label_door = new JLabel(new ImageIcon("path"));
        JPanel panel = new JPanel(null);
       
        frame.add(panel); 
        panel.add(label_door);
        label_door.setLocation(30,440);
        label_door.setSize(300, 300);
       
       
       
        //Outside Button up and down
        JButton buttonUp = new JButton("Up");
        panel.add(buttonUp);
        buttonUp.setLocation(280, 550);
        buttonUp.setSize(50, 20);
        buttonUp.addActionListener(new Action());
       
        JButton buttonDown = new JButton("Down");
        panel.add(buttonDown);
        buttonDown.setLocation(280, 575);
        buttonDown.setSize(50, 20);
        buttonDown.addActionListener(new Action());
       
       
        // Floor Button 1-4
        JButton button_Floor_1 = new JButton("1");
        panel.add(button_Floor_1);
        button_Floor_1.setLocation(50, 500);
        button_Floor_1.setSize(20, 20);
        button_Floor_1.addActionListener(new Action());
       
        JButton button_Floor_2 = new JButton("2");
        panel.add(button_Floor_2);
        button_Floor_2.setLocation(50, 530);
        button_Floor_2.setSize(20, 20);
        button_Floor_2.addActionListener(new Action());
       
        JButton button_Floor_3 = new JButton("3");
        panel.add(button_Floor_3);
        button_Floor_3.setLocation(50, 560);
        button_Floor_3.setSize(20, 20);
        button_Floor_3.addActionListener(new Action());
       
        JButton button_Floor_4 = new JButton("4");
        panel.add(button_Floor_4);
        button_Floor_4.setLocation(50, 590);
        button_Floor_4.setSize(20, 20);
        button_Floor_4.addActionListener(new Action());

    }

    static class Action implements ActionListener{

        @Override
        public void actionPerformed(ActionEvent e) {
       
        }
       
    }
   
    public class MyDrawPanel extends JPanel{ 
       
    @Override
    public void paint (Graphics g){
    g.setColor (Color.BLACK);
    g.drawRect (5, 5, 10, 10); // sind spontane Zahlen..
    //g.fillRect (5, 5, 10, 10);
  }
}

}
```


----------



## fiber (7. Dez 2015)

Hallo nochmal ,
ch habe die klasse ein wenig verändert und habe die Klasse die fürs zeichnen verantwortlich ist, als eine separate klasse erstellt, aber jetzt wird das Rechteck nicht mal angezeigt.. habe auch bei der drawRec() Methode mit validate() versucht klappt auch nicht..
neue Struktur der Klasse:


```
package elevatorgui;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class ElevatorGui extends JFrame {
    private static final long serialVersionUID = 1L;

  
     public static void main(String[] args) {
        new ElevatorGui(); 
    }
  
    public ElevatorGui(){
        JFrame frame = new JFrame("Elevator");
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(360, 700);

      
  

        // change path for Door icon...
        JLabel label_door = new JLabel(new ImageIcon("path"));
        JPanel panel = new JPanel(null);
      
      
        frame.add(panel);
        panel.add(label_door);
        label_door.setLocation(30,440);
        label_door.setSize(300, 300);
      
        MyDrawPanel drawPanel = new MyDrawPanel();
        drawPanel.drawRec();
        frame.add(drawPanel);
              
      
        //Outside Button up and down
        JButton buttonUp = new JButton("Up");
        panel.add(buttonUp);
        buttonUp.setLocation(280, 550);
        buttonUp.setSize(50, 20);
        buttonUp.addActionListener(new Action());
      
        JButton buttonDown = new JButton("Down");
        panel.add(buttonDown);
        buttonDown.setLocation(280, 575);
        buttonDown.setSize(50, 20);
        buttonDown.addActionListener(new Action());
      
      
        // Floor Button 1-4
        JButton button_Floor_1 = new JButton("1");
        panel.add(button_Floor_1);
        button_Floor_1.setLocation(50, 500);
        button_Floor_1.setSize(20, 20);
        button_Floor_1.addActionListener(new Action());
      
        JButton button_Floor_2 = new JButton("2");
        panel.add(button_Floor_2);
        button_Floor_2.setLocation(50, 530);
        button_Floor_2.setSize(20, 20);
        button_Floor_2.addActionListener(new Action());
      
        JButton button_Floor_3 = new JButton("3");
        panel.add(button_Floor_3);
        button_Floor_3.setLocation(50, 560);
        button_Floor_3.setSize(20, 20);
        button_Floor_3.addActionListener(new Action());
      
        JButton button_Floor_4 = new JButton("4");
        panel.add(button_Floor_4);
        button_Floor_4.setLocation(50, 590);
        button_Floor_4.setSize(20, 20);
        button_Floor_4.addActionListener(new Action());

    }

    static class Action implements ActionListener{

        @Override
        public void actionPerformed(ActionEvent e) {
      
        }
      
    }

}
```




```
package elevatorgui;

import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;

    public class MyDrawPanel extends JPanel{
      
    @Override
    public void paint (Graphics g){
        super.paintComponent(g);
        g.setColor(Color.BLACK);
        g.fillRect(10, 10, 100, 100); // zufällige zahlen, weil ich zuerst überprüfen möchte ob die Zeichnung erst sichtbar wird oder nicht..
      
  }
        public void drawRec(){
            repaint();
          
        }
}
```


----------



## Harry Kane (7. Dez 2015)

Deine ElevatorGui aus dem letzten Post ist ein JFrame, wird aber gar nicht als solcher benutzt. Das ist unsauber, überfflüssig und sollte geändert werden.
Der Aufruf 


fiber hat gesagt.:


> frame.setVisible(true);
> frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
> frame.setSize(360, 700);


gehört ans Ende der Methode: erst werden Komponenten zu einem COntainer hinzugefügt, dann wird das ganze sichtbar gemacht.
Deine drawRec-Methode ist überflüssig. Da kannst du direkt die ebenfalls public repaint Methode direkt aufrufen.
Weiterhin überschreibt man bei JComponents, in denen etwas spezielles gezeichnet werden soll, statt paint(Graphics g) die paintComponent(Graphics g) Methode.
Ausserdem verwendet ein JFrame (bzw. dessen ContentPane, auch wenn es oben so aussieht, als könnte man einem JFrame direkt Komponenten hinzufügen, findet das eigentlich hinzufügen auf der ContentPane statt) meines Wissens nach ein BorderLayout, d. h. du solltest nur die zuletzt eingefügte Komponente sehen, und das wiederum sollte dein MyDrawPanel sein. Ich vermute mal, dass du entgegen deiner Fehlerbeschreibung 


fiber hat gesagt.:


> jetzt wird das Rechteck nicht mal angezeigt


eigentlich sagen wolltest, dass gar nichts angezeigt wird, auch keine JButtons.
Zu guter Letzt: null Layouts sollte man vermeiden. Schau dir mal das Thema Layoutmanager an. Ich kann das MigLayout empfehlen. Kostet zwar etwas Einarbeitung, aber das war zumindest in meinem Fall sehr gut investierte Zeit.


----------



## fiber (7. Dez 2015)

Allesklar, Danke! Ich schau mir das gerne an! Dazu lernen ist immer gut  ich weiss auch nicht, wie ich mir das vorgestellt hatte,  JFrame in JPanel anzuzeigen..
Die drew Methode habe ich durch ein Image ersetzt, fiel mir persönlich leichter.
Hab das jetzt gelöst, ob es so sauber programmiert ist, da bin ich mir nicht so sicher, aber das Ergebnis sieht wie erwartet aus 


```
package elevatorgui;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class ElevatorGui extends JFrame {
    private static final long serialVersionUID = 1L;


     public static void main(String[] args) {
        new ElevatorGui();
    }

    public ElevatorGui(){
        JFrame frame = new JFrame("Elevator");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(460, 900);

   


        // change path for the images...
        JLabel label_door = new JLabel(new ImageIcon("path"));
        JLabel label_frame = new JLabel(new ImageIcon("path"));

        JPanel panel = new JPanel(null);
        frame.add(panel);
   
        panel.add(label_frame);
        label_frame.setBounds(10, 10, 399, 890);
   
        panel.add(label_door);
        label_door.setLocation(30,630);
        label_door.setSize(300, 300);
           
   
        //Outside Button up and down
        JButton buttonUp = new JButton("Up");
        panel.add(buttonUp);
        buttonUp.setLocation(320, 750);
        buttonUp.setSize(50, 20);
        buttonUp.addActionListener(new Action());
   
        JButton buttonDown = new JButton("Down");
        panel.add(buttonDown);
        buttonDown.setLocation(320, 775);
        buttonDown.setSize(50, 20);
        buttonDown.addActionListener(new Action());
   
   
        // Floor Button 1-4
        JButton button_Floor_1 = new JButton("1");
        panel.add(button_Floor_1);
        button_Floor_1.setLocation(320, 600);
        button_Floor_1.setSize(20, 20);
        button_Floor_1.addActionListener(new Action());
   
        JButton button_Floor_2 = new JButton("2");
        panel.add(button_Floor_2);
        button_Floor_2.setLocation(320, 630);
        button_Floor_2.setSize(20, 20);
        button_Floor_2.addActionListener(new Action());
   
        JButton button_Floor_3 = new JButton("3");
        panel.add(button_Floor_3);
        button_Floor_3.setLocation(320, 660);
        button_Floor_3.setSize(20, 20);
        button_Floor_3.addActionListener(new Action());
   
        JButton button_Floor_4 = new JButton("4");
        panel.add(button_Floor_4);
        button_Floor_4.setLocation(320, 690);
        button_Floor_4.setSize(20, 20);
        button_Floor_4.addActionListener(new Action());
   
        frame.setVisible(true);

    }

    static class Action implements ActionListener{

        @Override
        public void actionPerformed(ActionEvent e) {
   
        }
   
    }

}
```


----------



## fiber (8. Dez 2015)

Hallo nochmal,

habe das ähnliche Problem.. oder das gleiche?
Elevator model hat ganz gut geklappt. Nun muss ich Sensoren zeichne. ich hatte mir vorgestellt kreise mit JConponent zu zeichnen, weil die nach einer bestimmten Action rot leuchten müssen.
ich habe keine Ahnung wie ich den Kreis auf meiner GuI anzeigen lassen kann bzw. wie kann kann ich den Kreis in meinem JPanel zeichnen, ohne das meine elevator model verschwindet?


```
/*
This GUi class draws the ElevatorModel 
*/

package elevatorgui;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;


public class ElevatorGui extends JFrame {
    private static final long serialVersionUID = 1L;

   
     public static void main(String[] args) {
        new ElevatorGui();  
    }
   
    public ElevatorGui(){
        JFrame frame = new JFrame("Elevator");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(460, 860);

       
        // IMPORTANT: change path for the images...
        JLabel label_door = new JLabel(new ImageIcon("path"));
        JLabel label_frame = new JLabel(new ImageIcon("path"));
         
        JPanel panel = new JPanel(null);
        frame.add(panel); 
       
        panel.add(label_frame);
        label_frame.setLocation(-120, -800);
        label_frame.setSize(1010, 1800);
       
        panel.add(label_door);
        label_door.setLocation(23,600);
        label_door.setSize(300, 300);
               
       
        //Outside Button up and down
        JButton buttonUp = new JButton("Up");
        panel.add(buttonUp);
        buttonUp.setLocation(380, 750);
        buttonUp.setSize(50, 20);
        buttonUp.addActionListener(new Action());
       
        JButton buttonDown = new JButton("Down");
        panel.add(buttonDown);
        buttonDown.setLocation(380, 775);
        buttonDown.setSize(50, 20);
        buttonDown.addActionListener(new Action());
       
       
        // Floor Button 1-4
        JButton button_Floor_1 = new JButton("1");
        panel.add(button_Floor_1);
        button_Floor_1.setLocation(380, 600);
        button_Floor_1.setSize(20, 20);
        button_Floor_1.addActionListener(new Action());
       
        JButton button_Floor_2 = new JButton("2");
        panel.add(button_Floor_2);
        button_Floor_2.setLocation(410, 600);
        button_Floor_2.setSize(20, 20);
        button_Floor_2.addActionListener(new Action());
       
        JButton button_Floor_3 = new JButton("3");
        panel.add(button_Floor_3);
        button_Floor_3.setLocation(380, 630);
        button_Floor_3.setSize(20, 20);
        button_Floor_3.addActionListener(new Action());
       
        JButton button_Floor_4 = new JButton("4");
        panel.add(button_Floor_4);
        button_Floor_4.setLocation(410, 630);
        button_Floor_4.setSize(20, 20);
        button_Floor_4.addActionListener(new Action());
       
       
        // Alarm Button
        JButton button_Alarm = new JButton("Alarm");
        panel.add(button_Alarm);
        button_Alarm.setLocation(380, 690);
        button_Alarm.setSize(50, 20);
        button_Alarm.setForeground(Color.red);
        button_Alarm.addActionListener(new Action());
       
       
    Draw01Panel drawPanel = new Draw01Panel(); 
        frame.getContentPane().add(drawPanel);

        frame.setVisible(true);

    }
   
    /**
     * Circle
     */
    class Draw01Panel extends JPanel{
    public Draw01Panel(){
    repaint();
    }
        public void paintComponent(Graphics g){
    //Override
    super.paintComponent(g);
   
    //Draw filled circle
    g.setColor(Color.GRAY);
        g.fillArc(10, 10, 20, 20, 500, 500);

        }
    }
   
    /**
     * Starts an action if button pressed
     */
    static class Action implements ActionListener{

        @Override
        public void actionPerformed(ActionEvent e) {
       
        }
       
    }

}
```


----------



## Harry Kane (9. Dez 2015)

Harry Kane hat gesagt.:


> Deine ElevatorGui aus dem letzten Post ist ein JFrame, wird aber gar nicht als solcher benutzt. Das ist unsauber, überfflüssig und sollte geändert werden.


Zu deiner letzten Frage:
Beschäftige dich mal mit Layouts in Java. Wie oben gesagt, hat ein JFrame per default ein BorderLayout. Wenn mit add Komponenten hinzugefügt werden, werden diese in BorderLayout.CENTER platziert und ersetzen eine eventuell dort schon vorhandene Komponente.
Wenn du was komplizierteres zeichnen möchtest, würde ich die ganze Zeichenlogik in die paintComponent() Methode einer einzelnen JComponent packen. Aktuell verwendest du für den "Schaft" (du meinst doch wohl "Schacht", oder) und für die Sensoren unterschiedliche JPanels. Wenn später noch Türen dazukommen sollen, die sich eventuell sogar animiert öffnen und schliessen sollen, wird das ganze sehr kompliziert, wenn du alles in separate JComponents packst.
Den Konstruktor von Draw01Panel kannst du dir sparen. Ein expliziter Aufruf von repaint ist nur nötig, wenn sich die Gui, nachdem sie einmal fertiggestellt und sichtbar gemacht wurde, nochmal ändert.


----------



## fiber (9. Dez 2015)

Genau Schacht sollte es heißen, Sorry!
Bin seit 2 Tagen da dran aber verstehe irgendwie denn Sinn dahinter nicht. Habe mir sämtliche codes angeschaut und Tutorials ebenfalls.Die Klassen getrennt zu verwenden wäre kein Problem. Ich weiss das ich JFrame nicht in JPanel anzeigen lassen kann, also in meinem Fall. Aber ich weiss nicht, was ich alternativ machen kann. Die JComponent Methode kann ich nicht in JPanel aufrufen, richtig? Wenn ich die Kreise als Icon adden würde, könnte ICH die Farben nicht ändern. Ich bräuchte bitte einen Ansatz!

Ne so kompliziert soll es nicht werden. 
Mein GUI hat nur folgende Komponente: 
-Schacht
-Tür was nur hoch und runter fahren soll. 
-Sensoren die bei bestimmten Button druck leuchten sollen
Die Sensoren bestehen aus 6 kreise. Benutze hier JComponent, weil die jeweiligen kreise nach dem Button Druck rot beleuchtet werden müssen. Die Kreise werden über die Tür vorne auf dem Schacht platziert. ( was ich nicht hinbekommen habe..)


----------



## Harry Kane (9. Dez 2015)

fiber hat gesagt.:


> Ich weiss das ich JFrame nicht in JPanel anzeigen lassen kann


Davon ist ja auch gar nicht die Rede. Was für einen Sinn hat diese Aussage?


fiber hat gesagt.:


> Die JComponent Methode kann ich nicht in JPanel aufrufen, richtig?


Was soll dieser Satz bedeuten? JComponent ist keine Methode, sondern eine Klasse, und du kannst natürlich einem JPanel JComponents hinzufügen.


fiber hat gesagt.:


> Wenn ich die Kreise als Icon adden würde, könnte ICH die Farben nicht ändern.


Du kannst Icons nicht "adden", zumindest nicht einem JPanel. Aber du könntest dir eine Icon-Klasse selber schreiben, die einen Kreis in einer wählbaren Farbe zeichnet, dieses Icon einem JLabel verpassen, und das JLabel einem JPanel adden.


----------

