0

在组件方面需要帮助JComboBox。我已经从 MySQL 数据库加载数据并将这些数据写入组合。我使用四个组合框和ItemListener. 当一个组合框更改所有子组合框时,会从数据库重新加载数据。第一个和第二个工作正常,但第三个和第四个不显示价值正常,但有很好的价值。只是我不表现出来。当我在组合框中选择空字段之后,我看到了很好的结果。

源代码:

public class Vyhladat extends Okno {
    private static final long serialVersionUID = 1L;
    JComboBox nominalBOX,statBOX,podpisBOX,tlacDoskaBOX;
    Font sherif = new Font("Sherif",Font.BOLD,20);
    Font normal = new Font("Sherif",Font.PLAIN,20);
    JFrame uh = new JFrame();
            private String adresa="jdbc:mysql://localhost:3306/jarodb";
    private String meno="JKARAK";
    private String heslo="bankovka";
    String nominal,stat,podpis,tlacDoska,statH;
    private String nominalSQL = "SELECT DISTINCT(nominal) FROM prehlad";
    private String statSQL = "SELECT DISTINCT(concat(stat,'/',seria)) FROM prehlad WHERE nominal=? ORDER BY stat";
    private String podpisSQL = "SELECT DISTINCT(podpis) FROM prehlad WHERE nominal=? AND stat=? ";
    private String tlacDoskaSQL = "SELECT DISTINCT(doska) FROM prehlad WHERE nominal=? AND stat=? AND podpis=? ";

    Vector nominalV=new Vector();
    Vector statV=new Vector();
    Vector podpisV=new Vector();
    Vector tlacDoskaV=new Vector();

