将 ComboBoxEditor 接口与 Custom JComponent 一起使用,并允许编辑和显示 List

QA_Col

我正在检查文档。

...我正在尝试使用我的自定义 ComboBox 实现接口ComboBoxEditor

这是我的完整代码...

我哈瓦一个JPanelJComponents...

class ThePanel extends JPanel {

  private Font intFont = new Font("Monospaced", Font.PLAIN, 8);

  private final JToggleButton jtbEnabled = new JToggleButton();
  private final JToggleButton jtbDefaultOperation = new JToggleButton();
  private final JTextField jtfText = new JTextField("", 0);

  private final JPanel jpThePanel = new JPanel();

  public ThePanel(Font extFont) {
    this(new TheModel(), extFont);
  }

  public ThePanel(TheModel data, Font extFont) {
    super();
    intFont = extFont;
    initEnabled();
    initDefaultOperation();
    initText();
    setData(data);

    jpThePanel.setLayout(new BoxLayout(jpThePanel, BoxLayout.LINE_AXIS));
    jpThePanel.add(Box.createRigidArea(new Dimension(2, 0)));
    jpThePanel.add(jtbEnabled);
    jpThePanel.add(jtbDefaultOperation);
    jpThePanel.add(jtfText);
    jpThePanel.add(Box.createRigidArea(new Dimension(2, 0)));
    init();
  }

  private void init() {
    setFont(intFont);
    setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
    setBackground(new Color(0, 0, 0, 0/*64*/));
    add(jpThePanel);
    Dimension d = getMinimumSize();
    setSize(d);
    setPreferredSize(d);
    setMaximumSize(d);
    setSize(d);
  }

  private void initEnabled() {
    jtbEnabled.setFont(intFont);
    jtbEnabled.setIcon(new ImageIcon(getClass().getResource("Unselected.png")));
    jtbEnabled.setSelectedIcon(new ImageIcon(getClass().getResource("Selected.png")));
  }

  private void initDefaultOperation() {
    jtbDefaultOperation.setFont(intFont);
    jtbDefaultOperation.setIcon(new ImageIcon(getClass().getResource("Insert.png")));
    jtbDefaultOperation.setSelectedIcon(new ImageIcon(getClass().getResource("Extract.png")));
    jtbDefaultOperation.setDisabledIcon(new ImageIcon(getClass().getResource("DisabledInsert.png")));
    jtbDefaultOperation.setDisabledSelectedIcon(new ImageIcon(getClass().getResource("DisabledExtract.png")));
  }

  private void initText() {
    jtfText.setFont(intFont);
  }

  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.selectAll();
  }

}

现在,我有其内部组件的模型数据......

class TheModel {

  private Boolean enabled = true;
  private Boolean defaultOperation = true;
  private String text = "";

  public TheModel() {
    this("");
  }

  public TheModel(String text) {
    this(true, text);
  }

  public TheModel(Boolean defaultOperation, String text) {
    this(true, defaultOperation, 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 + '}';
  }

}

我想ThePanel在 a 中使用我的自定义组件 ( )根据文档JComboBox操作内部元素JToggleButtons 和JTextField...我需要实现ComboBoxEditor 接口注: ListCellRenderer接口是试图展示列表...因为implementng仅ComboBoxEditor是行不通的。

class TheComboBoxEditor implements ComboBoxEditor, ListCellRenderer {

  protected ThePanel editor;
  private final EventListenerList listenerList = new EventListenerList();

  public TheComboBoxEditor(Font extFont) {
    editor = new ThePanel(extFont);
  }

  private void fireActionEvent(ActionEvent evt) {
    for (ActionListener al : listenerList.getListeners(ActionListener.class)) {
      al.actionPerformed(evt);
    }
  }

  @Override
  public void addActionListener(ActionListener l) {
    listenerList.add(ActionListener.class, l);
  }

  @Override
  public void removeActionListener(ActionListener l) {
    listenerList.remove(ActionListener.class, l);
  }

  @Override
  public void selectAll() {
    editor.selectAll();
    editor.requestFocus();
  }

