Neuzeichnen eines JPanels

ub007

Mitglied
Hallo !

Ich bin kurz vor dem verzweifeln. Ich arbeite sehr gern mit NetBeans und versuche jetzt über einen jButton1 eine Grafik zu zeichnen. Macht er auch. Er zeichnet zwei schwarze Linien( v. File test4view.java ). Über den zweiten Button soll er repainten ( falls das überhaupt Sinn macht). Ich hab dazu die Klasse MyDraw im Internet gefunden.
Wenn ich die zwei Linien v. test4view.java weglasse - kommt auf dem Panel gar nichts. Es geht ja eigentl. nur darum dass wenn das Fenster geschlossen wird bzw. wieder geöffnet wird, dass der Inhalt nicht verlorengeht. Was mache ich falsch ? Ach ja, die Punkte heißen - ich hab den Source-Code v. NetBeans mal zur besseren Übersicht weggelassen.

Gruß Uli

Java:
// File: MyDraw.java
package test4;

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

public class MyDraw extends JPanel
{
   @Override
   public void paintComponent(Graphics g1)
   {
      Color C;

      C = new Color(0, 0 , 0);
      super.paintComponent(g1);
      g1.setColor(C); // setze Farbe
      g1.drawLine(0, 0, 40, 20);
      g1.drawLine(0, 20, 40, 20);
   }
}
------------------------------------------------------------------------
Java:
//File: test4view.java
package test4;

import java.awt.Graphics;
import org.jdesktop.application.Action;
import org.jdesktop.application.ResourceMap;
import org.jdesktop.application.SingleFrameApplication;
import org.jdesktop.application.FrameView;
import org.jdesktop.application.TaskMonitor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;
import javax.swing.Icon;
import javax.swing.JDialog;
import javax.swing.JFrame;

public class Test4View extends FrameView 
{

   public Graphics g;
   public int MyInit=0;
   .
   .
   .

    private void jButton1MouseClicked(java.awt.event.MouseEvent evt) 
    {
       if ( MyInit == 0 )
       {
          g = jPanel1.getGraphics();
          MyInit = 1;
          jPanel1 = new MyDraw();
       }

       g.drawLine( 0,  0, 20, 20);
       g.drawLine(10, 20, 30, 20);
       jPanel1.repaint();
    }

    private void jButton2MouseClicked(java.awt.event.MouseEvent evt) 
    {
       jPanel1.repaint();
    }

    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel mainPanel;
    private javax.swing.JMenuBar menuBar;
    private javax.swing.JProgressBar progressBar;
    private javax.swing.JLabel statusAnimationLabel;
    private javax.swing.JLabel statusMessageLabel;
    private javax.swing.JPanel statusPanel;

    private final Timer messageTimer;
    private final Timer busyIconTimer;
    private final Icon idleIcon;
    private final Icon[] busyIcons = new Icon[15];
    private int busyIconIndex = 0;

    private JDialog aboutBox;
}
 
Was meinst du mit Fenster schließen? Wenn beim Schließen des Fensters Programm beendet wird dann verschwinden natürlich die Linien. Du kanns zB dein Panel mit Hilfe von FileOutputStream und ObjectOutputStream in einer Datei speichern und dann beim Start dein Panel aus dieser Datei mit Hilfe von FileInputStream und ObjectInputStream laden.
 
Auf Komponenten niemals getGraphics() aufrufen (vgl. Test4View Zeile 30) sondern nur das Graphic Objekt innerhalb der paintComponent(...) abgreifen (vgl. MyDraw)
Selbst wenn Du mit getGraphics() erfolg hast ist nach einem repaint() das gezeichnete wieder weg, denn das was gezeichnet werden soll musst Du irgendewie speichern - die Komponente selbst merkt sich nicht was eine Millissekunde zur auf ihr gezeichnet wurde.

