IDEA-162025 Unexpected focus-effect painting in ComboBox with custom JPanel-based...
[idea/community.git] / platform / util / src / com / intellij / util / ui / components / ComboBoxCompositeEditor.java
1 /*
2  * Copyright 2000-2016 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.intellij.util.ui.components;
17
18 import javax.swing.*;
19 import java.awt.*;
20 import java.awt.event.ActionListener;
21 import java.awt.event.FocusEvent;
22 import java.awt.event.FocusListener;
23
24 /**
25  * @author Denis Fokin
26  */
27
28 public class ComboBoxCompositeEditor extends JComponent implements ComboBoxEditor {
29
30   public interface EditorComponent {
31     void setItem(String anObject);
32     String getItem();
33     void selectAll();
34     void addActionListener(ActionListener l);
35     void removeActionListener(ActionListener l);
36     JComponent getDelegate();
37
38   }
39
40   private final EditorComponent[] myComponents;
41   private String myItem = null;
42   private int focusableComponentIndex;
43
44   public ComboBoxCompositeEditor(final JComponent ... components) {
45     assert components.length > 0;
46     setLayout(new GridLayout(1, 0));
47     setFocusable(false);
48     myComponents = new EditorComponent[components.length];
49
50     for (int i = 0; i < components.length; i ++) {
51       final int index = i;
52       myComponents[i] = new ComboBoxCompositeEditor.EditorComponent () {
53         public void setItem(String anObject) {
54           if (components[index] instanceof JTextField) {
55             JTextField component = (JTextField)components[index];
56             component.setText((anObject == null) ? "" : anObject);
57           }
58         }
59
60         public String getItem() {
61           if (components[index] instanceof JTextField) {
62             JTextField component = (JTextField)components[index];
63             return component.getText();
64           }
65           return "";
66         }
67
68         @Override
69         public void selectAll() {
70           if (components[index] instanceof JTextField) {
71             JTextField component = (JTextField)components[index];
72             component.selectAll();
73           }
74         }
75
76         @Override
77         public void addActionListener(ActionListener l) {
78           if (components[index] instanceof JTextField) {
79             JTextField component = (JTextField)components[index];
80             component.addActionListener(l);
81           }
82         }
83
84         @Override
85         public void removeActionListener(ActionListener l) {
86           if (components[index] instanceof JTextField) {
87             JTextField component = (JTextField)components[index];
88             component.removeActionListener(l);
89           }
90         }
91
92         @Override
93         public JComponent getDelegate() {
94           return components[index];
95         }
96       };
97     }
98
99     focusableComponentIndex = 0;
100     final JComponent component = myComponents[focusableComponentIndex].getDelegate();
101     component.setBorder(null);
102     component.addFocusListener(new FocusListener() {
103
104       Component parent = null;
105
106       @Override
107       public void focusGained(FocusEvent e) {
108         parent = component.getParent();
109         parent.repaint();
110       }
111
112       @Override
113       public void focusLost(FocusEvent e) {
114         parent.repaint();
115       }
116     });
117   }
118
119   @Override
120   public Component getEditorComponent() {
121     return myComponents[focusableComponentIndex].getDelegate();
122   }
123
124   @Override
125   public void setItem(Object anObject) {
126       myItem = (String)anObject;
127       for (EditorComponent editorComponent : myComponents) {
128         editorComponent.setItem(myItem);
129       }
130   }
131
132   @Override
133   public Object getItem() {
134     return myItem;
135   }
136
137   @Override
138   public void selectAll() {
139     myComponents[focusableComponentIndex].selectAll();
140   }
141
142   @Override
143   public void addActionListener(ActionListener l) {
144     for (EditorComponent editorComponent : myComponents) {
145       editorComponent.addActionListener(l);
146     }
147   }
148
149   @Override
150   public void removeActionListener(ActionListener l) {
151     for (EditorComponent editorComponent : myComponents) {
152       editorComponent.removeActionListener(l);
153     }
154   }
155
156   @Override
157   public void setFocusable(boolean focusable) {}
158
159   @Override
160   public boolean isFocusable() {
161     return false;
162   }
163 }