Results 1 to 6 of 6
  1. #1
    agreed is offline Member
    Join Date
    Nov 2009
    Posts
    3
    Rep Power
    0

    Default Dynamic data model in JComboBox

    Hi everyone, I've got a problem with self-defined model for JComboBox. Here is the code

    Java Code:
    package fcombobox;
    
    import java.awt.event.ActionEvent;
    import java.util.Hashtable;
    import javax.swing.DefaultComboBoxModel;
    import javax.swing.JComboBox;
    import javax.swing.JFrame;
    import sun.awt.VerticalBagLayout;
    
    public class Main {
    
        public static void main(String[] args) {
            Attribute attribute = new Attribute();
            attribute.putValues("fruits", new String[] {"apples", "peaches"});
            attribute.putValues("drugs", new String[] {"euthanasipame", "aspirine", "analgine"});
            attribute.setSelectedKey("drugs");
    
            JFrame mainWindow = new JFrame("FComboBox");
            mainWindow.setSize(640, 480);
            mainWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            mainWindow.setLayout(new VerticalBagLayout());
            mainWindow.add(new SettingKeyComboBox(attribute));
            mainWindow.add(new FAttributeComboBox(attribute));
            mainWindow.setVisible(true);      
        }
    
        private static class SettingKeyComboBox extends JComboBox{
    
            public SettingKeyComboBox(Attribute attribute) {
                super(attribute.getKeys());
                this.attribute = attribute;
                this.addActionListener(this);
            }
    
            @Override
            public void actionPerformed(ActionEvent e) {
                attribute.setSelectedKey((String) this.getSelectedItem());
            }
    
            private Attribute attribute;
        }
    
        private static class Attribute {
    
            public Attribute() {
            }
    
            public void putValues(String key, String[] value) {
                values.put(key, value);
            }
    
            public String getValue(int index) {
                return values.get(selectedKey)[index];
            }
    
            public String getSelectedValue() {
                return selectedValue;
            }
    
            public void setSelectedValue(String selectedValue) {
                this.selectedValue = selectedValue;
            }
    
            public void setSelectedKey(String selectedKey) {
                if (!this.selectedKey.equals(selectedKey)) {
                    this.selectedKey = selectedKey;
                    selectedValue = values.get(selectedKey)[0];
                }
            }
    
            public int getSize() {
                return values.get(selectedKey).length;
            }
    
            public Object[] getKeys() {
                return values.keySet().toArray();
            }
    
            private String selectedKey = "";
            private String selectedValue = "";
            private Hashtable<String, String[]> values =
                    new Hashtable<String, String[]>();
        }
    
        private static class FAttributeComboBox extends JComboBox {
    
            public FAttributeComboBox(Attribute attribute) {
                this.setModel(new FAttributeComboBoxModel(attribute));
            }
    
            private class FAttributeComboBoxModel extends DefaultComboBoxModel {
    
                @Override
                public Object getElementAt(int index) {
                    return attribute.getValue(index);
                }
    
                @Override
                public Object getSelectedItem() {
                    return attribute.getSelectedValue();
                }
    
                @Override
                public void setSelectedItem(Object anObject) {
                    attribute.setSelectedValue((String) anObject);
                }
    
                @Override
                public int getSize() {
                    return attribute.getSize();
                }
    
                public FAttributeComboBoxModel(Attribute attribute) {
                    this.attribute = attribute;
                }
                private Attribute attribute;
            }
        }
    }
    As you see FAttributeComboBox depend on SettingKeyComboBox. Run it. If you open the second combobox (FAttributeComboBox) afrer that change the value in the first combobox(SettingKeyComboBox) on "fruits" and after that open second combobox everything will be fine. Instead of this if you firstly change firstly change first combobox value on "fruits" after that open second combobox after that change first combobox value on "drugs" and try to open second combobox after that you'll se just blank space.
    As I understand number of labels in combobox's popup is determined when it appears at first time. It means if you open combobox and after that something changes number of values and new number is more than previous popup won't display it.
    But I don't know how to solve that((
    P.S. Sori 4 mi inglish))

  2. #2
    camickr is offline Senior Member
    Join Date
    Jul 2009
    Posts
    1,233
    Rep Power
    7

    Default

    Here is a different approach that may work the way you want:

    Java Code:
    import java.awt.*;
    import java.awt.event.*;
    import java.util.*;
    import javax.swing.*;
    
    public class ComboBoxTwo extends JFrame implements ActionListener
    {
    	private JComboBox mainComboBox;
    	private JComboBox subComboBox;
    	private Hashtable subItems = new Hashtable();
    
    	public ComboBoxTwo()
    	{
    		String[] items = { "Select Item", "Color", "Shape", "Fruit" };
    		mainComboBox = new JComboBox( items );
    		mainComboBox.addActionListener( this );
    
    		//  In JDK1.4 this prevents action events from being fired when the
    		//  up/down arrow keys are used on the dropdown menu
    
    		mainComboBox.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);
    		getContentPane().add( mainComboBox, BorderLayout.WEST );
    
    		//  Create sub combo box with multiple models
    
    		subComboBox = new JComboBox();
    		subComboBox.setPrototypeDisplayValue("XXXXXXXXXX"); // JDK1.4
    		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);
    	}
    
    	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 ) );
    		}
    
    		//  make sure popup is closed when 'isTableCellEditor' is used
    
    //		mainComboBox.hidePopup();
    	}
    
    	public static void main(String[] args)
    	{
    		JFrame frame = new ComboBoxTwo();
    		frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
    		frame.pack();
    		frame.setLocationRelativeTo( null );
    		frame.setVisible( true );
    	 }
    }

  3. #3
    agreed is offline Member
    Join Date
    Nov 2009
    Posts
    3
    Rep Power
    0

    Default

    Actually it isn't exactly what I'm looking for. But unfortunately I haven't found better solutions((

  4. #4
    agreed is offline Member
    Join Date
    Nov 2009
    Posts
    3
    Rep Power
    0

    Default

    Here is my solution
    Java Code:
    package fcombobox;
    
    import java.awt.event.ActionEvent;
    import java.util.Hashtable;
    import javax.swing.DefaultComboBoxModel;
    import javax.swing.JComboBox;
    import javax.swing.JFrame;
    import sun.awt.VerticalBagLayout;
    
    public class Main {
    
        public static void main(String[] args) {
            Attribute attribute = new Attribute();
            attribute.putValues("fruits", new String[] {"apples", "peaches"});
            attribute.putValues("drugs", new String[] {"euthanasipame", "aspirine", "analgine"});
            attribute.setSelectedKey("drugs");
    
            JFrame mainWindow = new JFrame("FComboBox");
            mainWindow.setSize(640, 480);
            mainWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            mainWindow.setLayout(new VerticalBagLayout());
            mainWindow.add(new SettingKeyComboBox(attribute));
            FAttributeComboBox attributeComboBox = new FAttributeComboBox(attribute);
            mainWindow.add(attributeComboBox);       
            mainWindow.setVisible(true);
            attributeComboBox.init();
            mainWindow.validate();
        }
    
        private static class SettingKeyComboBox extends JComboBox{
    
            public SettingKeyComboBox(Attribute attribute) {
                super(attribute.getKeys());
                this.attribute = attribute;
                this.addActionListener(this);
            }
    
            @Override
            public void actionPerformed(ActionEvent e) {
                attribute.setSelectedKey((String) this.getSelectedItem());
            }
    
            private Attribute attribute;
        }
    
        private static class Attribute {
    
            final public static String UNDEFINED_STRING = "";
    
            public Attribute() {
            }
    
            public void putValues(String key, String[] value) {
                values.put(key, value);
            }
    
            public String getValue(int index) {
                String[] currentValues = values.get(selectedKey);
                return index < currentValues.length ?
                    values.get(selectedKey)[index] : UNDEFINED_STRING;
            }
    
            public String getSelectedValue() {
                return selectedValue;
            }
    
            public void setSelectedValue(String selectedValue) {
                this.selectedValue = selectedValue;
            }
    
            public void setSelectedKey(String selectedKey) {
                if (!this.selectedKey.equals(selectedKey)) {
                    this.selectedKey = selectedKey;
                    selectedValue = values.get(selectedKey)[0];
                }
            }
    
            public int getSize() {
                return values.get(selectedKey).length;
            }
    
            public Object[] getKeys() {
                return values.keySet().toArray();
            }
    
            private String selectedKey = "";
            private String selectedValue = "";
            private Hashtable<String, String[]> values =
                    new Hashtable<String, String[]>();
        }
    
        private static class FAttributeComboBox extends JComboBox {
    
            final public static int INITAL_SIZE = 255;
    
            public FAttributeComboBox(Attribute attribute) {
                this.setModel(new FAttributeComboBoxModel(attribute));
            }
    
            public void init() {
                setPopupVisible(true);
                setPopupVisible(false);
                ((FAttributeComboBoxModel)getModel()).initialized = true;
            }
    
            private class FAttributeComboBoxModel extends DefaultComboBoxModel {
    
                @Override
                public Object getElementAt(int index) {
                    return attribute.getValue(index);
                }
    
                @Override
                public Object getSelectedItem() {
                    return attribute.getSelectedValue();
                }
    
                @Override
                public void setSelectedItem(Object anObject) {
                    attribute.setSelectedValue((String) anObject);
                }
    
                @Override
                public int getSize() {
                    return initialized ? attribute.getSize() : INITAL_SIZE;
                }
    
                public FAttributeComboBoxModel(Attribute attribute) {
                    this.attribute = attribute;
                }
    
                private Attribute attribute;
                private boolean initialized = false;
            }
        }
    }
    It works but not proper. Every 5-8 run popup doesn't hide or hide incorrectly. FFUUUUU

  5. #5
    zweibieren is offline Senior Member
    Join Date
    Aug 2009
    Location
    Pittsburgh, PA
    Posts
    284
    Rep Power
    5

    Default

    I cannot reproduce hide failures on the pulldowns.
    But I have observed strange intermittent failures in the pulldowns.
    Every once in a while a selection cannot be made or once made fails to change the model.

  6. #6
    zweibieren is offline Senior Member
    Join Date
    Aug 2009
    Location
    Pittsburgh, PA
    Posts
    284
    Rep Power
    5

    Default Simple version

    The solution below makes more natural use of JComboBox
    and does not suffer the intermittent failures observed with other approaches.

    It also uses Box and BoxLayout. This is the first time I have used them,
    but it will not be the last. I may never write a LayoutManager again.

    Java Code:
    package com.physpics.test;
    
    import java.awt.*;
    import java.util.*;
    import javax.swing.*;
    
    /**
     * A Panel that displays two comboboxes, one for a category
     * and one for subcategories of the currently selected category.
     *
     * The input data structure is a HashMap from category names
     *  to arrays of subcategory names.
     *
     * @author zweibieren
     */
    public class ComboFest extends Box {
    	JComboBox category;  // the top level attributes
    	JComboBox [] subcat;  // one for each category
    	CardLayout layCards = new CardLayout();   // one card per subcat
    	JPanel cards = new JPanel(layCards);   // where to display the subcategories
    
    	/**
    	 * Constructor creating the Panel from an instance of the data structure.
    	 * @param values The HashMap from category names to subcategory arrays.
    	 */
    	ComboFest	(HashMap<String, String[]> values) {
    		super(BoxLayout.Y_AXIS);
    
    		category = new JComboBox(values.keySet().toArray()){
    			/**
    			 * When a selection is made in the category,
    			 * the subcategory is switched to the one for that catgegory.
    			 */
    			@Override
    			public void setSelectedIndex(int inx) {
    				super.setSelectedIndex(inx);
    				selectSub(inx);  // switch second row to subcategory
    			}
    		};
    
    		// for each category, make a JComboBox of the subcategories
    		ListModel lm = category.getModel();
    		subcat = new JComboBox[lm.getSize()];
    		for (int i = 0; i < subcat.length; i++) {
    			subcat[i] = new JComboBox(values.get((String)lm.getElementAt(i)));
    			cards.add(subcat[i], ""+i);
    		}
    		selectSub(0);   // (superfluous)
    
    		// now build the view
    
    		// first row
    		add(category);
    
    		// second row (with some indentation)
    		Box row2 = Box.createHorizontalBox();
    		row2.add(Box.createHorizontalStrut(20));
    		row2.add(cards);
    		add(row2);
    
    		// third row, swallow all extra space
    		add(new Box.Filler(new Dimension(91, 10),
    				new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE),
    				new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE)));
    	}
    
    	public void selectSub(int inx) {
    		layCards.show(cards, ""+inx);
    		// we could here reset the subcategory list to its first element
    	}
    
    	/**
    	 * @param args  From command line
    	 */
    	public static void main(String args[]) {
    		// create an example of the data structure
    		HashMap<String, String[]> attributes
    				= new HashMap<String, String[]> ();
    		attributes.put("fruits", new String[]{"apples", "peaches"});
    		attributes.put("drugs", new String[]{"euthanasipame", "aspirine", "analgine"});
    
    		// create a ComboFest
    		ComboFest fest = new ComboFest(attributes);
    		fest.setPreferredSize(new Dimension(400, 260));
    
    		// create a window and display the ComboFest in it
    		final JFrame frame = new JFrame();
    		frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
    		frame.add(fest);
    		frame.pack();
    		java.awt.EventQueue.invokeLater(new Runnable() {
    			@Override public void run() { frame.setVisible(true); }
    		});
    	}
    }

Similar Threads

  1. populate jCombobox with database data
    By joeyxaza in forum JDBC
    Replies: 2
    Last Post: 01-06-2014, 10:09 AM
  2. Filter table model by data in specific column
    By ribbs2521 in forum New To Java
    Replies: 9
    Last Post: 10-29-2009, 04:41 AM
  3. populate jCombobox with database data
    By joeyxaza in forum JDBC
    Replies: 0
    Last Post: 01-19-2009, 04:30 PM
  4. Data from a model class won't show up in the table
    By ayampanggang in forum AWT / Swing
    Replies: 3
    Last Post: 11-27-2008, 08:20 PM
  5. passing dynamic data
    By abhiN in forum Web Frameworks
    Replies: 0
    Last Post: 01-17-2008, 01:16 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •