需要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);
}
}
}
答案 0 :(得分:3)
JComboBox以某种方式不知道底层的Vector被更改了,必须动态地为JComboBox重新初始化这个数组,但这是错误的方式,
对运行时使用XxxComboBoxModel进行存储的任何更改Items for JComboBox
可能存在Concurency问题,所有更新都需要Swing JComponents(在本例中为JComboBox及其XxxComboBoxModel)must be done on EDT
从Database
或Runnable#Thread
调用SwingWorker
事件,将此(有潜在的)艰难且长时间运行的任务重定向到Workers Thread
,否则Swing GUi将会冻结或无响应(对于鼠标和键事件),直到JDBC结束
SwingWorker
s methods publish(), process() and 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);
}
}
答案 1 :(得分:0)
GUI可能无法正确重绘。您正在对事件调度线程进行所有艰苦的工作。该线程调用itemStateChanged。但是这个线程也负责重绘GUI。你正在阻止它这样做,因为你正在让它在数据库中做你的辛勤工作。
相反,您可以使用其他线程来完成您的工作。
public void itemStateChanged(ItemEvent e) { new Thread(new Runnable() { public void run() { .... your code... } }).start(); }
或者看看SwingWorker,它可以更好地完成这项工作。
此外,可以为每个选择调用itemStateChanged两次 - 这可能会导致您遇到问题。使用“e.getStateChange()”来检查刚刚收到的事件类型。您应该收到一个已选中和未选中的(来自旧项目)。