views:

692

answers:

2

Hi all.

Problem:

Update:

From the Java SE 6 API:

public JComboBox() Creates a JComboBox with a default data model. The default data model is an empty list of objects. Use addItem to add items. By default the first item in the data model becomes selected.

So I changed to JComboBox(model) as the API says:

public JComboBox(ComboBoxModel aModel) Creates a JComboBox that takes its items from an existing ComboBoxModel. Since the ComboBoxModel is provided, a combo box created using this constructor does not create a default combo box model and may impact how the insert, remove and add methods behave.

I tried the following:

    DefaultComboBoxModel model = new DefaultComboBoxModel();
    model.setSelectedItem(null);
    suggestionComboBox = new JComboBox(model);
    suggestionComboBox.setModel(model);

But could not get it to work, the first item is still being selected.

Anyone that can come up with a working example would be very much appreciated.


Old part of the post:

I am using JComboBox, and tried using setSelectionIndex(-1) in my code (this code is placed in caretInvoke())

suggestionComboBox.removeAllItems();
    for (int i = 0; i < suggestions.length; i++) {
        suggestionComboBox.addItem(suggestions[i]);
    }
    suggestionComboBox.setSelectedIndex(-1);
    suggestionComboBox.setEnabled(true);

This is the initial setting when it was added to a pane:

    suggestionComboBox = new JComboBox();
    suggestionComboBox.setEditable(false);
    suggestionComboBox.setPreferredSize(new Dimension(25, 25));
    suggestionComboBox.addActionListener(new SuggestionComboBoxListener());

When the caretInvoke triggers the ComboBox initialisation, even before the user selects an element, the actionPerformed is already triggered (I tried a JOptionPane here): http://i126.photobucket.com/albums/p109/eXPeri3nc3/StackOverflow/combo1.png http://i126.photobucket.com/albums/p109/eXPeri3nc3/StackOverflow/combo2.png http://i126.photobucket.com/albums/p109/eXPeri3nc3/StackOverflow/combo3.png

The problem is: My program autoinserts the selected text when the user selects an element from the ComboBox. So without the user selecting anything, it is automatically inserted already.

How can I overcome the problem in this situation? Thanks.

Here is my SSCCE: (finally)

package components;


import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.JTextPane;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.text.AbstractDocument;
import javax.swing.text.BadLocationException;
import javax.swing.text.StyledDocument;

public class Temp extends JFrame {

    JTextPane textPane;
    AbstractDocument doc;
    JTextArea changeLog;
    String newline = "\n";
    private JComboBox suggestionComboBox;
    private JPanel suggestionPanel;
    private JLabel suggestionLabel;
    private JButton openButton, saveButton, aboutButton;