  @Override
  public Object getItem() {
    return editor.getData();
  }

  @Override
  public void setItem(Object anObject) {
    if (anObject != null) {
      if (anObject instanceof TheModel) {
        editor.setData((TheModel) anObject);
      }
      if (anObject instanceof String) {
        editor.setData(new TheModel(anObject.toString()));
      }
    } else {
      editor.setData(new TheModel());
    }
  }

  @Override
  public Component getEditorComponent() {
    return editor;
  }

  @Override
  public Component getListCellRendererComponent(JList list, Object value,
      int index, boolean isSelected, boolean cellHasFocus) {
    TheModel data = (TheModel) value;
    editor.setData(data);
    return editor;
  }

}

现在,使用我的TheComboBoxEditor 类的一个例子

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

public class ExampleComboBoxEditor extends JFrame {

  public ExampleComboBoxEditor() {
    TheModel items[] = {
      new TheModel(true, true, "True, True"),
      new TheModel(true, false, "True, False"),
      new TheModel(false, true, "False, True"),
      new TheModel(false, false, "False, False")};

    String strings[] = {
      "True, True", "True, False", "False, True", "False, False"};

    JComboBox internalComboBox = new JComboBox(items);
    internalComboBox.setEditable(true);
    internalComboBox.setEditor(new TheComboBoxEditor(this.getFont()));
    internalComboBox.setMaximumRowCount(4);
    internalComboBox.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        System.out.println("You chose " + ((JComboBox) e.getSource()).getSelectedItem() + "!");
      }
    });

    JComboBox stringsComboBox = new JComboBox(strings);
    stringsComboBox.setEditable(true);
    stringsComboBox.setMaximumRowCount(4);
    stringsComboBox.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        System.out.println("You chose " + ((JComboBox) e.getSource()).getSelectedItem() + "!");
      }
    });

    JPanel outer = new JPanel();
    outer.add(internalComboBox);
    outer.add(stringsComboBox);
    add(outer);
    setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
  }

  public static void main(String[] args) {
    ExampleComboBoxEditor app = new ExampleComboBoxEditor();
    app.setSize(840, 240);
    app.setVisible(true);
  }
}

现在,我有我的疑问(对我来说这些方法的目标并不明确)......

1.当我重写selectAll()方法时我必须做什么?

2. 那么,我不仅有一个JTextField组件,还有两个组件JToggleButton有哪些建议addActionListener(ActionListener l)removeActionListener(ActionListener l)方法?

我正在检查这个例子...... http://www.java2s.com/Tutorials/Java/Swing_How_to/JComboBox/Add_JCheckBox_components_to_JComboBox.htm

在此处输入图片说明 在此处输入图片说明

如您所见,列表显示...

现在,在我的例子中......

在此处输入图片说明 在此处输入图片说明

3. 我看不到我的组件列表正确显示。

4. 我无法编辑我的jtfText,jtbEnabledjtbDefaultOperation组件(永久存储状态/属性)。

编辑

根据aterai的响应,我更改了保留原始TheModel的 Index porpouse 现在,我想知道不利的一面。

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;

/*
//https://stackoverflow.com/posts/53046908/revisions

javac -Xlint:unchecked -Xlint:deprecation -encoding utf8 -d /Users/bz/Documentos/Java/classes /Users/jose/Documentos/Java/ExampleComboBoxEditorNOIndex.java
java -cp /Users/bz/Documentos/Java/classes ExampleComboBoxEditorNOIndex &

*/

public class ExampleComboBoxEditorNOIndex  {

  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<TheModel> internalComboBox = new JComboBox<>();
    internalComboBox.setModel(new InternalComboBoxModel<>(items));
    internalComboBox.setEditable(true);
    internalComboBox.setEditor(new TheComboBoxEditor(internalComboBox.getFont()));
    internalComboBox.setRenderer(new TheComboBoxRenderer<>(internalComboBox.getFont()));
    internalComboBox.setMaximumRowCount(4);