    Vyhladat()
    {

        vlozPopis(nominalLAB,"NOMIN\u00C1L EUROBANKOVKY:   ",0,0,sherif);
        vlozPopis(statLAB,"\u0160T\u00C1T/S\u00C9RIA:",0,1,sherif);
        vlozPopis(podpisLAB,"PODPIS:",0,2,sherif);
        vlozPopis(tlacDoskaLAB,"TLA\u010COV\u00C1 DOSKA:",0,3,sherif);

        gbc.gridx=1;
        gbc.gridy=0;
        nacitajVyber(nominalSQL,nominalBOX,nominalV,false,false,false);
        nominalBOX = new JComboBox(nominalV);

        nominalBOX.addItemListener(new ItemListener()
        {
            public void itemStateChanged(ItemEvent e) 
            {
                nominal = (String)nominalBOX.getSelectedItem();

                if(nominal!=" ")
                {
                    nacitajVyber(statSQL,statBOX,statV,true,false,false);
                }
                else{
                    statBOX.removeAllItems();
                    podpisBOX.removeAllItems();
                    tlacDoskaBOX.removeAllItems();
                    }
            }   
        });
        nominalBOX.setPrototypeDisplayValue("500");
        nominalBOX.setFont(normal);
        nominalBOX.setSelectedIndex(0);
        nominalBOX.setToolTipText("Vyber z mo\u017Enost\u00ED nomin\u00E1lu bankoviek 5,10,20,50.");
        add(nominalBOX,gbc);

        gbc.gridx=1;
        gbc.gridy=1;
        statV.add(" ");
        statBOX= new JComboBox(statV);
        statBOX.addItemListener(new ItemListener()
        {
            public void itemStateChanged(ItemEvent e) 
            {
                stat = (String)statBOX.getSelectedItem();

                if(stat!=null)
                {
                    String [] statM= stat.split("/");
                    statH = statM[0];
                }

                if(stat!=" " & stat!=null)
                {
                    nacitajVyber(podpisSQL,podpisBOX,podpisV,false,true,false);
                }
                else{
                  podpisBOX.removeAllItems();
                  tlacDoskaBOX.removeAllItems();
                    }
            }   
        });
        statBOX.setPrototypeDisplayValue("Portugalsko/E");
        statBOX.setFont(normal);
        statBOX.setSelectedIndex(0);
        statBOX.setToolTipText("Vyber z mo\u017Enost\u00ED \u0161t\u00E1t/s\u00E9riu.");
        add(statBOX,gbc);

        gbc.gridx=1;
        gbc.gridy=2;
        podpisV.add(" ");
        podpisBOX = new JComboBox(podpisV);
        podpisBOX.addItemListener(new ItemListener()
        {
            public void itemStateChanged(ItemEvent e) 
            {
                podpis = (String)podpisBOX.getSelectedItem();

                if(podpis!=" " & podpis!=null)
                {
                    nacitajVyber(tlacDoskaSQL,tlacDoskaBOX,tlacDoskaV,false,false,true);
                }
                else{
                  tlacDoskaBOX.removeAllItems();
                    }
            }   
        });
        podpisBOX.setPrototypeDisplayValue("Jean-Claude Trichet ");
        podpisBOX.setFont(normal);
        podpisBOX.setSelectedIndex(0);
        podpisBOX.setToolTipText("Vyber z mo\u017Enost\u00ED troch podpisov.");
        add(podpisBOX,gbc);

        gbc.gridx=1;
        gbc.gridy=3;
        tlacDoskaV.add(" ");
        tlacDoskaBOX = new JComboBox(tlacDoskaV);

        tlacDoskaBOX.addItemListener(new ItemListener()
        {
            public void itemStateChanged(ItemEvent e) 
            {
                tlacDoska = (String)tlacDoskaBOX.getSelectedItem();

                if((nominal!=" " & nominal!=null) & (statH!=" " & statH!=null) & (podpis!=" " & podpis!=null) & (tlacDoska!=" " & tlacDoska!=null))
                {
                    zobraz.setEnabled(true);
                }

            }   
        });
        tlacDoskaBOX.setPrototypeDisplayValue("E010");
        tlacDoskaBOX.setFont(normal);
        tlacDoskaBOX.setSelectedIndex(0);
        tlacDoskaBOX.setToolTipText("Vyber z mo\u017Enost\u00ED tla\u010Dov\u00FDch dosiek.");
        add(tlacDoskaBOX,gbc);
}
private void nacitajVyber(String sqlDotaz, JComboBox chr,Vector v,
        boolean jedna,boolean dva, boolean tri)
{
    try
    {
        Class.forName("com.mysql.jdbc.Driver");
        Connection conn = DriverManager.getConnection(adresa,meno,heslo);
        PreparedStatement stmt = conn.prepareStatement(sqlDotaz);
        if(jedna==true)
            {
            chr.removeAllItems();
        stmt.setString(1, nominal);
        }
        if(dva==true)
        {
                    chr.removeAllItems();
            stmt.setString(1, nominal);
            stmt.setString(2, statH);
        }
        if(tri==true)
        {
                    chr.removeAllItems();
            stmt.setString(1, nominal);
            stmt.setString(2, statH);
            stmt.setString(3, podpis);
        }

        ResultSet rs = stmt.executeQuery();
           v.addElement(" ");
            while (rs.next())
                {v.addElement(rs.getString(1).trim());
            System.out.println(rs.getString(1));}



        validate();
        rs.close();
        stmt.close();
        conn.close();
    }
    catch(Exception e){
        JOptionPane.showMessageDialog(uh,e.toString(),
                "Chyba pripojenia",
                JOptionPane.ERROR_MESSAGE);
    }

}
}
4

2 回答 2

3
  • JComboBox 不知道以某种方式更改了底层 Vector,必须即时为 JComboBox 重新初始化此数组,但这是错误的方式,

  • 对于运行时的任何更改,以使用XxxComboBoxModel存储JComboBox 的项目

  • 对于 JDBC 或 FileIO 可能存在并发问题,所有更新所需的 Swing JComponents(在本例中为 JComboBox 及其 XxxComboBoxModel)必须在 EDT 上完成

  • DatabaseRunnable#Threador调用事件SwingWorker,将这个(可能)困难且长时间运行的任务重定向到Workers Thread,否则 Swing GUI 将冻结或无响应(对于鼠标和按键事件)直到 JDBC 结束

  • SwingWorkers 方法 publish()、process() 和 done()很好地保证了所有输出都将在 EDT 上完成