    public Temp() {
        super("Snort Ruleset IDE");
        //Create the text pane and configure it.
        textPane = new JTextPane();
        textPane.setCaretPosition(0);
        textPane.setMargin(new Insets(5, 5, 5, 5));
        StyledDocument styledDoc = textPane.getStyledDocument();
        if (styledDoc instanceof AbstractDocument) {
            doc = (AbstractDocument) styledDoc;
            //doc.setDocumentFilter(new DocumentSizeFilter(MAX_CHARACTERS));
        } else {
            System.err.println("Text pane's document isn't an AbstractDocument!");
            System.exit(-1);
        }
        JScrollPane scrollPane = new JScrollPane(textPane);
        scrollPane.setPreferredSize(new Dimension(700, 350));

        //Create the text area for the status log and configure it.
        //changeLog = new JTextArea(10, 30);
        //changeLog.setEditable(false);
        //JScrollPane scrollPaneForLog = new JScrollPane(changeLog);

        //Create a JPanel for the suggestion area
        suggestionPanel = new JPanel(new BorderLayout());
        suggestionPanel.setVisible(true);
        suggestionLabel = new JLabel("Suggestion is not active at the moment.");
        suggestionLabel.setPreferredSize(new Dimension(100, 50));
        suggestionLabel.setMaximumSize(new Dimension(100, 50));
        suggestionComboBox = new JComboBox();
        suggestionComboBox.setEditable(false);
        suggestionComboBox.setPreferredSize(new Dimension(25, 25));
        //suggestionComboBox.addActionListener(new SuggestionComboBoxListener());
        suggestionComboBox.addItemListener(new SuggestionComboBoxListener());
        //suggestionComboBox.setSelectedIndex(-1);

        //add the suggestionLabel and suggestionComboBox to pane
        suggestionPanel.add(suggestionLabel, BorderLayout.CENTER);
        suggestionPanel.add(suggestionComboBox, BorderLayout.PAGE_END);
        JScrollPane sp = new JScrollPane(suggestionPanel);
        JScrollPane scrollPaneForSuggestion = new JScrollPane(suggestionPanel);

        //Create a split pane for the change log and the text area.
        JSplitPane splitPane = new JSplitPane(
                JSplitPane.VERTICAL_SPLIT,
                scrollPane, scrollPaneForSuggestion);
        splitPane.setOneTouchExpandable(true);
        splitPane.setResizeWeight(1.0);
        //Disables the moving of divider
        splitPane.setEnabled(false);

        //splitPane.setDividerLocation(splitPane.getHeight());
        //splitPane.setPreferredSize(new Dimension(640,400));

        //Create the status area.
        JPanel statusPane = new JPanel(new GridLayout(1, 1));
        CaretListenerLabel caretListenerLabel =
                new CaretListenerLabel("Status: Ready");
        statusPane.add(caretListenerLabel);

        //Create the toolbar
        JToolBar toolBar = new JToolBar();
        toolBar.setFloatable(false);
        toolBar.setRollover(true);

        openButton = new JButton("Open Snort Ruleset");
        toolBar.add(openButton);
        saveButton = new JButton("Save Ruleset");
        toolBar.add(saveButton);
        toolBar.addSeparator();
        aboutButton = new JButton("About");
        toolBar.add(aboutButton);

        //Add the components.
        getContentPane().add(toolBar, BorderLayout.PAGE_START);
        getContentPane().add(splitPane, BorderLayout.CENTER);
        getContentPane().add(statusPane, BorderLayout.PAGE_END);

        JMenu editMenu = createEditMenu();
        JMenu styleMenu = createStyleMenu();
        JMenuBar mb = new JMenuBar();
        mb.add(editMenu);
        mb.add(styleMenu);
        setJMenuBar(mb);


        //Put the initial text into the text pane.
        //initDocument();
        textPane.setCaretPosition(0);

        //Start watching for undoable edits and caret changes.
        textPane.addCaretListener(caretListenerLabel);

        SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                textPane.requestFocusInWindow();
            }
        });

    }

    //This listens for and reports caret movements.
    protected class CaretListenerLabel extends JLabel
            implements CaretListener {

        public CaretListenerLabel(String label) {
            super(label);
        }

        //Might not be invoked from the event dispatch thread.
        public void caretUpdate(CaretEvent e) {
            caretInvoke(e.getDot(), e.getMark());
        }

        protected void caretInvoke(final int dot, final int mark) {
            SwingUtilities.invokeLater(new Runnable() {

                public void run() {
                    try {
                        Rectangle caretCoords = textPane.modelToView(dot);
                                    //Find suggestion
                                        suggestionComboBox.removeAllItems();
                                        for (int i = 0; i < 5; i++) {
                                            suggestionComboBox.addItem(Integer.toString(i));
                                        }
                                        //suggestionComboBox.setSelectedItem(null);
                                        suggestionComboBox.setEnabled(true);
                                        suggestionLabel.setText("The following keywords are normally used as well. Click to use keyword(s). ");
                                        //changeLog.setText("The following keywords are suggested to be used together: " + str);
                    } catch (BadLocationException ble) {
                        setText("caret: text position: " + dot + newline);
                        System.out.println("Bad Location Exception");
                    }
                }
            });
        }
    }

    public class SuggestionComboBoxListener implements ItemListener {

        //public void actionPerformed(ActionEvent e) {
        public void itemStateChanged(ItemEvent e) {
            if (e.getStateChange() == ItemEvent.SELECTED) {
                JComboBox cb = (JComboBox)e.getSource();
                String selection = (String) cb.getSelectedItem();
                JOptionPane.showMessageDialog(null, "Item is selected", "Information", JOptionPane.INFORMATION_MESSAGE);
            }
        }
    }

    /*
     * Menu Creation
     */
    //Create the edit menu.
    protected JMenu createEditMenu() {
        JMenu menu = new JMenu("Edit");
        return menu;
    }

    protected JMenu createStyleMenu() {
        JMenu menu = new JMenu("Style");
        return menu;
    }

    private static void createAndShowGUI() {
        //Create and set up the window.
        final Temp frame = new Temp();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    //The standard main method.
    public static void main(String[] args) {
        //Schedule a job for the event dispatch thread:
        //creating and showing this application's GUI.
        SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                //Turn off metal's use of bold fonts
                UIManager.put("swing.boldMetal", Boolean.FALSE);
                createAndShowGUI();
            }
        });
    }
}
A: 

use

setSelectedItem(null);

Please try with ItemListener instead of ActionListener.

sreejith
Does not work. It still triggers the two initial JOptionPane
Alex Cheng
sorry actually... i didnt read the complete post
sreejith
please check with ItemListener
sreejith
@sreejith: Ah crap I deleted the ItemListener code I tried just now. I'll try again. EDIT: Nope, didn't work.
Alex Cheng
+1  A: 

You need to remove the ItemListener before you make any changes to the combo-box and add it back when you are done.

Something like this:

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;

import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;

public class Suggestions {

    private JFrame frame;
    private JTextPane textPane;
    private JComboBox suggestionComboBox;
    private SuggestionComboBoxListener selectionListener;

    public Suggestions() {
        frame = new JFrame("Snort Ruleset IDE");

        textPane = new JTextPane();
        textPane.setCaretPosition(0);
        textPane.setMargin(new Insets(5, 5, 5, 5));
        textPane.addCaretListener(new SuggestionCaretListener());
        JScrollPane textEntryScrollPane = new JScrollPane(textPane);
        textEntryScrollPane.setPreferredSize(new Dimension(300, 400));

        selectionListener = new SuggestionComboBoxListener(frame);
        suggestionComboBox = new JComboBox();
        suggestionComboBox.setEditable(false);
        suggestionComboBox.setPreferredSize(new Dimension(25, 25));
        suggestionComboBox.addItemListener(selectionListener);

        JPanel suggestionPanel = new JPanel(new BorderLayout());
        suggestionPanel.add(suggestionComboBox, BorderLayout.PAGE_END);

        frame.getContentPane().add(textEntryScrollPane, BorderLayout.NORTH);
        frame.getContentPane().add(suggestionPanel, BorderLayout.SOUTH);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }

    private final class SuggestionCaretListener implements CaretListener {
        @Override
        public void caretUpdate(CaretEvent e) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    generateSuggestions();
                }
            });
        }
    }

    public static final class SuggestionComboBoxListener implements ItemListener {
        Component parent;
        public SuggestionComboBoxListener(Component parent) {
            this.parent = parent;
        }
        public void itemStateChanged(ItemEvent e) {
            if (e.getStateChange() == ItemEvent.SELECTED) {
                 JComboBox cb = (JComboBox) e.getSource();
                 String selection = (String) cb.getSelectedItem();
                 JOptionPane.showMessageDialog(parent, "The selected item is: " + selection, "Information",
                 JOptionPane.INFORMATION_MESSAGE);
            }
        }
    }

    void generateSuggestions() {
        suggestionComboBox.removeItemListener(selectionListener);
        suggestionComboBox.removeAllItems();
        for (int i = 0; i < 5; i++) {
            suggestionComboBox.addItem(Integer.toString(i));
        }
        suggestionComboBox.setEnabled(true);
        suggestionComboBox.addItemListener(selectionListener);
    }

    public static void main(String[] args) {
        new Suggestions();
    }
}

BTW, what you posted is not an SSCCE it is a dump of your code. An SSCCE should only have enough code to reproduce the issue you are experiencing.

Rulmeq
I'll try your code, thanks. I tried cutting it down further, it was originally 1k lines of code.
Alex Cheng
You can add a call to setSelectedIndex(-1) to not have any selection when it's created if that's what you want. I wasn't trying to provide you with a complete solution, just something to make you think about the code.
Rulmeq
I understand, you don't want to spoonfeed me. But it is really interesting that I have to remove the listener first and add it back again after I add the elements.
Alex Cheng
If you stick a breakpoint just after the if() in the itemStateChanged method, and look at the stack trace, you will see that the addItem() method on JComboBox() calls the addElement(Object) method on DefaultcomboBoxModel, and in there you will see why this event is being fired.
Rulmeq