Verbesserungvorschlag zu MyDraw:
Das Color Objekt (Zeile 13 bis 15) ausserhalb der paintComp... erzeugen, in Deinem Code wird bei jedem Neuzeichnen unnötig ein neues Objekt erzeugt. Ist in dem Fall nicht so wild, aber besser man gewöhnt sich sowas nicht an.
 
Hallo !

Erstmal Danke für die Antworten.

@Dit_ : Sorry war Fehler von mir. Ich dachte es wird klar wenn ich das Fenster mit zumachen meine, nicht das Programm ! Also um genau zu sein meinte ich Fenster-minimieren.

@Michael: Ups, das mit den Color war ein klarer Fehler von mir. Deshalb habe ich die Variable My_init drin wo das verhindern soll. Jetzt habe ich das Color-setzen in test4view eingebaut und funktioniert.

Aber alles andere ist für mich jetzt nicht mehr nachvollziehbar, zumal ich hier im Forum gelesen habe, das die Methode getGraphics() aufzurufen immer ein Fehler ist. Ich nehme an das ist ein awt-gedöns.... Aber wie soll ich denn in Swing dann die "Grafik" initialisieren ? Gut vielleicht sagt man ich soll mir ein Buch kaufen und das genau nachlesen. Hab ich ja gemacht als ich mit Java angefangen habe - mit dem Resultat das in diesem Buch nur awt-Komponenten besprochen werden. Swing wird mit einer Seite erwähnt und die Komponenten in einem Einzeiler kurz angesprochen.
1. Vielleicht kann man mir sagen was ich anstelle von getGraphics() verwenden sollte.
Bitte jetzt nicht sagen es geht nur über getGraphics() !
2. Warum derjenige das über die MyDraw-Klasse ( hab ich ja aus dem Internet) gemacht hat, ist mir eher schleierhaft. O.K. jeder programmiert anders. Das hätte man doch auch irgendwie im test4view unterkriegen können.
3. Ich weis ja nicht ob die paintComponent-Methode richtig ist für das Neuzeichnen. Ich hab gelesen da gibt es doch die repaint-Methode, also müßte ich die doch überschreiben, oder ? Ich gehe davon aus das die repaint-Methode von irgendwas ( Java oder Betriebssystem) aufgerufen wird, sobald das Fenster sich verändert oder minimiert/maximiert wird. Vielleicht habe ich aber auch da was falsch verstanden.

Gruß Uli
 
in der paintComponentMethode hast du ein Graphics-Object und genau das sollst du zum zeichnen benutzen kein getGraphics() und ganz sicher nicht repaint() überschreiben. Und wenn du es erst nachnem button klick zeichnen willst hilft ein boolean aus:
Java:
@Override
public void paintComponent(Graphics g) {
  super.paintComponent(g);
  if(buttonWasClicked){
     g.drawLine(0,0,50,50);
  }
}
buttonWasClicked wird halt dann durch den button auf true gesetzt
 
Hallo !

O.K. schon beim einfügen nach der Mouseklicked-Methode
meint der Compiler ob er eine Methode names paintComponent einfügen soll ? Die hab ich aber doch
schon in MyDraw stehen.

Also der Aufruf paintComponent(g); funktioniert nicht.

Oben in test4view ist Graphics wie folgt definiert:

public Graphics g;

Gruß Uli
 
man übreschreibt paintComponent aber ruft repaint auf (das kümmert sich dann um das Graphics Object so dass du nirgendswo ein Graphics Object brauchst)
 
Hi !

In test4view will ich in der Mouseclicked-Methode repaint(); reinschreiben, aber der Compiler fragt ob er jetzt eine Methode repaint in test4view erzeugen soll.

Gruß Uli
 
ub007 hat gesagt.:
Java:
private void jButton2MouseClicked(java.awt.event.MouseEvent evt) 
    {
       jPanel1.repaint();
    }
in deinem ersten post hast dus doch noch benutzt... prinzipiel war da nur falsch das du getGraphics() benutzt hast und nicht in der paintComponent-Methode gemalt hast wodurch das ganze beim repaint() futsch war (da wird nunmal die paintComponent-Methode aufgerufen wenn da nix steht wird auch nur der standart-hintergrund gemalt egal was du vorher mit getGraphics rumgespielt hast)
 
