2017-05-15 5 views
0

Ich übe, um eine Form auf einem JPanel zu zeichnen, indem ich auf einen Jbutton klicke, aber ich kann nicht. Es ist fünf Stunden her, dass ich im Internet surfe, aber ich finde den Weg nicht. Das möchte ich tun: wenn ich auf "Rechteck" klicke, erscheint unter den Schaltflächen ein Rechteck und wenn ich auf "Kreis" klicke, erscheint ein Kreis. Wie zeichne ich eine Form in JPanel mit ActionListener?

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

    class Shape extends JFrame { 
     JButton rec, circle; 
     static String botSelected; 
     Shape(){ 
      frameSet(); 
     } 

     void frameSet(){ 
      JFrame frame = new JFrame(); 
      frame.setVisible(true); 
      frame.setSize(600,300); 
      rec = new JButton ("Rectangle"); 
      circle = new JButton("Circle"); 
      JPanel panel = new JPanel(); 
      frame.add(panel); 
      panel.add(rec); 
      panel.add(circle); 
      Click clk = new Click(); 
      rec.addActionListener(clk); 
      circle.addActionListener(clk); 
     } 

     public void paint (Graphics g){ 
      super.paint(g); 
      if (botSelected.equals("Rectangle")) 
       g.fillRect(50,50,50,50); 
      else if (botSelected.equals("Circle")) 
       g.fillOval(50,50,50,50); 
     } 

     public static void main (String [] arg){ 
      Shape s = new Shape(); 
     } 
    } 

    class Click implements ActionListener{ 
     public void actionPerformed (ActionEvent e){ 
      Shape.botSelected = e.getActionCommand(); 
     } 
    } 
+0

Sie müssen Repaint aufrufen, damit die Änderungen angezeigt werden. Dieser Code ist mit so vielen schlechten Praktiken übersät. Warum erweitern Sie JFrame? Sie sollten Ihre Klasse 'Shape' nicht nennen, da es sich um eine Klasse in AWT handelt, dh' java.awt.Shape' – matt

+0

. Das erste, was ich tun würde, ist eine Lektüre von [Painting in Swing] (http: // www. oracle.com/technetwork/java/painting-140037.html) und [Ausführen von benutzerdefinierten Bildern] (https://docs.oracle.com/javase/tutorial/uiswing/painting/), um besser zu verstehen, wie der Malprozess funktioniert. Als allgemeine Empfehlung würde ich "statisch" vermeiden, es ist keine Lösung für die Kommunikation zwischen Objekten – MadProgrammer

Antwort

1

Das erste, was ich tun würde, ist eine Lese durch Painting in Swing haben und Performing custom painting besser zu verstehen, wie die Malerei Prozess funktioniert.

Als nächstes müssen Sie verstehen, dass JFrame eine schlechte Wahl für die Malerei ist. Warum? Weil es vielschichtig ist.

RootPane

A JFrame enthält eine JRootPane, die eine JLayeredPane die contentPane, glassPane und die JMenuBar und in Ihrem Beispiel enthält, ist es auch ein JPanel enthält.

Mit der Ausnahme (Ausnahme) glassPane sind alle diese Komponenten opak.

Während es möglich ist, etwas in der paint Methode gezogen haben zeigen ihnen, wenn eine der anderen Komponenten selbst zu malen, es wird sauber gewischt werden - das liegt daran, dass Swing-Komponenten tatsächlich unabhängig voneinander lackiert werden, mit zu müssen Lassen Sie die Eltern zuerst malen.

Eine bessere Lösung besteht darin, mit der Erweiterung von JPanel zu beginnen und die paintComponent Methode zu überschreiben.

Der Einfachheit halber würde ich auch Sie ermutigen, die ActionListener gegen diese Klasse zu implementieren als auch, wird es das actionPerformed Verfahren ermöglichen die Eigenschaften der Komponente zuzugreifen und in Ihrem Fall, rufen repaint einen Farbzyklus auszulösen, wenn Sie möchten die Benutzeroberfläche aktualisieren.

+0

Danke. Ich wusste nichts von diesem GlasPane. Ich sollte mehr darüber lesen. –

1

Hier ist ein abgeleitetes Beispiel aus Ihrem Code.

Wie @MadProgrammer sagte, nicht erweitern JFrame.

Im folgenden Beispiel sind hier die wichtigsten Änderungen:

  • einen Nicht-Null-Wert zu botSelected geben, oder die ersten Anrufe paintComponent geben Ihnen einen NullPointerException

  • die Klasse jetzt erweitert JPanel, und überschreibt paintComponent für benutzerdefinierte Malerei

  • die ActionListener ist eine anonyme Klasse, sein Ursache Sie nicht über eine eigene Klasse benötigen und es direkten Zugriff auf die Felder von Shape

  • botSelected ist nicht mehr statisch (siehe oben Punkt)

hat.

import java.awt.Graphics; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 

class Shape extends JPanel { 
    JButton rec, circle; 
    String botSelected = "";// don't let it be null, it would make paintComponent crash on startup 

    Shape() { 
     frameSet(); 
    } 

    void frameSet() { 
     JFrame frame = new JFrame(); 
     frame.setVisible(true); 
     frame.setSize(600, 300); 
     rec = new JButton("Rectangle"); 
     circle = new JButton("Circle"); 

     frame.add(this); 
     this.add(rec); 
     this.add(circle); 
     // anonymous class, has access to fields from the outer class Shape 
     ActionListener clk = new ActionListener() { 
      public void actionPerformed(final ActionEvent e) { 
       botSelected = e.getActionCommand(); 
       repaint(); 
      } 

     }; 
     rec.addActionListener(clk); 
     circle.addActionListener(clk); 
    } 

    //custom painting of the JPanel 
    @Override 
    public void paintComponent(final Graphics g) { 

     super.paintComponent(g); 
     if (botSelected.equals("Rectangle")) { 
      g.fillRect(50, 50, 50, 50); 
     } else if (botSelected.equals("Circle")) { 
      g.fillOval(50, 50, 50, 50); 
     } 
    } 

    public static void main(final String[] arg) { 
     Shape s = new Shape(); 
    } 

} 
+0

Vielen Dank. Ich habe viel gelernt. –

+0

Ich weiß immer noch nicht, warum die Erweiterung des JFrames nicht funktioniert hat, aber Jpanel funktioniert. und wie das "this" funktioniert, um die Buttons hinzuzufügen. Und warum letzte String in der Hauptmethode? Wo kann ich mehr darüber lesen? TNX –

+0

Ein 'JFrame' hat seinen eigenen Inhalt' JPanel', der Versuch, die 'Farbe' aus dem' JFrame' zu ​​überschreiben, wird nichts nützliches tun. Da Ihre Klasse selbst ein 'JPanel' ist, bedeutet' this' die 'Form'' JPanel'selbst, also kannst du Dinge einfach mit 'this.add ...' hinzufügen. – Berger

Verwandte Themen