Neuzeichnen bei AbstractAction

AndiE

Top Contributor
Hallo,

ich habe da Schwierigkeiten, die Ansicht neu zeichnen zu lassen. Dies sind die Klassen:
Java:
public class Umrechner {

    /**
     *
     * Startet die Anwendung
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Anzeige a= new Anzeige();
        a.start();
    }

}
Java:
import javax.swing.JFrame;

public class Anzeige {
   
    /**
     *  stellt den Frame dar
     */

    private JFrame f;
    private Zeiger z;
   
    double temperatur;
   
   
    public Anzeige(){
        temperatur=10.0;
    }
   
    public void start(){
        System.out.println("0");
        z= new Zeiger(this);
        f= new JFrame("Temperaturumrechner");
        f.setSize(320,320);
        f.pack();
        f.add(z);       
        f.setVisible(true);       
    }   
    public double holeTemp(){
        return temperatur;
    }
   
    public void erhoehen(){
        temperatur+=10.0;
    }
}
Java:
import java.awt.event.ActionEvent;

import javax.swing.AbstractAction;

public class KlickAction extends AbstractAction{
   
    /**
     * Klickaction
     */
   
    private Zeiger anz;
   
    public KlickAction(String s, Zeiger a){
        super(s);
        anz=a;
    }
   
    public void actionPerformed(ActionEvent ae){
        System.out.println("1");
        anz.erhoehen();
       
    }
   

}
Java:
import java.awt.Dimension;

import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class Zeiger extends JPanel{
   
    /**
     * Anzeigepanel
     */

    private String anz;
    private double temperatur;
    private Anzeige a;
   
    public Zeiger(Anzeige z){
        System.out.println("4");
        a=z;
        temperatur= z.holeTemp();
       
        this.setOpaque(true);
        this.setPreferredSize(new Dimension(300,300));       
        JTextField grad= new JTextField();
        anz=Double.toString(temperatur);
        grad.setText(anz);
       
       
        JTextField fahrenheit=new JTextField();
        double fahren;
        fahren=temperatur*1.8+32;
        anz=Double.toString(fahren);
        fahrenheit.setText(anz);
       
        Action klick= new KlickAction("Erhoehen", this);
        JButton button= new JButton(klick);
        add(new JLabel("Celsius"));
        add(grad);
        add(new JLabel("Fahrenheit"));
        add(fahrenheit);
        add(button);
    }
   
    public void erhoehen(){
        a.erhoehen();
        System.out.println("2");
        this.invalidate();
    }
}
Theoretisch sollte das Panel für ungültig erklärt werden und dieses dann neugezeichnet werden. aber irgendwie macht er das nicht. Beim tabbedPane an andere Stelle hat es funktioniert. Wo ist mein Denkfehler?
 
Du musst auf dem JTextField .setText aufrufen. Nur bei du die Variable temperatur erhöhst, bekommt das TextField diese Information nicht mit.

Also Etwa so:

Java:
import java.awt.Dimension;

import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class Zeiger extends JPanel{
 
    /**
     * Anzeigepanel
     */

    private String anz;
    private double temperatur;
    private Anzeige a;
    JTextField grad= new JTextField();
    JTextField fahrenheit=new JTextField();
    public Zeiger(Anzeige z){
        System.out.println("4");
        a=z;
        temperatur= z.holeTemp();
     
        this.setOpaque(true);
        this.setPreferredSize(new Dimension(300,300));     
      
        anz=Double.toString(temperatur);
        grad.setText(anz);
     
     
      
        double fahren;
        fahren=temperatur*1.8+32;
        anz=Double.toString(fahren);
        fahrenheit.setText(anz);
     
        Action klick= new KlickAction("Erhoehen", this);
        JButton button= new JButton(klick);
        add(new JLabel("Celsius"));
        add(grad);
        add(new JLabel("Fahrenheit"));
        add(fahrenheit);
        add(button);
    }
 
    public void erhoehen(){
        a.erhoehen();
        double temp = a.holeTemp();
        grad.setText(temp+"");
        System.out.println("2");       
    }
}
 
Danke. So ist das, wenn man mit mehreren Systemen gearbeitet hat. Ich weiß nicht mehr genau wo, aber manchmal muss man die ansicht ungültig erklären, dann wird sie neu gezeichnet. Das galt auch für Eingabeelemente, nicht nur für Zeichnungen. Könnte Perl/Tk, Qt oder C# gewesen sein.
 
Noch eine Kleinigkeit:
"Normalerweise" hätte ich einen ActionListener verwendet, mit Java 8 ungefähr so:

Java:
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class Zeiger extends JPanel{

    private Anzeige a;
    JTextField grad= new JTextField();
    JTextField fahrenheit=new JTextField();
    public Zeiger(Anzeige z){
        System.out.println("4");
        a=z;
        this.setOpaque(true);
        this.setPreferredSize(new Dimension(300,300)); 
       
        double temperatur= z.holeTemp();
        double fahren=temperatur*1.8+32;     
        grad.setText(temperatur+"");              
        fahrenheit.setText(fahren+"");
              
        JButton button= new JButton("Erhoehen");
        button.addActionListener(e -> erhoehen(e));
        add(new JLabel("Celsius"));
        add(grad);
        add(new JLabel("Fahrenheit"));
        add(fahrenheit);
        add(button);
       
    }
  
    public void erhoehen(ActionEvent e){
        a.erhoehen();
        double temp = a.holeTemp();
        double fahren=temp*1.8+32;
        grad.setText(temp+"");
        fahrenheit.setText(fahren+"");
        System.out.println("2");
       
    }
}

Ggf. möchtest du ja ein Pattern umsetzen, dann ist deine Variante vielleicht die Richtige.

achja, du rufst .pack() auf dem Jframe zuerst auf, und dann fügst du mit .add() Komponentenhinzu. .pack() sollte erst aufgerufen werden, wenn bereits alle Komponenten hinzugefügt werden.
Außerdem könnte es günstig sein, auf dem JFrame f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); aufzurufen, damit sich das Programm beendet, wenn man das Fenster schließt.
 

Zurück
Oben