Hallo !

O.K. Das ganze funktioniert aber immer noch nicht. Jetzt habe ich aber wahrscheinlich etwas gefunden warum das nicht geht:

Im Internet kann man folgenden Code finden:
Java:
import java.awt.Graphics; // Graphics
import javax.swing.*; // JPanel
import java.awt.*; // Color
public class paintDemo extends JPanel 
{
   protected void paintComponent( Graphics g ) 
   {
      super.paintComponent( g );
      g.setColor(Color.red);
      g.fillOval(5,5,300,200);
   }
   public static void main( String args[] ) 
   {
      JFrame f = new JFrame();
      f.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
      f.setSize ( 315, 240);
      f.getContentPane().add( new paintDemo() );
      f.setVisible( true );
   }
}

Mit diesem Code funktioniert auch meine Klasse.
Man sieht das ein neues JFrame eröffnet wird. Jetzt dachte ich das geht auch mit einem JInternalFrame, denn ich möchte auf keinen Fall ein weiteres Fenster öffnen.
Kurz umprogrammiert - und siehe da - es geht nicht. Das ganze jetzt auf JPanel ausprobiert mit den gleichen Resultat.
Ich vermute dass das gar nicht auf einen mit NetBeans-programmierten JPanel oder ähnliches geht !
Probier es einfach mal aus.

Gruß Uli
 
ich hab dir mal ein Bsp:
Java:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
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;
 
public class JFSize {
 
    private static Color color = Color.GREEN;
    
    private static final int SIZE = 200;
 
    public static void main(String[] args) {
        JFrame frame = new JFrame("Foo");
        frame.setPreferredSize(new Dimension(SIZE, SIZE));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        JPanel panel = new JPanel();
        panel.setLayout(new BorderLayout());
        
        final JPanel drawPanel = new JPanel() {
        	// hier wird immer gezeichnet:
            @Override
            public void paintComponent(Graphics g) {
                super.paintComponent(g);
                g.setColor(color);
                g.fillRect(0, 0, 100, 100);
            }
        };
 
        JButton button = new JButton("OK");
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if(color == Color.GREEN) {
                    color = Color.RED;
                } else {
                    color = Color.GREEN;
                }
                drawPanel.repaint();
            }
        });
        panel.add(button, BorderLayout.SOUTH);
        panel.add(drawPanel, BorderLayout.CENTER);
        frame.getContentPane().add(panel);
        
        frame.pack();
        frame.setVisible(true);
    }
}
 
Nein. Ich benutze Eclipse. Im zweifelsfalle:
java MyClass
von der Shell. Aber ich glaube kaum, dass sich in Netbeans da was anders ist.

EDIT:
klappt auch mit Netbeans 6.8 genau so wie erwartet. ;-)
 
Zuletzt bearbeitet:
Hi !

Als ich damals Eclipse installiert habe, suchte ich verzweifelt nach ner GUI.
Es gab damals zwei GUIs. Eine die noch nichts konnte und die zweite kostete gleich mal ein paar Euronen. Gibts da jetzt eine GUI ?

Gruß Uli
 
Die gibts sicher auch in Eclipse. Bin leider kaum in diesem Bereich tätig und schreibe die kleinen Dinge von Hand. Wenns was kleines ist würd ichs eh per Hand machen. Man lernts auch gleich.
Aber sonst?
Den vielleicht:
Visual Editor Project

Wie das genau in Netbeans läuft weiss ich leider nicht. Hab netbeans seit 10 min wieder installiert. Da kennt sich vielleicht jemand anderes besser aus.
Sonst machs halt von Hand. Kann nie schaden.

EDIT:
Ihhh. Der Builder von Netbeans macht ja 5 km Code.
 
Zuletzt bearbeitet:

Zurück
Oben