简体   繁体   English

JComboBox显示值

[英]JComboBox show value

Need help with JComboBox component. 需要有关JComboBox组件的帮助。 I've load data from MySQL database and write this data into combo. 我已经从MySQL数据库加载数据并将此数据写入组合。 I use four combo boxes with ItemListener . 我在ItemListener使用了四个组合框。 When one combo box change all children combo boxes reload data from database. 更改一个组合框时,所有子组合框将从数据库中重新加载数据。 First and two works fine but third and four don't show value normal, but good value is there. 第一个和第二个效果很好,但是第三个和第四个没有正常显示值,但是有很好的值。 Only I don't show it. 只有我不显示。 When I select empty field in combo box after then I see good result. 当我在组合框中选择空字段之后,我看到了很好的结果。

Source code: 源代码:

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);
    }

}
}
  • JComboBox doesn't know somehow then underlaying Vector is changed, have to reinitialize this array for JComboBox on the fly, but this is wrong way, JComboBox不知道如何改变底层Vector,必须即时为JComboBox重新初始化此数组,但这是错误的方式,

  • for any changes on the runtime to use XxxComboBoxModel for storing Items for JComboBox 在运行时进行任何更改以使用XxxComboBoxModel来存储JComboBox的项目

  • for JDBC or FileIO there could be Concurency issue, Swing JComponents required to all updates (in this case JComboBox and its XxxComboBoxModel) must be done on EDT 对于JDBC或FileIO,可能存在并发问题,所有更新所需的Swing JComponent(在这种情况下为JComboBox及其XxxComboBoxModel) 必须在EDT上完成

  • invoke Database event from the Runnable#Thread or SwingWorker , redirect this (potentionally) hard and long running task to the Workers Thread , otherwise Swing GUi will be freeze or unresponsive (for mouse and key events) untill JDBC ended Runnable#ThreadSwingWorker调用Database事件,将此(有可能)长时间运行的硬任务重定向到Workers Thread ,否则Swing GUi将被冻结或不响应(对于鼠标和键事件),直到JDBC结束

  • SwingWorker s methods publish(), process() and done() quite good quaranteed that all output wil be done on EDT SwingWorker的方法publish(),process()和done()很好地隔离了所有输出都将在EDT上完成

for example 例如

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);
    }
}

The GUI probably can't redraw properly. GUI可能无法正确重绘。 You are doing all of your hard work on the Event Dispatch Thread. 您正在对事件调度线程进行所有艰苦的工作。 This thread calls your itemStateChanged. 该线程调用您的itemStateChanged。 But this thread is also responsible for redrawing the GUI. 但是此线程还负责重绘GUI。 You are stopping it from doing that, because you are making it do your hard work in the database. 您正在阻止它执行此操作,因为您正在使它在数据库中完成艰苦的工作。

Instead, you can use a different thread to do your hard work. 相反,您可以使用其他线程来完成您的工作。

public void itemStateChanged(ItemEvent e) 
    {
        new Thread(new Runnable() {
            public void run() {
                .... your code...
            }
        }).start();
    }

Or take a look at SwingWorker, which does this in a nicer way. 或看看SwingWorker,它以一种更好的方式实现了这一点。

Also, itemStateChanged could be called twice for each selection - this might be causing you problems. 此外,对于每个选择,itemStateChanged可能会被调用两次-这可能会导致您出现问题。 Use "e.getStateChange()" to check what TYPE of event you just received. 使用“ e.getStateChange()”检查您刚刚收到的事件的类型。 You should receive a selected and an unselected (from the old item). 您应该收到一个选中的和未选中的(来自旧项)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM