paintComponent zeigt nix an

Y

yachty66

Mitglied
Ich habe ein JPanel erstellt in dem ich jetzt verschiedene Operationen durchführen möchte, allerdings wird mir der weiße Hintergrund mit dem Label "N/A" nicht angezeigt, sondern nur der Bereich von dem JPanel. Wie bekomme ich es hin, dass ich den Hintergrund mit Label angezeigt bekomme? In dem folgenden Code geht er auf jeden Fall in die Schleife rein (bei if (componentList.isEmpty())), allerdings passiert dann nix.

Java:
@Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        List<Component> componentList = Arrays.asList(borderPanel.getComponents());
        if (componentList.isEmpty()) {
            JLabel jlabel = new JLabel("N/A");
            borderPanel.add(jlabel);
            borderPanel.setBackground(Color.white);
        } else if(componentList.isEmpty() == false && !componentList.contains(getImage())){
            borderPanel.setBackground(Color.white);
            g.setColor(Color.BLUE);
            g.drawRect((Integer) getConCoo.get(1), (Integer) getConCoo.get(2), (Integer) (getConCoo.get(3))- (Integer) (getConCoo.get(1)), (Integer)(getConCoo.get(4))-(Integer)(getConCoo.get(2)));

        }
    }
 
kneitzel

kneitzel

Top Contributor
Da fallen mir gleich mehrere Dinge zu ein, die ich da gerne erwähnen möchte:

a) Die Elemente der Komponente werden in der Methode paintComponent der Super-Klasse gemalt. Der Aufruf kommt als erstes, daher sind natürlich keinerlei Änderungen, die danach kommen, berücksichtigt.

b) Aufbau: Was ist borderPanel? Ist das ein Child des eigentlichen Panels? Oder ist das irgend etwas, das eigentlich unabhängig ist? Wenn letzteres, dann sind Änderungen an dieser Komponente natürlich auch komplett unabhängig vom painComponent.

c) Clean Code: Hör auf Dich selbst zu verarschen (Sorry, für die krassen Worte - nicht pers. nehmen)! Eine Methode macht genau das, was ihr Name aussagt und nichts Anderes. paintComponent malt also die Komponente. Sonst macht diese Methode absolut NICHTS! Das mag natürlich technisch gehen, aber du entwickelst Code, der mit nur etwas mehr Komplexität bestimmt nicht wartbar wird und die Chance extrem hoch ist, dass er eben nicht das macht, was man von ihm erwartet.
Da kommen dann auch sofort Dinge hinzu, die wichtig sind: Trennung von Zuständigkeiten!
- Das borderPanel soll ja auf eine bestimmte Art und Weise angezeigt werden. Das ist also Code, der nicht zu Deinem Panel gehört sondern eher zu borderPanel!
- Du hast eine Logik, die in Abhängigkeit zu den Childs von dem borderPanel da etwas macht. => Das ist also Code, der laufen muss, wenn die Children des borderPanel sich verändern. Das hat nichts mit dem paintComponent zu tun!

Also um es kurz zusammen zu fassen, was ich da machen würde:
- borderPanel wird eine Klasse, die bei Änderung der Children ggf. das n/a Label hinzufügt und den Hintergrund anpasst.
- paintComponent enthält also nur ein spezielles malen des Rechtecks wenn borderPanel einen bestimmten Status hat. Das wäre aber ggf. auch über eine Child Komponente erreichbar. (borderPanel könnte also Events haben, wenn es leer oder eben nicht leer gemacht wird. Und das trigert dann ein setVisible der neu hinzugefügten Komponente.)
 
N

Neumi5694

Top Contributor
Ich vermute mal, dass borderPanel die Komponente ist, die gerade gezeichnet werden soll.
Während der Zeichenmethode ein Label hinzuzufügen kann nur daneben gehen.

Wenn du Text anzeigen willst, dann mach das mit g.drawString(...);
Um Grafiken anzuzeigen, nutzt du g.drawImage(...)
Wozu hast du denn das Graphics-Objekt sonst...

Falls du ein Label nutzen willst, um die Grafik anzuzeigen, dann fügst du das VORHER hinzu und überschreibst drawComponent NICHT.
 
kneitzel

kneitzel

Top Contributor
Ich vermute mal, dass borderPanel die Komponente ist, die gerade gezeichnet werden soll.
Ich war da halt etwas irritiert. "this" ist die Komponente, die gerade gezeichnet wird. borderPanel muss also eine Instanzvariable sein. Aber ob das Element dort auch in children ist, das ist halt der Punkt, den wir nicht wissen. Abhängig davon wird es mitgezeichnet oder eben nicht.

Aber der Ansatz, da ggf. ohne Label direkt mit drawString zu arbeiten ist auch gut. Damit könnte man den paintComponent Ansatz weiter verfolgen.
 

Ähnliche Java Themen


Oben