Using the ComboBoxEditor interface with Custom JComponent, and allow edit, and display the List

前端 未结 1 401
再見小時候
再見小時候 2021-01-27 12:07

I was checking the documentation.

  • https://docs.oracle.com/javase/tutorial/uiswing/components/combobox.html

  • https://alvinalexander.com/java/jware

1条回答
  •  [愿得一人]
    2021-01-27 12:32

    display the List

    You need to add a cell renderer.

    internalComboBox.setRenderer(new TheComboBoxRenderer<>(font));
    

    allow edit

    Need to add an action listener to each component of the combo editor.

    editor.jtbDefaultOperation.addActionListener(e -> {
      System.out.println("jtbDefaultOperation" + editor.getData().index);
      Container c = SwingUtilities.getAncestorOfClass(JComboBox.class, editor);
      if (c instanceof JComboBox) {
        JComboBox combo = (JComboBox) c;
        TheModel o = (TheModel) combo.getItemAt(editor.getData().index);
        o.setDefaultOperation(((JCheckBox) e.getSource()).isSelected());
      }
    });
    

    When I override the selectAll() method what I have to do?

    Do not move the focus to the TheComboBoxEditor.

    internalComboBox.addItemListener(e -> {
      if (e.getStateChange() == ItemEvent.SELECTED) {
        System.out.println("You chose ...");
        ((JComboBox) e.getSource()).getEditor().selectAll();
      }
    });
    
    class TheComboBoxEditor implements ComboBoxEditor {
      @Override
      public void selectAll() {
        editor.selectAll();
        // editor.requestFocus(); // <-- The focus moves from JTextField(jtfText) to JPanel(ThePanel).
      }
    

    ExampleComboBoxEditor3.java

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.event.*;
    
    public class ExampleComboBoxEditor3 {
      public Component makeUI() {
        TheModel[] items = {
          new TheModel(0, true, true, "00000"),
          new TheModel(1, true, false, "11111"),
          new TheModel(2, false, true, "22222"),
          new TheModel(3, false, false, "33333")
        };
        JComboBox internalComboBox = new JComboBox<>(items);
        internalComboBox.setEditable(true);
        internalComboBox.setEditor(new TheComboBoxEditor(internalComboBox.getFont()));
        internalComboBox.setRenderer(new TheComboBoxRenderer<>(internalComboBox.getFont()));
        internalComboBox.setMaximumRowCount(4);
        // internalComboBox.addActionListener(e -> {
        //   System.out.println("You chose " + ((JComboBox) e.getSource()).getSelectedItem() + "!");
        // });
        internalComboBox.addItemListener(e -> {
          if (e.getStateChange() == ItemEvent.SELECTED) {
            System.out.println("You chose " + ((JComboBox) e.getSource()).getSelectedItem() + "!");
            ((JComboBox) e.getSource()).getEditor().selectAll();
          }
        });
    
        JPanel outer = new JPanel();
        outer.add(internalComboBox);
        outer.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0));
        return outer;
      }
      public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
          JFrame f = new JFrame();
          f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
          f.getContentPane().add(new ExampleComboBoxEditor3().makeUI());
          f.setSize(320, 240);
          f.setLocationRelativeTo(null);
          f.setVisible(true);
        });
      }
    }
    
    class TheModel {
      private Boolean enabled = true;
      private Boolean defaultOperation = true;
      private String text = "";
      public int index = -1;
    
      public TheModel(int idx, Boolean enabled, Boolean defaultOperation, String text) {
        this.enabled = enabled;
        this.defaultOperation = defaultOperation;
        this.text = text;
        this.index = idx;
      }
      public Boolean getEnabled() {
        return enabled;
      }
      public void setEnabled(Boolean enabled) {
        this.enabled = enabled;
      }
      public Boolean getDefaultOperation() {
        return defaultOperation;
      }
      public void setDefaultOperation(Boolean defaultOperation) {
        this.defaultOperation = defaultOperation;
      }
      public String getText() {
        return text;
      }
      public void setText(String text) {
        this.text = text;
      }
      @Override
      public String toString() {
        return "TheModel{" + "enabled=" + enabled + ", defaultOperation=" + defaultOperation
          + ", text=" + text + '}';
      }
    }
    
    class TheComboBoxRenderer implements ListCellRenderer {
      protected ThePanel renderer;
      public TheComboBoxRenderer(Font extFont) {
        renderer = new ThePanel(new TheModel(-1, false, false, ""), extFont);
      }
      @Override
      public Component getListCellRendererComponent(JList list, E value,
          int index, boolean isSelected, boolean cellHasFocus) {
        renderer.setData(value);
        renderer.setBackground(isSelected ? new Color(200, 200, 255) : Color.WHITE);
        return renderer;
      }
    }
    
    class TheComboBoxEditor implements ComboBoxEditor {
      protected ThePanel editor;
      public TheComboBoxEditor(Font extFont) {
        super();
        editor = new ThePanel(new TheModel(-1, false, false, ""), extFont);
        editor.setBorder(BorderFactory.createLineBorder(Color.GRAY));
      }
      @Override
      public void selectAll() {
        editor.selectAll();
        // editor.requestFocus(); // <-- The focus moves from jtfText to editor.
      }
      @Override
      public Object getItem() {
        return editor.getData();
      }
      @Override
      public void setItem(Object anObject) {
        if (anObject instanceof TheModel) {
          TheModel d = (TheModel) anObject;
          editor.setData(d);
        } else {
          editor.setData(new TheModel(-1, false, false, ""));
        }
      }
      @Override
      public Component getEditorComponent() {
        return editor;
      }
      @Override
      public void addActionListener(ActionListener l) {
        System.out.println("addActionListener: " + l.getClass().getName());
        editor.addActionListener(l);
      }
      @Override
      public void removeActionListener(ActionListener l) {
        System.out.println("removeActionListener: " + l.getClass().getName());
        editor.removeActionListener(l);
      }
    }
    
    class ThePanel extends JPanel {
      private Font intFont = new Font("Monospaced", Font.PLAIN, 8);
      // Since there is no Unselected.png etc,
      // use JCheckBox instead of JToggleButton instead.
      public final JCheckBox jtbEnabled = new JCheckBox();
      public final JCheckBox jtbDefaultOperation = new JCheckBox();
      public final JTextField jtfText = new JTextField("", 10);
      private TheModel data;
    
      public ThePanel(TheModel data, Font extFont) {
        super();
        this.data = data;
        setData(data);
    
        jtbEnabled.addActionListener(e -> {
          Container c = SwingUtilities.getAncestorOfClass(JComboBox.class, this);
          if (c instanceof JComboBox) {
            JComboBox combo = (JComboBox) c;
            TheModel o = (TheModel) combo.getItemAt(data.index);
            boolean b = ((JCheckBox) e.getSource()).isSelected();
            o.setEnabled(b);
            jtbDefaultOperation.setEnabled(b);
          }
        });
        jtbEnabled.setOpaque(false);
        jtbEnabled.setFocusable(false);
    
        jtbDefaultOperation.addActionListener(e -> {
          Container c = SwingUtilities.getAncestorOfClass(JComboBox.class, this);
          if (c instanceof JComboBox) {
            JComboBox combo = (JComboBox) c;
            TheModel o = (TheModel) combo.getItemAt(data.index);
            o.setDefaultOperation(((JCheckBox) e.getSource()).isSelected());
          }
        });
        jtbDefaultOperation.setOpaque(false);
        jtbDefaultOperation.setFocusable(false);
    
        jtfText.addActionListener(e -> {
          Container c = SwingUtilities.getAncestorOfClass(JComboBox.class, this);
          if (c instanceof JComboBox) {
            JComboBox combo = (JComboBox) c;
            TheModel o = (TheModel) combo.getItemAt(data.index);
            o.setText(((JTextField) e.getSource()).getText());
          }
        });
        jtfText.setBorder(BorderFactory.createEmptyBorder());
        jtfText.setOpaque(false);
    
        setOpaque(true);
        setBackground(Color.WHITE);
        setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
    
        add(Box.createRigidArea(new Dimension(2, 0)));
        add(jtbEnabled);
        add(jtbDefaultOperation);
        add(jtfText);
        add(Box.createRigidArea(new Dimension(2, 0)));
      }
    
      public TheModel getData() {
        return new TheModel(
            data.index,
            jtbEnabled.isSelected(),
            jtbDefaultOperation.isSelected(),
            jtfText.getText());
      }
    
      public void setData(TheModel data) {
        this.data.index = data.index;
        jtbEnabled.setSelected(data.getEnabled());
        jtbDefaultOperation.setEnabled(data.getEnabled());
        jtbDefaultOperation.setSelected(data.getDefaultOperation());
        jtfText.setText(data.getText());
      }
      public void selectAll() {
          jtfText.requestFocusInWindow();
          jtfText.selectAll();
      }
      public void addActionListener(ActionListener l) {
        jtfText.addActionListener(l);
        jtbEnabled.addActionListener(l);
        jtbDefaultOperation.addActionListener(l);
      }
      public void removeActionListener(ActionListener l) {
        jtfText.removeActionListener(l);
        jtbEnabled.removeActionListener(l);
        jtbDefaultOperation.removeActionListener(l);
      }
    }
    

    ExampleComboBoxEditor4.java

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.event.*;
    
    public class ExampleComboBoxEditor4 {
      public Component makeUI() {
        TheModel[] items = {
          new TheModel(true, true, "00000"),
          new TheModel(true, false, "11111"),
          new TheModel(false, true, "22222"),
          new TheModel(false, false, "33333")
        };
        JComboBox internalComboBox = new JComboBox<>(items);
        internalComboBox.setEditable(true);
        internalComboBox.setEditor(new TheComboBoxEditor(internalComboBox.getFont()));
        internalComboBox.setRenderer(new TheComboBoxRenderer<>(internalComboBox.getFont()));
        internalComboBox.setMaximumRowCount(4);
        // internalComboBox.addActionListener(e -> {
        //   System.out.println("You chose " + ((JComboBox) e.getSource()).getSelectedItem() + "!");
        // });
        internalComboBox.addItemListener(e -> {
          if (e.getStateChange() == ItemEvent.SELECTED) {
            System.out.println("You chose " + ((JComboBox) e.getSource()).getSelectedItem() + "!");
            ((JComboBox) e.getSource()).getEditor().selectAll();
          }
        });
    
        JPanel outer = new JPanel();
        outer.add(internalComboBox);
        outer.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0));
        return outer;
      }
      public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
          JFrame f = new JFrame();
          f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
          f.getContentPane().add(new ExampleComboBoxEditor4().makeUI());
          f.setSize(320, 240);
          f.setLocationRelativeTo(null);
          f.setVisible(true);
        });
      }
    }
    
    class TheModel {
      private Boolean enabled = true;
      private Boolean defaultOperation = true;
      private String text = "";
    
      public TheModel(Boolean enabled, Boolean defaultOperation, String text) {
        this.enabled = enabled;
        this.defaultOperation = defaultOperation;
        this.text = text;
      }
      public Boolean getEnabled() {
        return enabled;
      }
      public void setEnabled(Boolean enabled) {
        this.enabled = enabled;
      }
      public Boolean getDefaultOperation() {
        return defaultOperation;
      }
      public void setDefaultOperation(Boolean defaultOperation) {
        this.defaultOperation = defaultOperation;
      }
      public String getText() {
        return text;
      }
      public void setText(String text) {
        this.text = text;
      }
      @Override
      public String toString() {
        return "TheModel{" + "enabled=" + enabled + ", defaultOperation=" + defaultOperation
          + ", text=" + text + '}';
      }
    //   // TEST:
    //   @Override
    //   public boolean equals(Object obj) {
    //     if (obj instanceof TheModel) {
    //       return Objects.equals(text, ((TheModel) obj).getText());
    //     } else {
    //       return false;
    //     }
    //   }
    }
    
    class TheComboBoxRenderer implements ListCellRenderer {
      protected ThePanel renderer;
      public TheComboBoxRenderer(Font extFont) {
        renderer = new ThePanel(new TheModel(false, false, ""), extFont);
      }
      @Override
      public Component getListCellRendererComponent(JList list, E value,
          int index, boolean isSelected, boolean cellHasFocus) {
        renderer.setData(value);
        renderer.setBackground(isSelected ? new Color(200, 200, 255) : Color.WHITE);
        return renderer;
      }
    }
    
    class TheComboBoxEditor implements ComboBoxEditor {
      protected ThePanel editor;
      public TheComboBoxEditor(Font extFont) {
        super();
        editor = new ThePanel(new TheModel(false, false, ""), extFont);
        editor.setBorder(BorderFactory.createLineBorder(Color.GRAY));
      }
      @Override
      public void selectAll() {
        editor.selectAll();
        // editor.requestFocus(); // <-- The focus moves from jtfText to editor.
      }
      @Override
      public Object getItem() {
        return editor.getData();
      }
      @Override
      public void setItem(Object anObject) {
        EventQueue.invokeLater(() -> {
          Container c = SwingUtilities.getAncestorOfClass(JComboBox.class, getEditorComponent());
          if (c instanceof JComboBox) {
            JComboBox combo = (JComboBox) c;
            int idx = combo.getSelectedIndex();
            if (idx >= 0 && idx != editor.lastValidIndex) {
              System.out.println("setItem: " + idx);
              editor.lastValidIndex = idx;
            }
          }
        });
        if (anObject instanceof TheModel) {
          TheModel d = (TheModel) anObject;
          editor.setData(d);
        } else {
          editor.setData(new TheModel(false, false, ""));
        }
      }
      @Override
      public Component getEditorComponent() {
        return editor;
      }
      @Override
      public void addActionListener(ActionListener l) {
        editor.addActionListener(l);
      }
      @Override
      public void removeActionListener(ActionListener l) {
        editor.removeActionListener(l);
      }
    }
    
    class ThePanel extends JPanel {
      private Font intFont = new Font("Monospaced", Font.PLAIN, 8);
      // Since there is no Unselected.png etc,
      // use JCheckBox instead of JToggleButton instead.
      public final JCheckBox jtbEnabled = new JCheckBox();
      public final JCheckBox jtbDefaultOperation = new JCheckBox();
      public final JTextField jtfText = new JTextField("", 10);
      private TheModel data;
      public int lastValidIndex = -1;
    
      public ThePanel(TheModel data, Font extFont) {
        super();
        this.data = data;
        setData(data);
    
        jtbEnabled.addActionListener(e -> {
          Container c = SwingUtilities.getAncestorOfClass(JComboBox.class, this);
          if (c instanceof JComboBox) {
            JComboBox combo = (JComboBox) c;
            TheModel o = (TheModel) combo.getItemAt(lastValidIndex);
            boolean b = ((JCheckBox) e.getSource()).isSelected();
            o.setEnabled(b);
            jtbDefaultOperation.setEnabled(b);
            combo.setSelectedIndex(lastValidIndex);
          }
        });
        jtbEnabled.setOpaque(false);
        jtbEnabled.setFocusable(false);
    
        jtbDefaultOperation.addActionListener(e -> {
          Container c = SwingUtilities.getAncestorOfClass(JComboBox.class, this);
          if (c instanceof JComboBox) {
            JComboBox combo = (JComboBox) c;
            TheModel o = (TheModel) combo.getItemAt(lastValidIndex);
            o.setDefaultOperation(((JCheckBox) e.getSource()).isSelected());
            combo.setSelectedIndex(lastValidIndex);
          }
        });
        jtbDefaultOperation.setOpaque(false);
        jtbDefaultOperation.setFocusable(false);
    
        jtfText.addActionListener(e -> {
          Container c = SwingUtilities.getAncestorOfClass(JComboBox.class, this);
          if (c instanceof JComboBox) {
            JComboBox combo = (JComboBox) c;
            TheModel o = (TheModel) combo.getItemAt(lastValidIndex);
            o.setText(((JTextField) e.getSource()).getText());
            combo.setSelectedIndex(lastValidIndex);
          }
        });
        jtfText.setBorder(BorderFactory.createEmptyBorder());
        jtfText.setOpaque(false);
    
        setOpaque(true);
        setBackground(Color.WHITE);
        setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
    
        add(Box.createRigidArea(new Dimension(2, 0)));
        add(jtbEnabled);
        add(jtbDefaultOperation);
        add(jtfText);
        add(Box.createRigidArea(new Dimension(2, 0)));
      }
    
      public TheModel getData() {
        return new TheModel(
            jtbEnabled.isSelected(),
            jtbDefaultOperation.isSelected(),
            jtfText.getText());
      }
    
      public void setData(TheModel data) {
        jtbEnabled.setSelected(data.getEnabled());
        jtbDefaultOperation.setEnabled(data.getEnabled());
        jtbDefaultOperation.setSelected(data.getDefaultOperation());
        jtfText.setText(data.getText());
      }
      public void selectAll() {
        jtfText.requestFocusInWindow();
        jtfText.selectAll();
      }
      public void addActionListener(ActionListener l) {
        jtfText.addActionListener(l);
        jtbEnabled.addActionListener(l);
        jtbDefaultOperation.addActionListener(l);
      }
      public void removeActionListener(ActionListener l) {
        jtfText.removeActionListener(l);
        jtbEnabled.removeActionListener(l);
        jtbDefaultOperation.removeActionListener(l);
      }
    }
    

    0 讨论(0)
提交回复
热议问题