首页 > 解决方案 > 编辑 JComboBox 中的选定项目

问题描述

我的目标是创建一个长度由另一个组件控制的列表,其中每个项目的值都可以编辑。

我的尝试使用具有一定数量元素的可编辑 JComboBox。但是,在我下面的代码中,所选索引不断更改为 -1,这不允许我修改该项目。有没有办法使用 JComboBox 选择和编辑项目?

//cb is a JComboBox with elements of type ComboItem. idx is defined elsewhere.
cb.addItemListener(new ItemListener() {
    @SuppressWarnings("unchecked")
    @Override
    public void itemStateChanged(ItemEvent e) {
        if(e.getStateChange() == ItemEvent.SELECTED)
            idx = ((JComboBox<ComboItem>) e.getSource()).getSelectedIndex();
        System.out.println("idx:"+idx);
    }
});
//Pressing enter should commit changes.
cb.getEditor().getEditorComponent().addKeyListener(new KeyAdapter() {
    @Override
    public void keyReleased(KeyEvent e) {
        if(e.getKeyChar() == KeyEvent.VK_ENTER) {
            String parse = ((JTextComponent) cb.getEditor().getEditorComponent()).getText();
            parse = parse.substring(parse.lastIndexOf(":")+1).replaceAll("[^0-9]+", ""); //Processes edits.
            cb.getItemAt(idx).change("Layer "+idx, Integer.parseInt(parse)); //This method should change the
            System.out.println("selected item:"+cb.getSelectedItem());      // data for each item.
        }
    }
});
//Editing the text in the JComboBox and pressing the enter key should update the selected item.

JComboBox 不是必需的,因此如果它是此任务的更好选择,请随意建议不同的组件。

标签: javaswingjcombobox

解决方案


经过一天的反复试验,我终于提出了一个可行的解决方案。我没有使用JComboBox可能不是为执行所需任务而设计的 a ,而是制作了 a ,每次按下按钮时都会JScrollPane添加一个子项。JPanel每个面板都有一个可以自定义的文本字段对象和一个删除它的按钮。就我而言,我添加了一个DocumentFilter允许正 < 5 位整数的值。

我无法弄清楚如何在滚动条出现之前删除添加的面板之间的间距,所以如果你有一个解决方案,请评论一个解决方案。另外,如果还有其他可以改进的地方,也请评论这些建议。

滚动面板

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ScrollPaneConstants;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;
import javax.swing.JLabel;

@SuppressWarnings("serial")
public class TestScrollPane extends JPanel {

    private int w,h;
    private JPanel content;
    private JScrollPane scroll;
    private JButton add;
    private JLabel getTextLabel;
    private JButton getTextBtn;

    /**
     * Create the panel.
     */
    public TestScrollPane(int width, int height) {
        setLayout(null);

        w = width; h = height;

        scroll = new JScrollPane();
        scroll.setBounds(0, 0, w, h);
        scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        add(scroll);

        content = new JPanel();
        scroll.setViewportView(content);
        content.setLayout(new BoxLayout(content, BoxLayout.Y_AXIS));

        add = new JButton("+");
        add.setBounds(0, h, 89, 23);
        add(add);

        getTextLabel = new JLabel("");
        getTextLabel.setBounds(10, 425, 215, 14);
        add(getTextLabel);

        getTextBtn = new JButton("Get Text");
        getTextBtn.setBounds(225, 425, 215, 14);
        getTextBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String a[] = getText(),
                       b = "";
                b += "[";
                for(int i = 0; i < a.length - 1; i++)
                    b += a[i]+", ";
                b += a[a.length-1]+"]";
                System.out.println(b);
                getTextLabel.setText(b);
            }
        });
        add(getTextBtn);

        add.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("adding "+content.getComponentCount());
                content.add(new ScrollItem(content.getComponentCount()));
                validate();
                repaint();
            }
        });
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(w, h);
    }

    public String[] getText() {
        String out[] = new String[content.getComponentCount()],s;
        for(int i = 0; i < out.length; i++)
            out[i] = (s = ((ScrollItem) content.getComponent(i)).out) == null ? "0" : s;
        return out;
    }

    private class ScrollItem extends JPanel {

        private JTextField text;
        private JButton del;
        private int idx;
        private String out;

        public ScrollItem(int id) {
            idx = id;
            setBounds(0, idx*20, w-5, 20);
            setLayout(null);
            text = new JTextField();
            text.setBounds(0, 0, (w-5)*3/4, 20);
            text.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    out = text.getText();
                }
            });

            AbstractDocument d = (AbstractDocument) text.getDocument();
            d.setDocumentFilter(new TextFilter(4));

            del = new JButton("X");
            del.setBounds((w-5)*3/4, 0, (w-5)/4, 20);
            del.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    content.remove(idx);
                    for(int i = idx; i < content.getComponentCount(); i++)
                        ((ScrollItem) content.getComponent(i)).moveUp();
                    content.validate();
                    content.repaint();
                    System.out.println("Removed "+idx);
                }
            });
            add(text);
            add(del);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(w-5, 20);
        }

        public void moveUp() {
            idx--;
            content.validate();
            content.repaint();
        }
    }

    private class TextFilter extends DocumentFilter {
        private int max;

        public TextFilter(int maxChars) {
            max = maxChars;
        }

        @Override
        public void insertString(FilterBypass fb, int offs, String str, AttributeSet a) throws BadLocationException {
            System.out.println("insert");
            if ((fb.getDocument().getLength() + str.length()) <= max && str.matches("\\d+"))
                super.insertString(fb, offs, str, a);
            else
                showError("Length: "+((fb.getDocument().getLength() + str.length()) <= max)+" | Text: "+str.matches("\\d+")+" | Str: "+str);
        }

        @Override
        public void replace(FilterBypass fb, int offs, int length, String str, AttributeSet a) throws BadLocationException {
            System.out.println("replace");
            if ((fb.getDocument().getLength() + str.length() - length) <= max && str.matches("\\d+"))
                super.replace(fb, offs, length, str, a);
            else
                showError("Length: "+((fb.getDocument().getLength() + str.length() - length) <= max)+" | Text: "+str.matches("\\d+")+" | Str: "+str);
        }

        private void showError(String cause) {
            JOptionPane.showMessageDialog(null, cause);
        }
    }
}

测试窗口

import java.awt.EventQueue;
import javax.swing.JFrame;

public class TestWindow {
    private JFrame frame;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    TestWindow window = new TestWindow();
                    window.frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public TestWindow() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        frame = new JFrame();
        frame.setBounds(100, 100, 435, 500);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new TestScrollPane(430, 247));
    }
}

推荐阅读