Avatar billede baitianlong Nybegynder
07. september 2004 - 01:31 Der er 16 kommentarer og
2 løsninger

put samme actionlistener på mange knapper

Jeg kan af en eller anden årsag ikke få det her til at virke...

Jeg har en række knapper i en række paneler. De skal alle have en action tilknyttet. Derfor kan jeg i min metode skrive:

knapbold.addActionListener(actionfocus);
knapitalic.addaddActionListener(actionfocus);
...osv

Men det er jo ikke så smukt. Hvordan gør jeg det med en forløkke eller noget lign.

For enhver component i contentPane
  Hvis componenten er et panel
    For enhver component i panelet
      Hvis componenten er en knap
        knap.addActionListener(actionfocus);

Jeg kan ikke skrue de linier sammen. Håber på hjælp her i nattetimerne :)

Lidt hjælp: Alle mine paneler hedder "panel..."
Alle mine knapper hedder "knap..."
Avatar billede baitianlong Nybegynder
07. september 2004 - 01:48 #1
Jeg har lige prøvet med den her:

    for(int j = 0; j < pane.getComponentCount(); j++) {
            if(pane.getComponent(j) instanceof JPanel) {
                for(int k = 0; k < ((JPanel)pane.getComponent(j)).getComponentCount(); k++) {
                    if(((JPanel)pane.getComponent(j)).getComponent(k) instanceof JButton) {
                        ((JButton)((JPanel)pane.getComponent(j)).getComponent(k)).addActionListener(actionfocus);
                    }
                }
            }
        }

Men ikke nok med at den er grimmere end Anne Marie Helger, den virker heller ikke...
Avatar billede baitianlong Nybegynder
07. september 2004 - 01:53 #2
Jeg skal egentlig bare have en metode, der samler aller JButtons i en Container, fra hele contentpane, :o
Avatar billede baitianlong Nybegynder
07. september 2004 - 02:26 #3
Jeg har kodet den sådan her nu (I dør af grin), men den er egentlig god nok...

    for(int j = 0; j < pane.getComponentCount(); j++) {
            if(pane.getComponent(j) instanceof JButton) {
                alleknapper.add(pane.getComponent(j));
            } else if(pane.getComponent(j) instanceof JPanel) {
                JPanel panellevel2 = (JPanel)pane.getComponent(j);
                for(int k = 0; k < panellevel2.getComponentCount(); k++) {
                    if(panellevel2.getComponent(k) instanceof JButton) {
                        alleknapper.add(panellevel2.getComponent(k));
                    } else if(panellevel2.getComponent(k) instanceof JPanel) {
                        JPanel panellevel3 = (JPanel)panellevel2.getComponent(k);
                        for(int l = 0; l < panellevel3.getComponentCount(); k++) {
                            if(panellevel3.getComponent(l) instanceof JButton) {
                                alleknapper.add(panellevel3.getComponent(l));
                            } else if(panellevel3.getComponent(l) instanceof JPanel) {
                                JPanel panellevel4 = (JPanel)panellevel3.getComponent(l);
                                for(int m = 0; m < panellevel4.getComponentCount(); m++) {
                                    if(panellevel4.getComponent(m) instanceof JButton) {
                                            alleknapper.add(panellevel4.getComponent(m));
                                    }
                                }
                            }
                        }     
                    }
                }
            }
        }
        for(int n = 0; n < alleknapper.size(); n++) {
            ((JButton)alleknapper.get(n)).addActionListener(actionfocus);
        }

Den giver dog en OutOfMemoryError... Det kune man måske forvente ?!
Avatar billede baitianlong Nybegynder
07. september 2004 - 02:42 #4
Nu ser den sådan her ud (for jeg ved hvor knapperne ligger:

public void lavFocus(Container pane, ActionListener al) {
        Vector alleknapper = new Vector();
        for (int j = 0; j < pane.getComponentCount(); j++) {
            JPanel panellevel2 = (JPanel) pane.getComponent(j);
            for (int k = 0; k < panellevel2.getComponentCount(); k++) {
                JPanel panellevel3 = (JPanel) panellevel2.getComponent(k);
                for (int l = 0; l < panellevel3.getComponentCount(); k++) {
                    JPanel panellevel4 = (JPanel) panellevel3.getComponent(l);
                    for (int m = 0; m < panellevel4.getComponentCount(); m++) {
                        if (panellevel4.getComponent(m) instanceof JButton) {
                            alleknapper.add(panellevel4.getComponent(m));
                        }
                    }
                }
            }
        }
        for (int n = 0; n < alleknapper.size(); n++) {
            ((JButton) alleknapper.get(n)).addActionListener(al);
        }
    }

Men stadig OutOfMemoryError :(
Avatar billede Slettet bruger
07. september 2004 - 10:42 #5
Kunne du ikke med fordel lave en rekursiv metode som itererede igennem alle paneler?
Avatar billede labanos Nybegynder
07. september 2004 - 14:03 #6
måske kunne du lave dit eget panel

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

public class MyPanel extends JPanel {
    private static ActionListener myListener = new MyActionListener();
   
    public Component add(Component comp) {
        if (comp instanceof JButton) {
            ((JButton)comp).addActionListener(myListener);
        }
        return super.add(comp);
    }
}

Og så implementere den fælles actionhåndtering i MyActionListener?
Avatar billede labanos Nybegynder
07. september 2004 - 14:05 #7
ved at overskrive add som ovenstående, bliver der altid smidt en MyActionListener til de komponenter der er instanser af jbutton.. alle andre addes normalt..
Avatar billede baitianlong Nybegynder
07. september 2004 - 16:18 #8
Det lyder smart. Det må jeg lige prøve :)
Avatar billede baitianlong Nybegynder
07. september 2004 - 16:46 #9
Jeg bliver nødt til at have lidt hjælp med at implementere det.

Problemet er at den eneste funktionalitet jeg har i actionPerformed på den ActionListener er at der bliver lagt focus på et JTextPane

Skal jeg bare smide dem ind som indre klasser i mit GUI vindue, sådan her:

  public class MyActionListener implements ActionListener {
        public void actionPerformed(ActionEvent ae) {
            tekst.requestFocus();
        }
    }
   
    public class FocusPanel extends JPanel {
        private ActionListener knaplistener = new MyActionListener();
             
        public Component add(Component comp) {
            if(comp instanceof JButton) {
                ((JButton)comp).addActionListener(knaplistener);
            }
            return super.add(comp);
        }
    }

Eller skal jeg putte det i en seperat klasse. Der skal jo være adgang og forståelse for hvad "tekst" er i denne Klasse !?
Avatar billede baitianlong Nybegynder
07. september 2004 - 16:51 #10
Og hvis jeg gør dette

private JPanel panelknapperover = new FocusPanel(new FlowLayout(3));

Siger den:
The constructor EditorWindow.FocusPanel(FlowLayout) is undefined
Avatar billede _carsten Nybegynder
07. september 2004 - 16:59 #11
Hvor mange tusinde knapper har du ?

Jeg har lige prøvet at adde 25.000 JButton's til et JPanel og samtidig adde en actionListener til dem, det giver ingen problemer
Avatar billede baitianlong Nybegynder
07. september 2004 - 17:08 #12
Der er heller ikke nogen problemer i at skrive, som det står nu

panelformat.add(knapbold);
        knapbold.addActionListener(new BoldAction());
        knapbold.addActionListener(actionfocus);
        panelformat.add(knapitalic);
        knapitalic.addActionListener(new ItalicAction());
        knapitalic.addActionListener(actionfocus);
       
og så videre. Der er cirka tyve knapper. Jeg tænkte bare på at gøre det på en lidt smartere / bedre måde. Jeg synes forslaget med et Panel er smukt, jeg forstår bare ikke at bruge det.
Avatar billede _carsten Nybegynder
07. september 2004 - 17:23 #13
Jeg ved ikke om dette eksempel giver dig et hint, men jeg ville oprette et array af JButton's og så arbejde videre med det

public class Exp extends javax.swing.JFrame implements ActionListener{

    public Exp() {
        initComponents();
        setSize(400,400);
    }
   
    private void initComponents() {
        panel = new javax.swing.JPanel();

        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                exitForm(evt);
            }
        });

        // Her dannes knapperne, samt addes actionListener og
        // tilføjes til panelet
        for(int i = 0; i < button.length; i++){
            button[i] = new JButton("" + i);
            button[i].setName("" + i);
            button[i].addActionListener(this);
            panel.add(button[i]);
        }

        getContentPane().add(panel, java.awt.BorderLayout.CENTER);

        pack();
    }

    private void exitForm(java.awt.event.WindowEvent evt) {
        System.exit(0);
    }

    public static void main(String args[]) {
        new Exp().show();
    }
   
    public void actionPerformed(java.awt.event.ActionEvent e) {
        JButton but = (JButton)e.getSource();
        JOptionPane.showMessageDialog(this, "Dette er knap " + but.getName(),
                                        "Besked fra knap " + but.getName(),
                                        JOptionPane.PLAIN_MESSAGE);
    }
   
    private javax.swing.JPanel panel;
    private JButton[] button = new JButton[25];
}
Avatar billede baitianlong Nybegynder
07. september 2004 - 18:01 #14
Jeg fik den løst med rekursion:

public void enterComponentsToList(Vector list, Container con) {
        Component[] comps = con.getComponents();
        for (int i = 0; i < comps.length; i++) {
            if (comps[i] instanceof Container) {
                enterComponentsToList(list, (Container)comps[i]);
            } 
            list.addElement(comps[i]);
        }
    }
    public void addActionListenerToButtons(Vector list) {
        for(int i = 0; i < list.size(); i++) {
            Component tempcomp = (Component)list.get(i);
            if(tempcomp instanceof JButton) ((JButton)tempcomp).addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent ae) {
                    tekst.requestFocus();
                }
            });
        }
    }

Men tak for jeres forslag :)
Avatar billede _carsten Nybegynder
07. september 2004 - 18:05 #15
Det var da noget af en omvej, men det kører jo.
Avatar billede baitianlong Nybegynder
07. september 2004 - 18:34 #16
Tja, jeg er ikke helt sikker på hvad du mener med omvej. Formodentlig at det ville være smartere at putte ActionListeneren på, når knappen blev lavet ;)

Men jeg gad ikke til at kode det hele om, og jeg kan godt lide når komponenterne har forståelige navne "knapbold" osv. Ikke bare button[7] f.eks

Hvis du eller labanos vil have points for indsatsen, så smid et svar og få lidt for arbejdet...
Avatar billede _carsten Nybegynder
07. september 2004 - 19:53 #17
Jeg synes du er den som har arbejdet mest med opgaven, så for min skyld kan du snuppe points selv.

PS:    Den med navne/ knaptekst er nem at løse, eventuelt med et array af navne.

        String[] knapNavne = {"Knap 1", "Knap 2", "Knap 3" ..........};

        for(int i = 0; i < button.length; i++){
            button[i] = new JButton( knapNavne[i] );
            button[i].setName("" + i);
            button[i].addActionListener(this);
            panel.add(button[i]);
        }
Avatar billede labanos Nybegynder
08. september 2004 - 09:19 #18
sorry jeg fik ikke lige fulgt med...
jeg mistede lige tråden omkring de textpanes.. så hvis du selv fik det til at virke er jeg enig med carsten i at du selv snupper points.. mit forslag var bare en "generel" løsning der løste problemet med at smide den samme listener på alle knapper...
hvis du mener det var noget værd kan du gøre med points som du har lyst :) jeg håber bare det virker som det skal nu..
så jeg smider lige et uforpligtende svar :)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester