Avatar billede weeelo Nybegynder
10. december 2007 - 17:30 Der er 15 kommentarer og
1 løsning

ActionListener på JComboBox skal opdatere anden

Hej eksperter,

Jeg har en combobox, som henter noget data fra en mysql database. Der er sat en actionlistener på, som fanger den valgte string og printer den i terminalen.

Jeg vil dog gerne have, at den string skal indgå i en query for den næste combobox, men kan simpelthen ikke få det til at virke.

Min kode ser sådan her ud:

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

public class Klasse {

    private JComboBox box1;
    private JComboBox box2;

        JComboBox box1 = new JComboBox();
        box1.setSelectedIndex(0);
        box1.addActionListener(new Box1Listener());

        JComboBox box2 = new JComboBox();
        box2.addActionListener(new Box2Listener());

    private class Box1Listener implements ActionListener {
        public void actionPerformed(ActionEvent e) {       
            box1 = (JComboBox)e.getSource();
            String tekst = (String)box1.getSelectedItem();
            updateBox2(tekst);
        }
    }
   
    private class Box2Listener implements ActionListener {
        public void actionPerformed(ActionEvent e) {       
            box2 = (JComboBox)e.getSource();
            String tekst2 = (String)box2.getSelectedItem();
            System.out.println(tekst2);
        }
    }

    private void updateBox2(String tekst) {
        txt = tekst;
        try {
            String query = MIN_QUERY;
                     
            res = MySQL.getMySQL().getData(query);
       
            while (res.next()) {
                String tekst = res.getString("felt");
                box2.addItem(tekst);
            } 
        } catch (Exception exn) {
            exn.printStackTrace();
        }
    }

Problemet opstår i updateBox2, hvor jeg får en nullpointerexception i box2.addItem(tekst);

Er der nogen der kan se hvad jeg gør forkert i forhold til opbygningen?
Avatar billede di8leva Nybegynder
10. december 2007 - 17:44 #1
Dette er måske en ny måde som man skal lave java-kod, men jeg kan ikke lige at du bruger samme referense til dine box1 og box2 i dine ActionListeners... starte med at byde dette til:

    private class Box1Listener implements ActionListener {
        public void actionPerformed(ActionEvent e) {     
            JComboBox src = (JComboBox)e.getSource();
            String tekst = (String)src.getSelectedItem();
            updateBox2(tekst);
        }
    }
 
    private class Box2Listener implements ActionListener {
        public void actionPerformed(ActionEvent e) {     
            JComboBox src = (JComboBox)e.getSource();
            String tekst2 = (String)src.getSelectedItem();
            System.out.println(tekst2);
        }
    }

og se hvad der sker.
Avatar billede weeelo Nybegynder
10. december 2007 - 17:53 #2
Det ændrer ikke på noget..

Hvad er forskellen helt præcist på JComboBox src og box1/box2 - den refererer da til det samme?
Avatar billede weeelo Nybegynder
10. december 2007 - 17:56 #3
Hvordan sørger jeg for, at updateBox2, udover at opdatere indholdet af boksen også tegner den igen?
Avatar billede di8leva Nybegynder
10. december 2007 - 17:58 #4
hvis du bruger addItem(...) så skal den selv tegne om combo-boksen.

NullPointerException får du fordi box2 ikke findes, fordi du ikke skabt den..

hvor i koden er:


        JComboBox box1 = new JComboBox();
        box1.setSelectedIndex(0);
        box1.addActionListener(new Box1Listener());

        JComboBox box2 = new JComboBox();
        box2.addActionListener(new Box2Listener());


Er de ikke i constructor til Klasse? Jeg syns det ser lidt underligt ud
Avatar billede weeelo Nybegynder
10. december 2007 - 18:04 #5
Nej de ligger i en metode drawPanel(), som returnerer et JPanel til en anden klasse, der står for at tegne hele GUI'en.

Begge combo-bokse bliver skabt i drawPanel()
Avatar billede weeelo Nybegynder
10. december 2007 - 18:06 #6
Hov, kan godt se mit kodeeksempel i første indlæg ikke ser særlig rigtigt ud. Det burde være sådan her:

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

public class Klasse {

    private JComboBox box1;
    private JComboBox box2;

    public JPanel drawPanel() {
        JComboBox box1 = new JComboBox();
        box1.setSelectedIndex(0);
        box1.addActionListener(new Box1Listener());

        JComboBox box2 = new JComboBox();
        box2.addActionListener(new Box2Listener());
       
        // Og en masse andet...
       
        return JPanel;
    }

    private class Box1Listener implements ActionListener {
        public void actionPerformed(ActionEvent e) {     
            box1 = (JComboBox)e.getSource();
            String tekst = (String)box1.getSelectedItem();
            updateBox2(tekst);
        }
    }
 
    private class Box2Listener implements ActionListener {
        public void actionPerformed(ActionEvent e) {     
            box2 = (JComboBox)e.getSource();
            String tekst2 = (String)box2.getSelectedItem();
            System.out.println(tekst2);
        }
    }