    InternalComboBoxModel internalComboBoxModel  = (InternalComboBoxModel)internalComboBox.getModel();
    internalComboBox.addItemListener(e -> {
      if (e.getStateChange() == ItemEvent.SELECTED) {
        JComboBox combo = ((JComboBox) e.getSource());
        int lastValidIndex = combo.getSelectedIndex();
        if (lastValidIndex > -1) {
          internalComboBoxModel.setLastValidIndex(lastValidIndex);
          System.out.println("You chose " + combo.getSelectedItem() 
          + ", in position:" + lastValidIndex + "!");
        }
        combo.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 ExampleComboBoxEditorNOIndex().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<E extends TheModel> implements ListCellRenderer<E> {
  protected ThePanel renderer;
  private int lastSelected = -1;
  public TheComboBoxRenderer(Font extFont) {
    renderer = new ThePanel(new TheModel(/*-1, */false, false, ""), extFont);
  }
  @Override
  public Component getListCellRendererComponent(JList<? extends E> list, E value,
      int index, boolean isSelected, boolean cellHasFocus) {
    if (isSelected) {
      this.lastSelected = index;
      //System.out.println("value: " + value + ", index: " + index + ", isSelected:" + isSelected);
    }
    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() {
  //  System.out.println("getItem(): " + editor.getData());
    return editor.getData();
  }
  @Override
  public void setItem(Object anObject) {
  //  System.out.println("setItem: " + 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("TheComboBoxEditor.addActionListener: " + l.getClass().getName());
    editor.addActionListener(l);
  }
  @Override
  public void removeActionListener(ActionListener l) {
  //  System.out.println("TheComboBoxEditor.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;
        if (combo.getItemCount() > 0) {
          InternalComboBoxModel internalComboBoxModel = (InternalComboBoxModel) combo.getModel();
          int lastValidIndex = internalComboBoxModel.getLastValidIndex();
      //  TheModel o = (TheModel) combo.getSelectedItem();
      //  int idx = positionItemList(getComboBoxItems(combo), o);//int idx = model.getIndexOf(data);
          TheModel rd = (TheModel) combo.getItemAt(lastValidIndex);//(TheModel) combo.getItemAt(idx);
          boolean b = ((JCheckBox) e.getSource()).isSelected();
          rd.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;
        if (combo.getItemCount() > 0) {
          InternalComboBoxModel internalComboBoxModel = (InternalComboBoxModel) combo.getModel();
          int lastValidIndex = internalComboBoxModel.getLastValidIndex();
      //  TheModel o = (TheModel) combo.getSelectedItem();
      //  int idx = positionItemList(getComboBoxItems(combo), o);//int idx = model.getIndexOf(data);
          TheModel rd = (TheModel) combo.getItemAt(lastValidIndex);//(TheModel) combo.getItemAt(idx);
          rd.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;
        if (combo.getItemCount() > 0) {
          InternalComboBoxModel internalComboBoxModel = (InternalComboBoxModel) combo.getModel();
          int lastValidIndex = internalComboBoxModel.getLastValidIndex();
      //  TheModel o = (TheModel) combo.getSelectedItem();
      //  int idx = positionItemList(getComboBoxItems(combo), o);//int idx = model.getIndexOf(data);
          TheModel rd = (TheModel) combo.getItemAt(lastValidIndex);//(TheModel) combo.getItemAt(idx);
          rd.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)));
  }

  private <T> java.util.List<T> getComboBoxItems(JComboBox comboBox) {
    if (comboBox != null) {
      java.util.List<String> list = new ArrayList<>();
      for (int i = 0; i < comboBox.getItemCount(); i++) {
        list.add(comboBox.getItemAt(i).toString());
      }
      return (java.util.List<T>) list;//(ArrayList<T>)list; // list; // (List<T>)list;
    }
    return null;
  }

  private Integer positionItemList(java.util.List list, Object object) {
    Integer position = -1;
    Integer last = list.size();
    for (int pos = 0; pos < last; pos++) {
      if (list.get(pos).toString().equals(object.toString())) {
        position = pos;
      }
    }
    return position;
  }

  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);
  }

}

class InternalComboBoxModel<E extends TheModel> extends DefaultComboBoxModel {
  private Integer lastValidIndex = 0;

  InternalComboBoxModel(final E items[]) {
    super(items);
  }

  InternalComboBoxModel(Vector<E> v) {
    super(v);
  }

  public Integer getLastValidIndex() {
    return lastValidIndex;
  }

  public void setLastValidIndex(Integer lastValidIndex) {
    this.lastValidIndex = lastValidIndex;
  }

}

如果可能的话,我想解决所有警告。

MacBook-Air:Users bz$ javac -Xlint:unchecked -Xlint:deprecation -encoding utf8 -d /Users/bz/Documentos/Java/classes /Users/bz/Documentos/Java/ExampleComboBoxEditorNOIndex.java
/Users/bz/Documentos/Java/ExampleComboBoxEditorNOIndex.java:24: warning: [unchecked] unchecked method invocation: method setModel in class JComboBox is applied to given types
    internalComboBox.setModel(new InternalComboBoxModel<>(items));
                             ^
  required: ComboBoxModel<E>
  found: InternalComboBoxModel<TheModel>
  where E is a type-variable:
    E extends Object declared in class JComboBox
/Users/bz/Documentos/Java/ExampleComboBoxEditorNOIndex.java:24: warning: [unchecked] unchecked conversion
    internalComboBox.setModel(new InternalComboBoxModel<>(items));
                              ^
  required: ComboBoxModel<E>
  found:    InternalComboBoxModel<TheModel>
  where E is a type-variable:
    E extends Object declared in class JComboBox
/Users/bz/Documentos/Java/ExampleComboBoxEditorNOIndex.java:257: warning: [unchecked] unchecked cast
      return (java.util.List<T>) list;//(ArrayList<T>)list; // list; // (List<T>)list;
                                 ^
  required: List<T>
  found:    List<String>
  where T is a type-variable:
    T extends Object declared in method <T>getComboBoxItems(JComboBox)
/Users/bz/Documentos/Java/ExampleComboBoxEditorNOIndex.java:310: warning: [unchecked] unchecked call to DefaultComboBoxModel(E[]) as a member of the raw type DefaultComboBoxModel
    super(items);
         ^
  where E is a type-variable:
    E extends Object declared in class DefaultComboBoxModel
/Users/bz/Documentos/Java/ExampleComboBoxEditorNOIndex.java:314: warning: [unchecked] unchecked call to DefaultComboBoxModel(Vector<E>) as a member of the raw type DefaultComboBoxModel
    super(v);
         ^
  where E is a type-variable:
    E extends Object declared in class DefaultComboBoxModel
5 warnings
MacBook-Air:Users bz$ 
阿特莱

显示列表

您需要添加一个单元格渲染器。

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

允许编辑

需要为组合编辑器的每个组件添加一个动作监听器。

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());
  }
});

