简体   繁体   中英

JComboBox not showing arrow

I have been searching this site and google for a solution to my problem, and I can't find anything. I think it's supposed to just work; however, it doesn't. The arrow icon for my JComboBox doesn't show up, and I can't find anywhere to set its visibility to true.

Here's my code:

public class Driver implements ActionListener {

private JTextField userIDField;
private JTextField[] documentIDField;
private JComboBox repository, environment;
private JButton close, clear, submit;
private JFrame window;

    public Driver()
    {
    window = makeWindow();
    makeContents(window);
    window.repaint();
    }

    private JFrame makeWindow()
    {
    JFrame window = new JFrame("");
    window.setSize(500,300);
    window.setLocation(50,50);
    window.getContentPane().setLayout(null);
    window.setResizable(false);
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.setVisible(true);

    return window;
    }

    private void makeContents(JFrame w)
    {
    makeDropDowns(w);
    w.repaint();
    }

    private void makeDropDowns(JFrame w)
    {       
    String[] repositoryArray = {"Click to select", "NSA", "Finance", "Test"};
    repository = new JComboBox(repositoryArray);
    repository.setSelectedIndex(0);
    repository.addActionListener(this);
    repository.setSize(150,20);
    repository.setLocation(175,165);
    repository.setEditable(false);
    w.add(repository);

    String[] environmentArray = {"Click to select", "Dev", "Test", "Qual"};
    environment = new JComboBox(environmentArray);
    environment.setSelectedIndex(0);
    environment.addActionListener(this);
    environment.setSize(150,20);
    environment.setLocation(175,195);
    //environment.setEditable(false);
    w.add(environment,0);
}

    public void actionPerformed(ActionEvent e) 
    {

    String repositoryID = "null", environmentID = "null";

    if (e.getSource() == repository)
        {
        repositoryID = (String)repository.getSelectedItem();
        }

    if(e.getSource() == environment)
        {
        environmentID = (String)environment.getSelectedItem();
        }
    }
}

Here's a link to a picture of the problem:

图片

If anyone could help that would be awesome.

It doesn't appear to be the issue you were suffering from, but I found this post due to the same resulting issue of the arrow disappearing.

In my case it was due to me mistakenly using .removeAll() on the JComboBox rather than .removeAllItems() when I was attempting to empty and then reuse the JComboBox after a refresh of the data I was using. Just thought I'd include it as an answer in case someone else comes across this thread for similar reasons.

The code you show works, but it looks like you're fighting the enclosing container's default layout . Here, ComboTest is a JPanel which defaults to FlowLayout .

Addendum: In general, do not use absolute positioning , as shown in your update . I've changed the example to use GridLayout ; comment out the setLayout() call to see the default, FlowLayout .

在此输入图像描述

import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;

/**
* @see https://stackoverflow.com/a/10824504/230513
*/
public class ComboTest extends JPanel {

    private JComboBox repository = createCombo(new String[]{
        "Click to select", "NSA", "Finance", "Test"});
    private JComboBox environment = createCombo(new String[]{
        "Click to select", "Dev", "Test", "Qual"});

    public ComboTest() {
        this.setLayout(new GridLayout(0, 1));
        this.add(repository);
        this.add(environment);
    }

    private JComboBox createCombo(String[] data) {
        final JComboBox combo = new JComboBox(data);
        combo.setSelectedIndex(1);
        combo.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println(e.getActionCommand()
                    + ": " + combo.getSelectedItem().toString());
            }
        });
        return combo;
    }

    private void display() {
        JFrame f = new JFrame("ComboTest");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(this);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new ComboTest().display();
            }
        });
    }
}

I had the same issue. I fixed it by revalidating and repainting the panel with the following code :

myPanel.revalidate();
myPanel.repaint();

Maybe a little late, but for those who are still looking for an easy and fail-safe way to use the JComboBox can use this:

public class FixedJComboBox<E>
        extends JComboBox<E> {
    // Copied constructors
    public FixedJComboBox() {
        super();
    }
    public FixedJComboBox(ComboBoxModel<E> aModel) {
        super(aModel);
    }
    public FixedJComboBox(E[] items) {
        super(items);
    }
    public FixedJComboBox(Vector<E> items) {
        super(items);
    }

    @Override
    public void setBounds(int x, int y, int width, int height) {
        super.setBounds(x, y, width, height);

        // The arrow is the first (and only) component
        // that is added by default
        Component[] comps = getComponents();
        if (comps != null && comps.length >= 1) {
            Component arrow = comps[0];
            // 20 is the default width of the arrow (for me at least)
            arrow.setSize(20, height);
            arrow.setLocation(width - arrow.getWidth(), 0);
        }
    }
}

As described here , the bug is caused by incorrectly setting both the location and the size of the arrow to (0,0) , followed by some repainting issues. By simply overriding the setBounds() function, the arrow is always corrected after the UI/layout manager has wrongly updated the arrow.

Also, since new components are added after the old ones (ie higher index), the arrow will always be at the first element in the array (assuming you don't remove and re-add the arrow).

The disadvantage is of this class is that the width of the arrow is now determined by a constant instead of the UI/layout manager.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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