Swing Sorry nicht mal ein Fenster öffnen...

NochNixBlicker

Bekanntes Mitglied
Hi Leute,

da man ja besser an einem Projekt, das man selber hat, lernt bin ich dabei ein paar Fenster für meine Anwendung zu schreiben. Ich hab raus, dass ich wenn ich aus einem Menü ein Fenster öffnen will (Wie in Windows) brauche ich einen ActionListener. Aber bei einer GUI benötige ich auch die AWT oder nur die swing (siehe unten)? Und wie bekomme ich dann den Listener dazu mein Formular zu öffnen?

JA ich weiß, nach acht Jahren hier im Forum sollte man dies wissen, aber ich bin seit 2000 behindert da ich angefahren wurde und war lange in Rehabilitation, die die Ausbildung zum IT-Kaufmann mit einschloß, warum ich HIER überhaupt dabei bin. Und am Ende der Ausbildung hatte ich es nich mal hinbekommen eine Java Anwendung im Debugger zum laufen zu bringen, obwohl ich Abitur habe. Jetzt verständlich, warum ich diese Tatsachen nicht allen Erzähle?

Java:
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JMenuBar;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import java.awt.Toolkit;
import java.awt.CardLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JPanel;
import javax.swing.event.*;

public class GIzEH {

   private JFrame frmGizeh;

   /**
    * Launch the application.
    */
   public static void main(String[] args)
   {
     EventQueue.invokeLater(new Runnable()
     {
       public void run()
       {
         try
         {
           GIzEH window = new GIzEH();
           window.frmGizeh.setVisible(true);
         }
         catch (Exception e)
         {
           e.printStackTrace();
         }
       }
     });
   }

   /**
    * Create the application.
    */
   public GIzEH()
   {
     initComponents();
     createEvents();
   }

   private void initComponents() // Creating and initializing components
     {
     frmGizeh = new JFrame();
     frmGizeh.setTitle("GIzEH 3.0");
     frmGizeh.setIconImage(Toolkit.getDefaultToolkit().getImage(GIzEH.class.getResource("/resource/GIzEH.ico")));
     frmGizeh.setBounds(100, 100, 670, 368);
     frmGizeh.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     
     JMenuBar menuBar = new JMenuBar();
     frmGizeh.setJMenuBar(menuBar);
     
     JMenu mndatei = new JMenu("Datei");
     menuBar.add(mndatei);
     
     JMenuItem mntmUpdateErzwingen = new JMenuItem("Update erzwingen");
     mndatei.add(mntmUpdateErzwingen);
     
     JMenuItem mntmEinstellungen = new JMenuItem("Einstellungen");
     mndatei.add(mntmEinstellungen);
     
     JMenuItem mntmBenutzerwechsel = new JMenuItem("Benutzerwechsel");
     mndatei.add(mntmBenutzerwechsel);
     
     JMenuItem mntmBeenden = new JMenuItem("Beenden");
     mntmBeenden.addActionListener(new ActionListener() {
       public void actionPerformed(ActionEvent arg0) {
       }
     });
     mndatei.add(mntmBeenden);
     
     JMenu mnEinsatz = new JMenu("Einsatz");
     menuBar.add(mnEinsatz);
     
     JMenuItem mntmSichern = new JMenuItem("Sichern");
     mnEinsatz.add(mntmSichern);
     
     JMenuItem mntmRetten = new JMenuItem("Retten");
     mnEinsatz.add(mntmRetten);
     
     JMenuItem mntmBergen = new JMenuItem("Bergen");
     mnEinsatz.add(mntmBergen);
     
     JMenu mn = new JMenu("?");
     menuBar.add(mn);
     
     JMenuItem mntmInhaltUndIndex = new JMenuItem("Inhalt und Index");
     mn.add(mntmInhaltUndIndex);
     
     JMenuItem mntmVerursacher = new JMenuItem("Verursacher");
     mn.add(mntmVerursacher);
     frmGizeh.getContentPane().setLayout(new CardLayout(0, 0));
     
     JPanel panel = new JPanel();
     
     panel.setLayout(null);
     
     JPanel panel_1 = new JPanel();
     frmGizeh.getContentPane().add(panel_1, "name_286991735852339");
     panel_1.setLayout(null);
     
     JPanel panel_2 = new JPanel();
     frmGizeh.getContentPane().add(panel_2, "name_287003703545487");
     panel_2.setLayout(null);
   }

   private void createEvents() {
     //JMenuItem.
   }
}


package einsatz;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JLabel;

public class triathlon {
   
