2016-04-02 14 views
0

Ich bin neu in Java und habe erst angefangen, GUI-Komponenten zu lernen. So las ich Headfirst Java und es gibt diesen Code, der paintcomponent Methode von JPanel erklärt. Es ist nur die Farbe des Ovals zu ändern, wenn der Benutzer auf die Schaltfläche "Farben ändern" klickt. -repaint() -Methode in JFrame oder Jpanel?

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

public class SimpleGui3C implements ActionListener { 

    JFrame frame; 

    public static void main(String[] args) { 
     SimpleGui3C gui = new SimpleGui3C(); 
     gui.go(); 
    } 

    public void go() { 
     frame = new JFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     JButton button = new JButton("Change colors"); 
     button.addActionListener(this); 

     MyDrawPanel drawPanel = new MyDrawPanel(); 

     frame.getContentPane().add(BorderLayout.SOUTH, button); 
     frame.getContentPane().add(BorderLayout.CENTER, drawPanel); 
     frame.setSize(500,500); 
     frame.setVisible(true); 
    } 

    public void actionPerformed(ActionEvent event) { 
     frame.repaint(); 
    } 
} 

MyDrawPanel Klasse -

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

class MyDrawPanel extends JPanel { 

    public void paintComponent(Graphics g) { 

     Graphics2D g2d = (Graphics2D) g; 

//  GradientPaint gradient = new GradientPaint(70,70,Color.blue,150,150,Color.orange); 

     int red = (int) (Math.random() * 255); 
     int green = (int) (Math.random() * 255); 
     int blue = (int) (Math.random() * 255); 
     Color startColor = new Color(red, green, blue); 

     red = (int) (Math.random() * 255); 
     green = (int) (Math.random() * 255); 
     blue = (int) (Math.random() * 255); 
     Color endColor = new Color(red, green, blue); 

     GradientPaint gradient = new GradientPaint(70,70,startColor,150,150,endColor); 

     g2d.setPaint(gradient); 
     g2d.fillOval(70,70,100,100); 
    } 
} 

Ich habe alles aus diesem Beispiel mit Ausnahme des Teils, wo wir repaint() Methode aufrufen.

In dem Buch wurde erwähnt, dass nur die paintcomponent Methode von JPanel außer Kraft setzen und wenn Sie repaint() nennen, wird es paintcomponent den Inhalt zu machen nennen (da sie nicht direkt paintcomponent nennen).

Jetzt habe ich MyDrawPanel Klasse erstellt, indem Sie JPanel erweitern und seine paintComponent Methode überschreiben. Wenn wir jetzt drawPanel Widget auf Frame und dann auf Mausklick setzen, wird repint() Methode aufgerufen. Aber diese repaint() Methode wird mit frame - ein Objekt von JFrame aufgerufen. Laut meinem grundlegenden Java-Verständnis muss diese Methode, wenn ich eine Methode unter Verwendung eines Objekts aufrufe, in dieser Klasse oder in irgendeiner Super-Klasse sein. Ich sehe nicht, wie das Rufen repaint() auf frame Farbkomponente von MyDrawPanel auslösen wird. Ich habe einige graben, um zu sehen, ob JFrame und JPanel Aktien die gleiche Hierarchie und hier ist das, was ich gefunden habe:

object -> component (hat Methode neu streichen) -> container (hat paintcomponent-Methode) ->

 `jcomponent` --> `jpanel` 

     `window` --> `frame` --> `jframe` 

So dachte ich, dass beide seit JFrame und JPanelpaintComponent und repaint Methoden bekommen, kann ich Jframe erweitern können MyDrawPanel zu schaffen statt Jpanel und es sollte gut funktionieren. Aber das tut es nicht. Es kompiliert fein, aber Laufzeitausnahme.

Es ist wirklich frustrierend. Vielleicht bekomme ich keine GUI-Konzepte oder meine Grundlagen sind immer noch schwach. Bitte lassen Sie mich wissen, wenn ich hier etwas wirklich Dummes verpasse.

+1

Können Sie die Ausnahme Sie hinzufügen bekommen? – APerson

Antwort

2

der mit paintComponent Beginnen wir wirklich super.paintComponent Vor dem Beginn der Custom Painting

Dann fahren Sie auf Sie sollten wirklich Painting in AWT and Swing und Performing Custom Painting für ein besseres Verständnis davon, wie Malerarbeiten in Swing lesen nennen sollte. repaint ruft nicht paintComponent direkt an, es fordert die RepaintManager an, ein paint Ereignis in der Ereigniswarteschlange zu planen, die zu einem bestimmten Zeitpunkt in der Zukunft von dem Event Dispatching Thread verarbeitet wird, das das paint Ereignis basierend auf den Anforderungen von verarbeitet der Behälter

So dachte ich, dass beide seit JFrame und JComponent bekommen paintcomponent

Nein, tun sie nicht.JFrame (und es ist Klasse Eltern) nicht über eine paintComponent Methode

sein kann, kann ich JFrame verlängern MyDrawPanel statt JPanel zu erstellen und es sollte

No fine“arbeiten, sollten Sie nicht, Abgesehen von JFrame keine paintComponent, gibt es viel mehr los, die mit jeder benutzerdefinierten Malerei stören könnte versuchen und auf einer JFrame durchführen und Sie sollten weiterhin Ihren Code so strukturieren, wie es ist

+0

Die Es sollte nicht einmal kompiliert werden, wenn JFrame keine Farbkomponente hat. Es kompiliert gut, aber während der Laufzeit - C: \ javahome> java SimpleGui3C Exception in thread "main" java.lang.IllegalArgumentException: ein Fenster zu einem Behälter bei java.awt.Container.checkNotAWindow (Container hinzugefügt wird. Java: 490) bei java.awt.Container.addImpl (Container.java:1091) bei java.awt.Container.add (Container.java:438) bei SimpleGui3C.go (SimpleGui3C.java:24) bei SimpleGui3C.main (SimpleGui3C.java:11) –

+0

Ich kann alles loslassen. Aber wie man Repaint auf Frame aufruft, ruft paintcomponent von MyDrawPanel auf. Dieses Ding nervt mich. –

+0

@EolElement Fügen Sie der 'paintComponent'-Methode in Ihrem' JFrame' '@ Override' hinzu, dann wird es nicht kompiliert. Wenn Sie in der Klasse "paintComponent" eine Methode erstellen, haben Sie gerade eine Methode erstellt. Ihr Fehler liegt darin, dass Sie versuchen, ein Fenster zu einem anderen Fenster hinzuzufügen, was eine unzulässige Operation ist. – MadProgrammer

Verwandte Themen