    private void updateBox2(String tekst) {
        txt = tekst;
        try {
            String query = MIN_QUERY;
                   
            res = MySQL.getMySQL().getData(query);
     
            while (res.next()) {
                String tekst = res.getString("felt");
                box2.addItem(tekst);
            }
        } catch (Exception exn) {
            exn.printStackTrace();
        }
    }
}
Avatar billede di8leva Nybegynder
10. december 2007 - 18:07 #7
jeg håber de bare bliver skabt en gang?

men så er ju fejlen her... i den metode, byd:

JComboBox box1 = new JComboBox(); -> box1 = new JComboBox();
JComboBox box2 = new JComboBox(); -> box2 = new JComboBox();

så du skaber de globale JComboBox:es og ikke de lokale i drawPanel
Avatar billede weeelo Nybegynder
10. december 2007 - 18:29 #8
Ja, det var bedre.. Nu opdaterer den med det samme!

Men den vil ikke udskrive box2 længere. Den returnerer null efter valget i box1 og så skriver den ellers ikke noget i terminalen når man vælger i box2.
Avatar billede di8leva Nybegynder
10. december 2007 - 18:36 #9
Altså... du må ju bare skabe dine JComboBoxes EN gang... hvis du laver 'new' på dem hver gang Panel:et skal gentegnes vil det virke meget dårligt, hvis det als kan virke.

Så desvärre er der nok nogle fler ting at lave inden du kan få det til at virke...

Kig på http://java.sun.com/docs/books/tutorial/uiswing/
Avatar billede weeelo Nybegynder
10. december 2007 - 19:08 #10
Nu ser det ud til at jeg har fået det til at virke næsten som det skal. Du har i hvert fald sat godt skub i det di8leva :)

Jeg har dog et problem jeg ikke helt kan gennemskue. Når jeg vælger fra box 1 printer den først den rigtige string i terminalen og dernæst printer den null fra box2.

Når jeg vælger i box2 printer den det rigtige.

Min kode ser nu sådan her ud:

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

public class Klasse {

    JComboBox box1 = new JComboBox();
    JComboBox box2 = new JComboBox();

    public JPanel drawPanel() {
        box1.addItem("Vælg en string...");
        box1.addActionListener(new Box1Listener());

        box2.addItem("Vælg fra box1...");
        box2.addActionListener(new Box2Listener());
       
        // Og en masse andet...
       
        return JPanel;
    }

    private class Box1Listener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            if((int)box1.getSelectedIndex() != 0) {
                box1 = (JComboBox)e.getSource();
                String tekst = (String)box1.getSelectedItem();
                System.out.println("Box1: " + tekst)
                updateBox2(tekst);
            }
        }
    }
 
    private class Box2Listener implements ActionListener {
        public void actionPerformed(ActionEvent e) {     
            if((int)box2.getSelectedIndex() != 0) {
                box2 = (JComboBox)e.getSource();
                String tekst2 = (String)box2.getSelectedItem();
                System.out.println("Box2: " + tekst2);
            }
        }
    }

    private void updateBox2(String tekst) {
        txt = tekst;
        try {
            String query = MIN_QUERY;
                   
            res = MySQL.getMySQL().getData(query);
            box2.removeAllItems();
            box2.addItem("Vælg fra box 2...");
     
            while (res.next()) {
                String tekst = res.getString("felt");
                box2.addItem(tekst);
            }
        } catch (Exception exn) {
            exn.printStackTrace();
        }
    }
}
Avatar billede _carsten Nybegynder
10. december 2007 - 20:54 #11
Det er vist nemmere at ItemListener

public class NewJFrame1 extends javax.swing.JFrame {

    public NewJFrame1() {
        initComponents();
    }
   
    private void initComponents() {

        box1 = new javax.swing.JComboBox();
        box2 = new javax.swing.JComboBox();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        getContentPane().setLayout(new java.awt.FlowLayout());

        box1.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
        box1.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                setBox2(evt);
            }
        });
        getContentPane().add(box1);

        box2.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
        getContentPane().add(box2);

        pack();
    }

    private void setBox2(java.awt.event.ItemEvent evt) {
        box2.setSelectedIndex(box1.getSelectedIndex());
    }
   
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new NewJFrame1().setVisible(true);
            }
        });
    }
   
    private javax.swing.JComboBox box1;
    private javax.swing.JComboBox box2;
}
Avatar billede di8leva Nybegynder
11. december 2007 - 10:05 #12
Du kan enten lytte til _carsten, og bruge en anden type af lyttere, eller kan du tilpasse din lyttere sådan her:

    private class Box2Listener implements ActionListener {
        public void actionPerformed(ActionEvent e) {   
            if((int)box2.getSelectedIndex() != 0) {
                box2 = (JComboBox)e.getSource();
                String tekst2 = (String)box2.getSelectedItem();
                if(tekst2 != null && tekst2.length() > 0) {
                    System.out.println("Box2: " + tekst2);
                }
            }
        }
    }
Avatar billede di8leva Nybegynder
11. december 2007 - 10:08 #13
Det er fordi når du tilföjer et element til en box (jeg ved ikke hvis det bare er förste gang, eller alle ganger) så fyres det af et ActionEvent, og jeg tror det er fordi når du tilföjer et objekt så bliver det også valgt.
Avatar billede weeelo Nybegynder
18. januar 2008 - 13:00 #14
Sorry for den lange ventetid og stilhed. Vi valgte at bruge en anden og mere simpel løsning og fik derfor ikke brug for denne.
Avatar billede weeelo Nybegynder
18. januar 2008 - 13:00 #15
Hov, lidt for hurtigt sendt..

di8leva og _carsten, hvis i vil have point må i lige svare :)
Avatar billede weeelo Nybegynder
29. januar 2008 - 14:53 #16
Ok, lukker..
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