当我覆盖 selectAll() 方法时,我必须做什么?

不要将焦点移到 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<TheModel> 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<E extends TheModel> implements ListCellRenderer<E> {
  protected ThePanel renderer;
  public TheComboBoxRenderer(Font extFont) {
    renderer = new ThePanel(new TheModel(-1, false, false, ""), extFont);
  }
  @Override
  public Component getListCellRendererComponent(JList<? extends E> 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<TheModel> 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<E extends TheModel> implements ListCellRenderer<E> {
  protected ThePanel renderer;
  public TheComboBoxRenderer(Font extFont) {
    renderer = new ThePanel(new TheModel(false, false, ""), extFont);
  }
  @Override
  public Component getListCellRendererComponent(JList<? extends E> 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);
  }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

将接口与枚举一起使用

来自分类Dev

将接口与方法签名一起使用

来自分类Dev

将秒表方法与soap接口一起使用

来自分类Dev

将MouseListener与JComponent关联

来自分类Dev

将接口派生的类与NEST和ElasticSearch一起使用

来自分类Dev

将JComponent的宽度和高度设置为实例变量

来自分类Dev

将JComponent作为图像发送

来自分类Dev

将非虚拟接口和多级继承结合在一起

来自分类Dev

将非虚拟接口和多级继承结合在一起

来自分类Dev

是否可以将Custom EventArgs与SystemEvents一起使用?

来自分类Dev

如何使用JComponent

来自分类Dev

将 List 接口转换为自定义 List 类

来自分类Dev

如何将Guice AssistedInject与接口的多个实现一起使用?

来自分类Dev

当T是接口时,如何将IFixture.Build <T>()与AutoMoqCustomization一起使用?

来自分类Dev

将接口库与check_c_source_runs()或try_run()一起使用

来自分类Dev

如何将typescript接口属性与margin属性一起使用?

来自分类Dev

如何将Guice AssistedInject与接口的多个实现一起使用?

来自分类Dev

将.iloc与'list'对象一起使用

来自分类Dev

如何将JComponent添加到具有指定大小和位置的JFrame中?

来自分类Dev

将多个JComponent绘制到框架

来自分类Dev

JComponent不显示在JFrame中

来自分类Dev

使用Newtonsoft.Json,如何将SerializationBinder和CustomResolver一起反序列化抽象/接口类型?

来自分类Dev

使用接口作为List <T>的参数

来自分类Dev

使用派生接口中的 List 覆盖 IReadOnlyList

来自分类Dev

为什么不应该将两个集合接口一起实现?

来自分类Dev

在Scala中,如何将unapplySeq与模式匹配(例如List,开始模式和varargs参数)一起使用?

来自分类Dev

无法将List <SuperType>参数与List <SubType>一起使用

来自分类Dev

无法将List <SuperType>参数与List <SubType>一起使用

来自分类Dev

为什么MongoDB不再允许将$ set和$ unset与空文档一起使用?

Related 相关文章

  1. 1

    将接口与枚举一起使用

  2. 2

    将接口与方法签名一起使用

  3. 3

    将秒表方法与soap接口一起使用

  4. 4

    将MouseListener与JComponent关联

  5. 5

    将接口派生的类与NEST和ElasticSearch一起使用

  6. 6

    将JComponent的宽度和高度设置为实例变量

  7. 7

    将JComponent作为图像发送

  8. 8

    将非虚拟接口和多级继承结合在一起

  9. 9

    将非虚拟接口和多级继承结合在一起

  10. 10

    是否可以将Custom EventArgs与SystemEvents一起使用?

  11. 11

    如何使用JComponent

  12. 12

    将 List 接口转换为自定义 List 类

  13. 13

    如何将Guice AssistedInject与接口的多个实现一起使用?

  14. 14

    当T是接口时,如何将IFixture.Build <T>()与AutoMoqCustomization一起使用?

  15. 15

    将接口库与check_c_source_runs()或try_run()一起使用

  16. 16

    如何将typescript接口属性与margin属性一起使用?

  17. 17

    如何将Guice AssistedInject与接口的多个实现一起使用?

  18. 18

    将.iloc与'list'对象一起使用

  19. 19

    如何将JComponent添加到具有指定大小和位置的JFrame中?

  20. 20

    将多个JComponent绘制到框架

  21. 21

    JComponent不显示在JFrame中

  22. 22

    使用Newtonsoft.Json,如何将SerializationBinder和CustomResolver一起反序列化抽象/接口类型?

  23. 23

    使用接口作为List <T>的参数

  24. 24

    使用派生接口中的 List 覆盖 IReadOnlyList

  25. 25

    为什么不应该将两个集合接口一起实现?

  26. 26

    在Scala中,如何将unapplySeq与模式匹配(例如List,开始模式和varargs参数)一起使用?

  27. 27

    无法将List <SuperType>参数与List <SubType>一起使用

  28. 28

    无法将List <SuperType>参数与List <SubType>一起使用

  29. 29

    为什么MongoDB不再允许将$ set和$ unset与空文档一起使用?

热门标签

归档