   public static void main(String[] args) {
     
     JFrame triathlon = new JFrame("Triathlon");
     triathlon.setSize(600, 100);
     triathlon.setLocationRelativeTo(null);
     triathlon.setVisible(true);
     
     JPanel stammdaten = new JPanel();
     JPanel durchschnitt = new JPanel();
     JPanel normalverteilung = new JPanel();
     JPanel streckenundabstand = new JPanel();

     JTabbedPane tabpane = new JTabbedPane();
     tabpane.addTab("Stammdaten", stammdaten);
     tabpane.addTab("Durchschnitt und Abweichung", durchschnitt);
     tabpane.addTab("Normalverteilung", normalverteilung);
     tabpane.addTab("Strecke und Abstand", streckenundabstand);
     
     triathlon.add(tabpane);
     triathlon.setVisible(true);     
   }
}
[/code=java]
 
Ich habe mal sowas programmiert. Wenn man auf den Button klickt, verschiebt sich das Quadrat. Genauso kann sich dann das Glücksrad drehen. Du musst aber dafür einen Timer nutzen.

Java:
package code;

public class Rad {

    public static void main(String[] args){
    Spielfeld sf= new Spielfeld();
    sf.Spielen();
    }

}

Java:
package code;

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

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

public class Spielfeld implements ActionListener{

    private JFrame frame;
    private JPanel panel;
    private JButton spiel;
    private Blatt malblatt;
    private int zahl;

    public void Spielfeld(){
    
    }

    public void Spielen(){
        frame= new JFrame();
        panel= new JPanel();
        spiel= new JButton("Spielen");
        malblatt= new Blatt();
        spiel.addActionListener(this);
        panel.add(malblatt);
        panel.add(spiel);
        frame.add(panel);
        frame.pack();
        frame.setVisible(true);
    
    }

    public void actionPerformed( ActionEvent ae){
        if(ae.getSource()==this.spiel){
            zahl++;
            malblatt.SetZahl(zahl);
            frame.repaint();
        }
    }
}

Java:
package code;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;

import javax.swing.JLabel;

public class Blatt extends JLabel{

    
    Dimension layoutSize;
    int zahl=0;

    public Blatt(){
        super();
    }

    @Override
    public Dimension getPreferredSize() {
        layoutSize = super.getPreferredSize();
        int max = Math.max(layoutSize.width, layoutSize.height);
        return new Dimension(max + 200, max + 200);
    }

    @Override
    public void paintComponent(final Graphics g){
        super.paintComponent(g);
        g.setColor(Color.RED);
        g.fillRect(10+10*zahl,10,20,20);
    }

    public void SetZahl(int z){
        this.zahl=z;

    }

}
Das ist ein Post zu einem anderen Thema. Du siehst, dass ich das Programm auf mehrere Klassen aufgeteilt habe. Der Vorteil ist einfach, dass der Code aufgeteilt ist und damit leichter wartbar. Im Beispielcode wird nur ein Quadrat verschoben. Ich denke aber, du kannst das Wechselspiel zwischen Actionlistener und Neuzeichnen erkennen. Ich persönlich würde das nicht so spannend machen. Statt einer Menüstruktur kannst du auch erstmal Button erstellen, die dann die Dialoge aufrufen. JDialog ist eine eigene Klasse, da musst du dich mal belesen. Wenn du noch Fragen hast, frag.
 
Hallo AndiE,

vielen dank für deine Mühe. Aber irgendwie bin ich jetzt noch mehr verwirrt. Da du ja gemeint hast, dass das Programm mit mehr Klassen übersichtlicher wird, vermute ich meines könnte noch mehr aufgeteilt werden. De facto besteht meines auch aus zwei Klassen, jedoch kam ich nicht auf die Idee einen neuen Tag daraus zu machen.

Das heißt ich muss nur folgendes codieren?

Java:
public void actionPerformed( [ActionEvent ae){
        triarhlon()
    }
 
Das heißt ich muss nur folgendes codieren?
Nein. So wie du das geschrieben hast, muss "triarhlon" eine parameterlose Methode in der Klasse sein, in der auch die actionPerformed steht.
Du hast zwar eine Klasse triathlon, aber diese hat nur eine static main-Methode.
Wene du aus einem Menü ein neues Fenster oder einen Dialog öffnen möchtest, würde ich dir dazu raten, die mit der Klasse AbstractAction auseinanderzusetzen. Hier ist ein Beispiel:
Java:
public class MainWindow {

  public static void main(String[] args) {
  JFrame frame = new JFrame("Action Demo");
  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  JPanel content = new JPanel();
  JMenuBar bar = new JMenuBar();
  JMenu panels = new JMenu("Panels");
  panels.add(new BluePanelAction(frame));
  bar.add(panels);
  frame.setJMenuBar(bar);
  frame.pack();
  frame.setVisible(true);
  }

  static class BluePanelAction extends DialogAction {

  public BluePanelAction(JFrame parent) {
  super("Blaues Panel", parent);
  }

  protected Component getComponent() {
  JPanel panel = new JPanel();
  panel.setOpaque(true);
  panel.setBackground(Color.BLUE);
  panel.setPreferredSize(new Dimension(500, 500));
  return panel;
  }

  }

  static abstract class DialogAction extends AbstractAction {

  private JFrame parent;

  protected DialogAction(String name, JFrame parent) {
  super(name);
  }

  protected abstract Component getComponent();

  public void actionPerformed(ActionEvent ae) {
  JDialog dialog = new JDialog(parent);
  dialog.getContentPane().add(getComponent());
  dialog.pack();
  dialog.setVisible(true);
  }
  }
}
 
Danke schön. Das kannte ich noch gar nicht. ich habe es immer mit ActionListener gemacht. Aber es entkoppelt die Klassen noch mehr.
 
Danke Harry! Ich versuche jetzt mal hier zu sagen, was mir der Code wahrscheinlich mitteilt.

Java:
public class MainWindow {

  public static void main(String[] args) {
  JFrame frame = new JFrame("Action Demo");
  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  JPanel content = new JPanel();
  JMenuBar bar = new JMenuBar();
  JMenu panels = new JMenu("Panels");
  panels.add(new BluePanelAction(frame));
  bar.add(panels);
  frame.setJMenuBar(bar);
  frame.pack();
  frame.setVisible(true);
  }
Du erstellst das Fenster mit der Menüleiste.
Java:
  static class BluePanelAction extends DialogAction {
  public BluePanelAction(JFrame parent) {
  super("Blaues Panel", parent);
  }
Die Klasse BlauFärben erbt von DialogAction. Und welche Klasse ist jetzt die Elternklasse?
Java:
  protected Component getComponent() {
  JPanel panel = new JPanel();
  panel.setOpaque(true);
  panel.setBackground(Color.BLUE);
  panel.setPreferredSize(new Dimension(500, 500));
  return panel;
}
Du erzeugst ein neues Panel und änderst das Erscheinungsbild.

Ab hier bin ich meldet sich die Suppe im Gehirn zurück und ich verstehe Bahnhof.
Java:
  static abstract class DialogAction extends AbstractAction {

  private JFrame parent;

  protected DialogAction(String name, JFrame parent) {
  super(name);
  }

  protected abstract Component getComponent();

  public void actionPerformed(ActionEvent ae) {
  JDialog dialog = new JDialog(parent);
  dialog.getContentPane().add(getComponent());
  dialog.pack();
  dialog.setVisible(true);
  }
  }
}

Könntest du bitte den von mir angegebenen Code modifizieren? Vielleicht kapiere ich es so besser. Ich hätte größte Lust alles hinzuschmeißen, weil seit meinem Unfall bin ich nur am Kämpfen (laufen, sprechen, Stuhl und Urin halten) - Ich mag nicht mehr...

Danke LG
Erik

P.S. Das ist KEINE Suizidankündigung!
 
Zuletzt bearbeitet von einem Moderator:
Ich habe auch eine berufliche Reha hinter mir. Ich will nicht sagen, ich kann nachfühlen, wie es dir geht, aber es vielleicht verstehen. Doch nun zum Thema. Es gibt bei GUI einen grundsätzlichen Mechanismus. Er taucht in ähnlicher Form überall auf. Es ist nämlich so, dass du zuerst die grafischen Elemente zeichnest. Nun gibt es Bedienelemente, wie Button, die "Actions" durch "ActionEvents" auslösen. Das geschieht z.B. dadurch, dass du auf einen Button klickst. Diese AktionEvents werden in Swing mit "actionPerformed" abgefangen. Dabei werden die Daten verändert und dann werden die Ansichten für ungültig erklärt ("invalidate") , woraufhin sich die Ansichten neu zeichnen. Damit ist die Abarbeitung beende, und die GUI wartet auf ein neues ActionEvent. Das Ganze wiederholt sich, bis zu das Programm beendest. Die Funktion actionPerformend kannst du Implementierung des Interfaces "ActionListener" einfügen, oder, für Swing typischer, durch Einbindung der Klasse "AbstractAction". Ich habe gerade "Triathlon" in Arbeit und dabei beide Wege ausprobiert. Soll ich dir das per PN schicken?
 
Danke AndiE gerne, denn ich VERSUCHE gerade aus deinem Post schlau zu werden: Also es gibt zwei Herangehensweisen. Einmal über den ActionListener was im Gegensatz zu AbstractAction nich wirklich gebräulich ist bei Swing-Komponenten.
 
Mein Versuch. Das ist die Startklasse. Sie erstellt eine Projektklasse und startet diese.
Java:
package code;


public class Triatlon {
  
    /**
     *
     * Start des Programms
     */
   public static void main(String[] args) {
       Laufen app= new Laufen();
       app.Start();
     }
}
Das ist die Ansichtsklasse, die dein Tabbed-Panel anzeigt.
Java:
package code;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;

public class Laufen {
   
    private JFrame triathlon;
   
    public Laufen(){
       
    }
   
    /**
     * Start der grafischen Oberfläche
     */
   
    public void Start(){
    triathlon = new JFrame("Triathlon");
    triathlon.setSize(600, 100);
    triathlon.setLocationRelativeTo(null);
       
    Stammdaten std = new Stammdaten();
    Durchschnitt drchschn = new Durchschnitt();
    JPanel normalverteilung = new JPanel();
    JPanel streckenundabstand = new JPanel();

    JTabbedPane tabpane = new JTabbedPane();
    tabpane.addTab("Stammdaten", std);
    tabpane.addTab("Durchschnitt und Abweichung", drchschn);
    tabpane.addTab("Normalverteilung", normalverteilung);
    tabpane.addTab("Strecke und Abstand", streckenundabstand);
   
    triathlon.add(tabpane);
    triathlon.setVisible(true);
    }

}
Wie du oben siehst habe ich ein Panel als Stammdaten implementiert. Diese ist die Klasse dazu. Sie enthält die Konstruktion mit dem ActionListener
Java:
package code;

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

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

public class Stammdaten extends JPanel implements ActionListener{
   
    static final long serialVersionUID=1L;
    JLabel lbl;
    JButton btn;
   
    public Stammdaten(){
        lbl= new JLabel();
        lbl.setText("Test");
        btn= new JButton("Klick mich");
        btn.addActionListener(this);
        this.add(btn);
        this.add(lbl);
       
        setVisible(true);
    }
   
    public void actionPerformed(ActionEvent ae){
    if(ae.getSource()==this.btn){
        lbl.setText("Geklickt");
        this.invalidate();
        }
    }
}
Nun folgt die Klasse Durchschnitt. Hier siehst du, dass der Button mit einer Action erstellt wurde.
Java:
package code;


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

public class Durchschnitt extends JPanel {
   
    final static long serialVersionUID=01L;
    private JTextField name;
    private JButton btn_save;
   
   
    public Durchschnitt(){
        Action klick= new KlickAction("Druecken",this);
        btn_save=new JButton(klick);
        name= new JTextField();
        name.setText("Null");
        this.add(name);
        this.add(btn_save);
        setVisible(true);
    }

    public void setAusgabe(){
        name.setText("Alles Klar");
        System.out.println("OK");
        this.invalidate();
    }
   
}
Das ist die KlickAction-Klasse, die in der obigen Klasse eingefügt wurde.
Java:
package code;

import java.awt.event.ActionEvent;

import javax.swing.AbstractAction;

public class KlickAction extends AbstractAction{
   
    final static long serialVersionUID=1l;
    Durchschnitt du;
   
    public KlickAction(String text, Durchschnitt d){
        super(text);
        du=d;
    }
   
    public void actionPerformed(ActionEvent ae){
        du.setAusgabe();
        du.invalidate();
    }
   

}
Soweit so gut. Du musst nun aber unterscheiden, das "Gizeh" und "Triathlon" zwei unterschiedliche Dialogformen benötigen, würde ich sagen. Bei "Gizeh" brauchst du modale Dialoge und bei "Triathlon" nicht. Daher wäre es jetzt schlau, wenn du dich erst mal auf ein Programm spezialisierst, das wir hier besprechen. Sonst kommst du tatsächlich immer durcheinander.
 
Danke AndiE, jetzt habe ich es auch hinbekommen *sichFreuWieEinSchneekönig* deine Anwendung laufen zu lassen. Man muss lernen sich an kleunen Dingen zu freuen, sonst wird man bescheuert wenn man so ein Schädel-Hirn-Trauma hat. Muss ich jetzt erstmal verdauen!
 
Ich denke, du hast IK gelernt, oder umgeschult. Dann solltest du auch das ARIS-Haus kennen, oder ähnliche Entwicklungswerkzeuge. Versuche nun einfach mal, aufzuschreiben, was die Programme beide machen sollen, und wozu du dafür diese Menu-Punkte oder Register angelegt hast. Wenn du uns das auch noch mitteilst, können wir dir helfen, zumindest ein Programm auf den richtigen Weg zu bringen. Ansonsten finde ich, ist es tatsächlich so, dass man sich beim Programmieren oft über das Funktionieren kleiner Abschnitte freut.
 
Hallo AndiE,
ja habe im BBW Neckargemünd gelernt. Aber leider reicht das, was hängen geblieben ist gerade noch für ein bißchen SQL. Habe dennoch for (lauter Langeweile mich an den) next Schritt gewagt und habe einigen Word- und Excel-Dokumente fertig, mit Bildern der einzelnen Fenster, in denen detailiert Beschrieben ist, was passieren soll. Aber leider kann man die nicht hochladen, nicht mal als *.opendocument
 
So wird das ganze viel zu umfangreich. Das Kernproblem sehe ich hier: "Für die Absicherung der Wasserrettung bei Triathlon-Wettbewerben soll der Bereich bestimmt werden, in dem nach Ermüdeten oder Ertrunkenen im Fluss gesucht werden kann." In einem See , also ohne Strömung ist der Bereich zwischen Start und Ziel mal Feldbreite der gesuchte Bereich. Dieser verschiebt sich je nachdem, ob die Schwimmer mit oder gegen die Strömung schwimmen. Ich denke, diesen Bereich zu bestimmen, ist die erste Aufgabe.

Was mir noch nicht klar ist, ist der praktische Einsatz. Ich habe gedacht, es werden die Teilnehmer gezählt, die ins Wasser gehen und rauskommen. Und dann sind Rettungsschwimmer auf dem Wasser, die die Sportler beobachten. Es gibt ja Treibanker, so dass die begleitenden Boote nicht mit der Strömung mitgerissen werden, sondern vor Ort bleiben, wenn sie nicht ankern können. Die sehen doch, ob jemand nicht mehr kann. Macht man ja bei uns bei Regatten auch.
 
Leider nicht ganz richtig, aber zur verständlichkeit probier ich es mal so:

  1. Die Triathlon-Überwachung ist eigentlich nur gedacht als Hilfsmittel zum berechnen des benötigten Materials und Personals. Sie hat nichts mit der Leichensuche oder der Rettung Ertrinkender zu tun.
  2. Die Rettung ertrinkender ist oft ein Problem weil sich die Einsatzkräfte in der Regel verschätzen, wie weit jemand vom Wasser mitgetrieben worden sein könnte. So wird die Strecke von der nächsten Flussbiegen bis zur Übernächsten gar nicht abgesucht.
  3. Bei der Leichensuche werden auch Suchhunde eingesetzt. Jedoch ist der Ort an dem sie anschlagen logischerweise nicht der Lageort. Und dafür die Software, weil so was im Kopf zu berechnen würde ich vielleicht Berufsfeuerwehren zutrauen aber nicht Kräften, die fünfmal im Jahr einen Einsatz haben.
 
Ich sag mal so. Ich sehe da momentan kein GUI-Problem mehr. Du solltest nun probieren, das Traithlon- und das Suchmodeul seperat zu erstellen. Erst mal als Standalone-Abwendung. Auf jeden Fall solltest du mal auf einem Blatt die Anwendungen nachvollziehen, damit du weißt, was du willst. Aber in meinen Augen hat das nichts mehr mit GUI zu tun, wofür diese Rubrik ja gedacht ist.
 
public void addElement(JComponent component, int x, int y, int width, int height, String text) {
component.setLocation(x, y);
component.setSize(width, height);

if (component instanceof JTextField) {
((JTextField) component).setText(text); }
if (component instanceof JRadioButton) {
((JRadioButton) component).setText(text);
}
if (component instanceof JButton) {
((JButton) component).setText(text);
}
if (component instanceof JLabel) {
((JLabel) component).setText(text);
}
component.setVisible(true);
getContentPane().add(component);

}
 
Den Cunstructor brauchst du dann sicherlich auch 🙂
public AuslesenMain() { // Constructor

setTitle("Klassen suchen"); // JFrame wird erzeugt
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(1000, 500);
setLocation(50, 50);
setVisible(true);

name = new JLabel(); // JLabel wird erzeugt und String wird ausgegeben
addElement(name, 50, 130, 300, 50, zeile);
 

Zurück
Oben