Announcement

Collapse
No announcement yet.

Anfänger aus Berlin

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Anfänger aus Berlin

    Ich brauche wieder Hilfe!!!

    Frage 1:<BR>
    Meine "Test_Menu" Klasse wird in der "Test_Frame" Klasse implementiert, und von dieser Klasse möchte ich auf den "statusBar" der in der "Test_Frame" definiert wird, zugreifen d.h. den Inhalt verändern(andere Text schreiben) wenn ein Menü Eintrag ausgewählt wurde.<BR> Mein "statusBar" Inhalt wurde jedoch nicht verändert wenn der Menü Eintrag ausgewählt wurde s. Zeile A.

    Frage 2:<BR>
    Das gleiche Szenario wie in der Frage 1<BR>
    Mein "JRadioButton" sollte meiner Applikation neuen Look&Feel verpassen, wenn er aktiviert wird passiert folgendes: neue Look&Feel wurde nur der "Test_Menu" Klasse vergeben, die "Test_Frame" Klasse bleibt jedoch unverändert.<BR>
    Ich möchte aber das die ganze Applikation einen neuen L&F übernimmt. s. Zeile B.

    PS.<BR>
    Folgendes habe ich ausprobiert:
    Wenn die ganze Syntax "Test_Menu" Klasse, in die "Test_Frame" Klasse eingesetzt wird funktioniert auch alles.

    <B>Test_Frame</B> SYNTAX<BR>
    <PRE>

    public class Test_Frame extends JFrame {
    Test_Menu menu = new Test_Menu();
    JLabel statusBar = new JLabel();
    .
    .

    public Test_Frame() {
    .
    .
    this.statusBar.setText(" Status");
    this.getContentPane().add(menu, BorderLayout.NORTH);
    this.getContentPane().add(statusBar, BorderLayout.SOUTH);
    }
    }
    </PRE>

    <B>Test_Menu</B> SYNTAX<BR>
    <PRE>

    public class Test_Menu extends JMenuBar {
    static String motif = "com.sun.java.swing.plaf.motif.MotifLookAndFee l";
    static String win = "com.sun.java.swing.plaf.windows.WindowsLookAndFee l";
    .
    .

    public Test_Menu() {
    .
    .
    menuItem1.setMnemonic('N');
    menuItem1.addActionListener(new java.awt.event.ActionListener() {
    public void actionPerformed(ActionEvent e)
    { menuItem1_actionPerformed(e); }
    });
    radioButton2.setMnemonic('o');
    radioButton2.addActionListener(new java.awt.event.ActionListener() {
    public void actionPerformed(ActionEvent e)
    { radioButton2_actionPerformed(e); }
    });
    .
    .
    .
    }
    <P>

    <B> //Zeilen A. Behandle Menüeintrag Datei/Neu</B>

    void menuItem1_actionPerformed(ActionEvent e) {
    Test_Frame frame = new Test_Frame();
    frame.statusBar.setText(" TEST ");
    }
    </P>

    <B> //Zeilen B. Behandle Menüeintrag Ansicht/Motif</B>

    void radioButton2_actionPerformed(ActionEvent e) {
    try
    { UIManager.setLookAndFeel(motif); }
    catch(Exception exc)
    { System.err.println("Error loading L&F \n" + exc); }
    SwingUtilities.updateComponentTreeUI(this);
    }
    .
    .
    .
    </PRE>

  • #2
    Hallo Andreas,

    um ein Menü einzufügen musst du die Methode public void setJMenuBar(JMenuBar menubar) der Klasse JFrame benutzen.
    Schau dir dazu auch mal die Doku an.

    Thoma

    Comment


    • #3
      Hi Thomas

      Ich habe die Zeilen korrigiert, statt:
      <P>
      <I> Test_Menu menu = new Test_Menu();<BR>
      this.getContentPane().add(menu, BorderLayout.NORTH);</I>
      </P>
      habe ich <I>this.setJMenuBar(new Test_Menu());</I> geschrieben.

      Die Probleme die ich in den Fragen 1 & 2 geschildert habe bleiben wie vorher

      Comment


      • #4
        Hallo,

        das kann ja auch nicht gehen, da du im Eventandler A eine neue Instanz auf Test_Frame erzeugst. Diese ist aber nicht identisch
        mit der Instanz in die du das Menü einfügst. Du musst also entweder deinem Menü Konstruktor einen Parameter vom Typ Test_Frame hinzufügen, oder das Menü als innere Klasse der Klasse Test_Frame implementieren, oder nur ein Menü in der Klasse Test_Frame erzeugen, die Items erzeugen und diese dem Menü mit add... hinzufügen und dann das Menü mit setJMenuBar der
        Klasse Test_Frame hinzufügen.

        Das Problem mit SwingUtilities.updateComponentTreeUI(this); ist folgendes:

        this ist eine Referenz auf Test_Menu, somit wird auch nur dieses upgedatet.

        Thoma

        Comment


        • #5
          Hi Thomas

          Ich habe verschiedene Sachen ausprobiert, komme aber leider nicht weiter.<BR>
          Bedeutet das, dass ich lieber mein gesamtes Syntax der "Test_Menu" Klasse, direkt ins "Test_Frame" Klasse implementieren soll?
          Oder kannst Du mir verraten wie ich meinem Menu Konstruktor einen Parameter vom Typ Test_Frame hinzufügen soll.

          Diese Zeilen(in der "Test_Menu" Class) funktionieren nicht.<BR>
          Und obwohl der Compiler keine Fehler meldet, bleibt meine Applikation(Test_Frame.class) nach dem sie ausgeführt wurde unsichtbar, CPU läuft ganze Zeit mit 100%.


          <PRE>

          Test_Frame gesAnwendung =<B> new</B> Test_Frame();

          <P>
          <I> //Behandelt Menüeintrag Ansicht/Motif</I>

          <B> void</B> radioButton2_actionPerformed(ActionEvent e) {
          <B> try</B>
          { UIManager.setLookAndFeel(motif); }
          <B> catch</B>(Exception exc)
          { Error_Msg(); }
          SwingUtilities.updateComponentTreeUI(gesAnwendung) ;
          }
          </P>

          </PRE&gt

          Comment


          • #6
            Hallo Andreas,

            der Einfachheit halber habe ich eine eigene Implementierung gemacht:

            <pre>

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

            public class Test extends JFrame
            {
            private JLabel statusBar = new JLabel();
            private JPanel contentPane;
            private JMenuBar menuBar = new JMenuBar();
            private JMenu fileMenu = new JMenu("Datei");
            private JMenuItem exitItem = new JMenuItem("Beenden");
            //Schlüssel für die Klassennamen der LFs
            private final static String CLASSNAME = "className";
            private LookAndFeelChanger lookAndFeelChanger = new LookAndFeelChanger();

            public static void main(String[] args)
            {
            new Test();
            }

            public Test()
            {
            contentPane = (JPanel)getContentPane();
            contentPane.setLayout(new BorderLayout());
            //Name des aktiven LF setzen
            statusBar.setText(UIManager.getLookAndFeel().getNa me());
            contentPane.add(statusBar, BorderLayout.SOUTH);
            //Standardverhalten setzen (erst ab JDK 1.3)
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setBounds(100,100,600,400);
            //anonyme innere Klasse für Beenden Menüpunkt
            exitItem.addActionListener(new ActionListener()
            {
            public void actionPerformed(ActionEvent e)
            {
            System.exit(0);
            }
            });

            fileMenu.add(exitItem);
            menuBar.add(fileMenu);
            //Beschreibung siehe dort
            menuBar.add(createLookAndFeelMenu());
            setJMenuBar(menuBar);
            show();
            }
            //Erstellt das LF Menü.
            private JMenu createLookAndFeelMenu()
            {
            JMenu menu = new JMenu("Look & Feels");
            JMenuItem item;
            //Infos aller verfügbaren LFs holen
            UIManager.LookAndFeelInfo[] info = UIManager.getInstalledLookAndFeels();
            for (int i = 0; i < info.length; i++)
            {
            //item mit dem Namen des LFs erzeugen
            item = new JMenuItem(info[i].getName());
            //Listener hinzufügen - näheres siehe dort.
            item.addActionListener(lookAndFeelChanger);
            //item besitzt eine Hashtable. In dieser den Klassennamen speichern
            //Näheres zu Hashtable siehe java.util.Hashtable
            item.putClientProperty(CLASSNAME, info[i].getClassName());
            menu.add(item);
            }
            //das fertige Menü zurückgeben.
            return menu;
            }

            //Innere Klasse
            private class LookAndFeelChanger implements ActionListener
            {
            private AbstractButton b;
            private String fullName;

            public void actionPerformed(ActionEvent e)
            {
            //den Sender auf AbstractButton casten.
            //Dadurch unabhängig von Menü.
            //Sender könnte auch ein Button sein
            b = (AbstractButton)e.getSource();
            //Klassennamen aus der Hashtable holen
            fullName = (String)b.getClientProperty(CLASSNAME);
            try
            {
            //LF setzen
            UIManager.setLookAndFeel(fullName);
            //this würde auf LookAndFeelChanger referenzieren,
            //daher voll qualifizieren --> Test.this
            SwingUtilities.updateComponentTreeUI(Test.this);
            statusBar.setText(b.getText());
            }
            catch (Exception ex)//Es können 4 verschiedene Exceptions geworfen werden!!!!!
            {
            statusBar.setText("L&F-Wechsel fehlgeschlagen: "+ex);
            }
            }
            }

            }
            </pre>
            Gruss

            Thoma

            Comment


            • #7
              Hallo Thomas

              Wunderbare Beispiel, umfangreiche Kommentare, <U>Danke!</U><BR>
              Aber ich weiß immer noch nicht wie ich aus einer Subclass auf die Methoden einer Superclasse zugreifen kann.<BR>
              Hier folgende Szenario:<BR>
              meine <B>"Test" Klasse</B> implementiert <B>"Frame" Klasse</B>, diese beinhaltet nur einen StatusBar, und implementiert eine neue <B>Klasse "A"</B>. Die <B>Klasse "A"</B> beinhaltet nur einen Button, dieser sollte einen neuen String an StatusBar übergeben, nach dem er gedrückt wurde s. ZEILE 1.

              <U>Hier Komplette Syntax:</U>

              <B>Test.java</B>

              <PRE>

              public class test {

              public test() {
              Frame frame = new Frame();
              frame.setVisible(true);
              }

              public static void main(String[] args) {
              new test();
              }
              }

              </PRE>

              <B>Frame.java</B>

              <PRE>

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

              public class Frame extends JFrame {
              BorderLayout layout = new BorderLayout();
              JLabel statusBar = new JLabel("Status...");
              A meineKlasse = new A();

              //Frame konstruieren
              public Frame() {
              this.getContentPane().setLayout(layout);
              this.setSize(new Dimension(400, 300));
              this.getContentPane().add(meineKlasse, BorderLayout.CENTER);
              this.getContentPane().add(statusBar, BorderLayout.SOUTH);
              }

              //bei Herunterfahren das Programm beenden
              protected void processWindowEvent(WindowEvent e) {
              super.processWindowEvent(e);
              if(e.getID() == WindowEvent.WINDOW_CLOSING) {
              System.exit(0);
              }
              }
              }

              </PRE>

              <B>A.java</B>

              <PRE>

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

              public class A extends JPanel {
              JButton button = new JButton("Button");

              public A() {
              button.addActionListener(new java.awt.event.ActionListener() {
              public void actionPerformed(ActionEvent e)
              { button_actionPerformed(e); }
              });
              this.add(button);
              }

              void button_actionPerformed(ActionEvent e) {
              String s = "TEST Button wurde gedrückt";

              <B>// ZEILE 1. String s sollte statusBar Inhalt(Status...) überschreiben</B>

              }
              }

              </PRE&gt

              Comment


              • #8
                Hallo,

                implementieren ist hier nicht so der richtige Ausdruck. Die Klasse test ruft die Klasse Frame auf, aber implementiert sie nicht.
                Von Implementierung spricht man meist wenn es gilt ein Interface mit Quelltext zu versehen oder ähnlichem.
                Ausserdem sollte man Klassennamen immer gross schreiben, und auf Namen die bereits vergeben sind verzichten - hier Frame.
                Funktionieren tut es trotzdem, da es unterschiedliche Namensräume sind: java.awt.Frame und Frame (kein package).
                Auch die Begriffe Subclass und Superklasse sind in diesem Zusammenhang irreführend. Wenn man deine Frage wörtlich nimmt, dann müsste man antworten - einfach durch Aufruf der Methoden.

                Beispiel:
                Frame ist die Subklasse von JFrame und JFrame ist die Superklasse von Frame (in deinem konkreten Beispiel oben).
                Nicht umsonst gibt es das Schlüsselwort super. Angenommen du möchtest Zeichenoperationen in deinem JPanel A vornehmen,
                dann musst du die Methode public void paint (Graphics g) neu implementieren (jetzt passt's). Um sicherzustellen dass auch all das gezeichnet wird was die superklasse JPanel zeichnen will, musst du paint der Superklasse aufrufen - also so:

                <pre>
                public void paint(Graphics g)
                {
                super.paint(g);
                //hier deine Zeichenoperationen
                }
                </pre>

                die Frage müsste wohl lauten: Wie kann ich auf Methoden zugreifen die eine ander Klasse besitzt?

                Ganz einfach, in dem du dir eine Referenz auf diese Klasse besorgst etwa im Konstruktor. Ich habe die Klasse A entsprechend abgeändert.

                <pre>
                public class A extends JPanel
                {
                private JLabel statusBar;
                JButton button = new JButton("Button");
                public A(JLabel l)
                {
                statusBar = l;
                button.addActionListener(new java.awt.event.ActionListener() {
                public void actionPerformed(ActionEvent e)
                {
                statusBar.setText("TEST Button wurde gedrückt");
                }
                });
                this.add(button);
                }
                }
                </pre>

                Und so bindest du sie ein:

                contentPane.add(new A(statusBar), BorderLayout.CENTER);

                Gruss

                Thoma

                Comment


                • #9
                  Hi

                  ich glaube ich werden wahnsinnig, habe über 2500 Seiten Java-Unterlagen und trotzdem kann ich mein Problem nicht lösen.<BR>
                  Wieso kann ich nicht von der Klasse(A.java bzw. B.java) auf Methoden meiner Oberklasse(Test.java) zugreifen?<BR>
                  Habe verschiedene Sachen ausprobiert aber es klappt nicht.<BR>
                  hier noch mal mein Bsp.

                  <B>Test.java</B>

                  <PRE>

                  public class Test extends JFrame {
                  GridLayout gridLayout1 = new GridLayout();
                  JLabel jLabel = new JLabel("Noch nichts passiert!");
                  A klasse_A = new A();
                  B klasse_B = new B();

                  public Test() {
                  this.setSize(400,400);
                  this.getContentPane().setLayout(gridLayout1);
                  gridLayout1.setRows(3);
                  this.getContentPane().add(klasse_A.buttonA);
                  this.getContentPane().add(klasse_B.buttonB);
                  this.getContentPane().add(jLabel);
                  }

                  public static void main(String[] args) {
                  Test test = new Test();
                  test.setVisible(true);
                  }
                  }

                  </PRE>

                  <B>A.java</B>

                  <PRE>

                  public class A {
                  JButton buttonA = new JButton("Button A");

                  public A() {
                  buttonA.addActionListener(new java.awt.event.ActionListener() {
                  public void actionPerformed(ActionEvent e) {
                  String a = "Button A wurdre gedrückt!";

                  <B> // der String "a" sollte den jLabel Klasse "Test" überschreiben</B>

                  }
                  });
                  }
                  }

                  </PRE>

                  <B>B.java</B>

                  <PRE>

                  public class B {
                  JButton buttonB = new JButton("Button B");

                  public B() {
                  buttonB.addActionListener(new java.awt.event.ActionListener() {
                  public void actionPerformed(ActionEvent e) {
                  String b = "Button B wurdre gedrückt!";

                  <B> // der String "b" sollte den jLabel Klasse "Test" überschreiben</B>

                  }
                  });
                  }
                  }

                  </PRE&gt

                  Comment


                  • #10
                    Hallo,

                    die Frage habe ich doch in Antwort Nr. 7 beantwortet?????

                    Thoma

                    Comment

                    Working...
                    X