例如

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

public class ComboBoxTwo extends JFrame implements ActionListener, ItemListener {

    private static final long serialVersionUID = 1L;
    private JComboBox mainComboBox;
    private JComboBox subComboBox;
    private Hashtable<Object, Object> subItems = new Hashtable<Object, Object>();

    public ComboBoxTwo() {
        String[] items = {"Select Item", "Color", "Shape", "Fruit"};
        mainComboBox = new JComboBox(items);
        mainComboBox.addActionListener(this);
        mainComboBox.addItemListener(this);
        //prevent action events from being fired when the up/down arrow keys are used
        //mainComboBox.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);
        getContentPane().add(mainComboBox, BorderLayout.WEST);
        subComboBox = new JComboBox();//  Create sub combo box with multiple models
        subComboBox.setPrototypeDisplayValue("XXXXXXXXXX"); // JDK1.4
        subComboBox.addItemListener(this);
        getContentPane().add(subComboBox, BorderLayout.EAST);
        String[] subItems1 = {"Select Color", "Red", "Blue", "Green"};
        subItems.put(items[1], subItems1);
        String[] subItems2 = {"Select Shape", "Circle", "Square", "Triangle"};
        subItems.put(items[2], subItems2);
        String[] subItems3 = {"Select Fruit", "Apple", "Orange", "Banana"};
        subItems.put(items[3], subItems3);
//      mainComboBox.setSelectedIndex(1);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        String item = (String) mainComboBox.getSelectedItem();
        Object o = subItems.get(item);
        if (o == null) {
            subComboBox.setModel(new DefaultComboBoxModel());
        } else {
            subComboBox.setModel(new DefaultComboBoxModel((String[]) o));
        }
    }

    @Override
    public void itemStateChanged(ItemEvent e) {
        if (e.getStateChange() == ItemEvent.SELECTED) {
            if (e.getSource() == mainComboBox) {
                if (mainComboBox.getSelectedIndex() != 0) {
                    FirstDialog firstDialog = new FirstDialog(ComboBoxTwo.this,
                            mainComboBox.getSelectedItem().toString(), "Please wait,  Searching for ..... ");
                }
            } 
        }
    }

    private class FirstDialog extends JDialog { //sipmle simulation of JDBC events, by using Swing Timer

        private static final long serialVersionUID = 1L;

        FirstDialog(final Frame parent, String winTitle, String msgString) {
            super(parent, winTitle);
            setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
            JLabel myLabel = new JLabel(msgString);
            JButton bNext = new JButton("Stop Processes");
            add(myLabel, BorderLayout.CENTER);
            add(bNext, BorderLayout.SOUTH);
            bNext.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent evt) {
                    setVisible(false);
                }
            });
            javax.swing.Timer t = new javax.swing.Timer(1000, new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    setVisible(false);
                }
            });
            t.setRepeats(false);
            t.start();
            setLocationRelativeTo(parent);
            setSize(new Dimension(400, 100));
            setVisible(true);
        }
    }

    public static void main(String[] args) {
        JFrame frame = new ComboBoxTwo();
        frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}
于 2013-01-25T11:28:52.257 回答
0

GUI 可能无法正确重绘。您正在 Event Dispatch Thread 上进行所有艰苦的工作。该线程调用您的 itemStateChanged。但是这个线程也负责重绘 GUI。您正在阻止它这样做,因为您正在让它在数据库中完成您的辛勤工作。

相反,您可以使用不同的线程来完成您的艰苦工作。

    公共无效 itemStateChanged(ItemEvent e)
    {
        新线程(新可运行(){
            公共无效运行(){
                ....你的代码...
            }
        })。开始();
    }

或者看看 SwingWorker,它以更好的方式做到了这一点。

此外,每次选择都可以调用 itemStateChanged 两次 - 这可能会给您带来问题。使用“e.getStateChange()”检查您刚刚收到的事件类型。您应该收到一个选中的和未选中的(来自旧项目)。

于 2013-01-25T11:24:11.283 回答