Problem setVisible()

Lui-Kun

Neues Mitglied
Guten Morgen,

Ich habe ein Problem beim einblenden/ausblenden von Textfeldern.

Funktion:
Beim drücken des Buttons btnTest0 soll das Textfeld tfFlaeche0 erzeugt, gezeichnet und das Textfeld tfFlaeche1 sowie die Zeichnung ausgeblendet werden falls Button btnTest1 davor schon gedrückt wurde.
Beim drücken des Buttons btnTest1 soll das Textfeld tfFlaeche1 erzeugt, gezeichnet und das Textfeld tfFlaeche0 sowie die Zeichnung ausgeblendet werden falls Button btnTest0 davor schon gedrückt wurde.
Ich hab das ganze in eine if-Verzweigung jeweils gepackt damit die Textfelder immer nur einmal erzeugt werden und danach bloß eingeblendet und ausgeblendet werden müssen.

Problem:
Das Programm läuft zwar aber nicht eindwandfrei. Beim ersten klicken des Buttons wird nicht gezeichnet oder wenn man ein Button mehrmals hintereinander drückt lässt sich mit dem anderen Button das Textfeld nicht mehr ausblenden.

Java:
import java.awt.*;
import java.awt.event.*;

public class Test extends Frame implements ActionListener {
  
  private Button btnTest0;
  private Button btnTest1;
  private int topic = -1;
  
  TextField tfFlaeche0;
  TextField tfFlaeche1;
  
  boolean x=true;
  boolean y=true;
  
  public Test() {
    ;
    addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {// System.exit(0);
        dispose();
      }
    });
    
    setTitle("Test");
    setSize(5000, 5000);
    setVisible(true);
    setLayout(null);
    
    btnTest0 = new Button("Test1");
    this.add(btnTest0);
    btnTest0.addActionListener(this);
    btnTest0.setBounds(300,110,100,30);
    
    btnTest1 = new Button("Test2");
    this.add(btnTest1);
    btnTest1.addActionListener(this);
    btnTest1.setBounds(400,110,100,30);
  }
  
  public void paint(Graphics g) {
    switch (topic) {
      case 0:
      g.drawString("Test!!!", 100, 100);
      break;
      case 1:
      g.drawLine(100, 100, 500, 500);
      break;
    } // end of switch
  }
  
  public void actionPerformed(ActionEvent oEvent) {
    if (oEvent.getSource() == btnTest0) {
      topic = 0;
      if(x=true){
        tfFlaeche0 = new TextField (8);
        add(tfFlaeche0);
        tfFlaeche0.setBounds(200,90,100,20);
      }else{
        tfFlaeche0.setVisible(true);
      }
      tfFlaeche1.setVisible(false);
      x=false;
    }
    if (oEvent.getSource() == btnTest1) {
      topic = 1;
      if(y=true){
        tfFlaeche1 = new TextField (8);
        add(tfFlaeche1);
        tfFlaeche1.setBounds(300,90,100,20);
      }else{
        tfFlaeche1.setVisible(true);
      }
      tfFlaeche0.setVisible(false);
      y=false;
    }
    repaint();
  }
  
  public static void main(String args[]) {
    new Test();
  }
}

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at Test.actionPerformed(Test.java:61)
at java.awt.Button.processActionEvent(Button.java:392)
at java.awt.Button.processEvent(Button.java:360)
at java.awt.Component.dispatchEventImpl(Component.java:4630)
at java.awt.Component.dispatchEvent(Component.java:4460)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

Ich hoffe ihr könnt mir bei dem Problem schnell helfen. Vielen dank!
Liebe Grüße!
 
Java:
if (x=true)

Bedeutet "weiße x true zu und gehe dann in die if-Abfrage, falls x true ist", was natürlich immer der Fall ist. Die Abfragen müsste heißen

Java:
if (x==true)

bzw. noch besser

Java:
if (x)

Außerdem musst du deine Anzeigefläche revalidieren, wenn du Komponenten hinzufügst/neu erzeugst (Methode
Java:
validate()
).

Hat es einen Grund, warum du AWT und kein Swing verwendest?
 
1) Frame.setVisible() gehört NIE in den eigenen Konstruktor sondern IMMER in den Caller !
2) Von Frame (bzw Window oder den ganzen Swing-Klassen) zu erben macht keinen Sinn. Denn du willst ja keinen neuen unter-Typ von Frame erstellen sondern lediglich ein normales Frame. Ergo : das extends weg und dafür eine Instanz-Variable vom Typ Frame.
3) Nutze lieber Swing. Ist deutlich einfacher zu handhaben als AWT.
4) if(x=true) ist weder ein Vergleich (sondern eine Zuweisung) noch sinnvoll. Erstmal müsste es wenn überhaupt if(x==true) heißen, was aber wenig Sinn hat wenn du prüfst ob es wahr ist das x wahr ist. Also prüfst du gleich ob x wahr ist : if(x).

Alles in allem ziemlich viele Anfänger-Fehler. Ich würde dir mal einen Blick hirein empfehlen : Galileo Computing :: Java ist auch eine Insel - index
 
Von Swing-Klassen zu erben ist wohl kein Anfängerfehler und kann durchaus sinnvoll sein, z.B. um Methoden zu überschreiben. Mache ich auch nach Jahren noch hin und wieder.

Aber Variablen wie boolean x und boolean y finde ich ein wenig gruselig. Da ließe sich bestimmt ein besserer Name finden.
 
Java:
if (oEvent.getSource() == btnTest0) {
    topic = 0;
    if(x=true){
        tfFlaeche0 = new TextField (8);
        add(tfFlaeche0);
        tfFlaeche0.setBounds(200,90,100,20);
    }else{
        tfFlaeche0.setVisible(true);
    }
    tfFlaeche1.setVisible(false);
    x=false;
}
Ohne jetzt teifer eingestiegen zu sein, aber das sieht komisch aus. Betrachte mal den else-Zweig: dort setzt du
Code:
setVisible(true)
. Nur einen Programmschritt weiter setzt du
Code:
setVisible(false)
, was denke ich nicht Sinn der Sache war.
 
Ohne jetzt teifer eingestiegen zu sein, aber das sieht komisch aus. Betrachte mal den else-Zweig: dort setzt du
Code:
setVisible(true)
. Nur einen Programmschritt weiter setzt du
Code:
setVisible(false)
, was denke ich nicht Sinn der Sache war.

Das sind 2 verschiedene Controls, wenn ich das richtig sehe...
 
Ohne jetzt teifer eingestiegen zu sein, aber das sieht komisch aus. Betrachte mal den else-Zweig: dort setzt du
Code:
setVisible(true)
. Nur einen Programmschritt weiter setzt du
Code:
setVisible(false)
, was denke ich nicht Sinn der Sache war.

dachte ich auch erst, aber es wird nicht das gleiche Objekt geändert mit setVisible(), sondern erst tfFlaeche0 und dann tfFlaeche1 😉
 

Zurück
Oben