plough
7 years ago
4 changed files with 466 additions and 11 deletions
@ -0,0 +1,398 @@
|
||||
package com.fr.design.gui.ilist; |
||||
|
||||
import com.fr.base.Utils; |
||||
import com.fr.design.gui.itextfield.UITextField; |
||||
import com.fr.general.Inter; |
||||
import com.fr.general.NameObject; |
||||
import com.fr.stable.Nameable; |
||||
import com.fr.stable.StringUtils; |
||||
import com.fr.stable.core.PropertyChangeAdapter; |
||||
|
||||
import javax.swing.*; |
||||
import javax.swing.event.CellEditorListener; |
||||
import javax.swing.event.ChangeEvent; |
||||
import java.awt.*; |
||||
import java.awt.event.FocusEvent; |
||||
import java.awt.event.FocusListener; |
||||
import java.awt.event.MouseAdapter; |
||||
import java.awt.event.MouseEvent; |
||||
import java.util.ArrayList; |
||||
import java.util.Vector; |
||||
|
||||
/** |
||||
* Created by plough on 2017/7/23. |
||||
*/ |
||||
public class UINameEdList extends UIList implements CellEditorListener { |
||||
private static final int TEST_LIST_LENTH = 20; |
||||
private static final int BUTTON_WIDTH = 20; |
||||
private boolean editable = true; |
||||
|
||||
// kunsnat: 是否强制ListName是数字 (int型)
|
||||
private boolean isNameShouldNumber = false; |
||||
|
||||
transient protected ListCellEditor cellEditor; |
||||
transient protected Component editorComp; |
||||
transient protected int editingIndex; |
||||
private PropertyChangeAdapter editingListner; |
||||
private java.util.List<ModNameActionListener> ll = new ArrayList<ModNameActionListener>(); |
||||
|
||||
public UINameEdList(ListModel dataModel) { |
||||
super(dataModel); |
||||
} |
||||
|
||||
public UINameEdList(final Object[] listData) { |
||||
super(listData); |
||||
} |
||||
|
||||
public UINameEdList(final Vector<?> listData) { |
||||
super(listData); |
||||
} |
||||
|
||||
public UINameEdList() { |
||||
super(); |
||||
} |
||||
|
||||
/* |
||||
* Sets是否可编辑 |
||||
*/ |
||||
public void setEditable(boolean editable) { |
||||
this.editable = editable; |
||||
} |
||||
|
||||
/** |
||||
* 是否可编辑 |
||||
* |
||||
* @return 是则返回true |
||||
*/ |
||||
public boolean isEditable() { |
||||
return this.editable; |
||||
} |
||||
|
||||
public void setNameShouldNumber(boolean isNameShouldNumber) { |
||||
this.isNameShouldNumber = isNameShouldNumber; |
||||
} |
||||
|
||||
/** |
||||
* 是否强制ListName是数字 (int型) |
||||
* |
||||
* @return 是则返回true |
||||
*/ |
||||
public boolean isNameShouldNumber() { |
||||
return isNameShouldNumber; |
||||
} |
||||
|
||||
/** |
||||
* 添加名字改变时的listener |
||||
* |
||||
* @param l 监听器 |
||||
*/ |
||||
public void addModNameActionListener(ModNameActionListener l) { |
||||
ll.add(l); |
||||
} |
||||
|
||||
/** |
||||
* 编辑时的监听器 |
||||
* |
||||
* @param l 监听器 |
||||
*/ |
||||
public void addEditingListner(PropertyChangeAdapter l) { |
||||
this.editingListner = l; |
||||
} |
||||
|
||||
/** |
||||
* 移除某名字改变时的listener |
||||
* |
||||
* @param l 监听器 |
||||
*/ |
||||
public void removeModNameActionListener(ModNameActionListener l) { |
||||
ll.remove(l); |
||||
} |
||||
|
||||
public ListCellEditor getCellEditor() { |
||||
if (cellEditor == null) { |
||||
UITextField editField = new UITextField(); |
||||
if (editingListner != null) { |
||||
editField.addFocusListener(new FocusListener() { |
||||
|
||||
@Override |
||||
public void focusLost(FocusEvent e) { |
||||
editingListner.propertyChange(); |
||||
|
||||
} |
||||
|
||||
@Override |
||||
public void focusGained(FocusEvent e) { |
||||
// TODO Auto-generated method stub
|
||||
|
||||
} |
||||
}); |
||||
} |
||||
cellEditor = new DefaultListCellEditor(editField) { |
||||
public boolean stopCellEditing() { |
||||
boolean isTrue = super.stopCellEditing(); |
||||
stopEditing(); |
||||
|
||||
return isTrue; |
||||
} |
||||
}; |
||||
cellEditor.addCellEditorListener(this); |
||||
} |
||||
|
||||
return cellEditor; |
||||
} |
||||
|
||||
protected void doAfterLostFocus() { |
||||
|
||||
} |
||||
|
||||
public void setCellEditor(ListCellEditor editor) { |
||||
this.cellEditor = editor; |
||||
} |
||||
|
||||
/* |
||||
* 取得index节点的名字 |
||||
*/ |
||||
public String getNameAt(int index) { |
||||
Nameable nameable = ((ListModelElement) getModel().getElementAt(index)).wrapper; |
||||
if (nameable != null) { |
||||
return nameable.getName(); |
||||
} |
||||
|
||||
return null; |
||||
} |
||||
|
||||
public Object getType(int index) { |
||||
Nameable nameable = ((ListModelElement) getModel().getElementAt(index)).wrapper; |
||||
if (nameable != null && nameable instanceof NameObject) { |
||||
return ((NameObject) nameable).getObject(); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
|
||||
public void setWarnigText() { |
||||
setWarnigText(this.getSelectedIndex()); |
||||
} |
||||
|
||||
public void setWarnigText(int index) { |
||||
setNameAt(Inter.getLocText("Please_Rename") + "!", index); |
||||
this.repaint(); |
||||
} |
||||
|
||||
/* |
||||
* 设置index节点的名字 |
||||
*/ |
||||
// b:edit改变name的时候怎么办?
|
||||
public void setNameAt(String name, int index) { |
||||
Nameable nameable = ((ListModelElement) getModel().getElementAt(index)).wrapper; |
||||
if (nameable != null) { |
||||
String oldName = nameable.getName(); |
||||
|
||||
if (isNameShouldNumber()) { |
||||
// kunsnat: 限制只能是数字(int型)
|
||||
Number number = Utils.string2Number(name); |
||||
if (number == null) { |
||||
nameable.setName(oldName); |
||||
} else { |
||||
int newName = number.intValue(); |
||||
nameable.setName(String.valueOf(newName)); |
||||
} |
||||
} else { |
||||
nameable.setName(name); |
||||
} |
||||
|
||||
for (int i = 0, len = ll.size(); i < len; i++) { |
||||
ll.get(i).nameModed(index, oldName, name); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/* |
||||
* 编辑第index个item |
||||
*/ |
||||
private String oldName; |
||||
|
||||
/** |
||||
* 编辑第index项 |
||||
* |
||||
* @param index 序号 |
||||
* @return 成功返回true |
||||
*/ |
||||
public boolean editItemAt(int index) { |
||||
// 如果不可编辑,返回
|
||||
if (!this.editable) { |
||||
return false; |
||||
} |
||||
|
||||
if (cellEditor != null && !cellEditor.stopCellEditing()) { |
||||
return false; |
||||
} |
||||
if (index < 0 || index >= this.getModel().getSize()) { |
||||
return false; |
||||
} |
||||
|
||||
ListCellEditor editor = getCellEditor(); |
||||
Object value = editor.getCellEditorValue(); |
||||
if (!StringUtils.isBlank(value.toString())) { |
||||
oldName = value.toString(); |
||||
} |
||||
editorComp = prepareEditor(editor, index); |
||||
if (editorComp == null) { |
||||
return false; |
||||
} |
||||
Rectangle rect = this.getCellBounds(index, index); |
||||
// alex:所有的UINameEdList都有Icon,空出前面20 * 20的位置就是放的Icon
|
||||
rect.setRect(createRect(rect, BUTTON_WIDTH)); |
||||
|
||||
editorComp.setBounds(rect); |
||||
add(editorComp); |
||||
editorComp.validate(); |
||||
editorComp.requestFocus(); |
||||
if (editorComp instanceof UITextField) { |
||||
((UITextField) editorComp).selectAll(); |
||||
} |
||||
|
||||
setEditingIndex(index); |
||||
|
||||
return true; |
||||
} |
||||
|
||||
public Rectangle createRect(Rectangle rect, int iconWidth) { |
||||
return new Rectangle(rect.x + iconWidth, rect.y, rect.width - iconWidth, rect.height); |
||||
} |
||||
|
||||
public String getEditingName() { |
||||
return (String) getCellEditor().getCellEditorValue(); |
||||
} |
||||
|
||||
/* |
||||
* 根据ListCellEditor取得编辑器的Component |
||||
*/ |
||||
private Component prepareEditor(ListCellEditor cellEditor, int index) { |
||||
String name = getNameAt(index); |
||||
boolean isSelected = this.isSelectedIndex(index); |
||||
Component comp = cellEditor.getListCellEditorComponent(this, name, isSelected, index); |
||||
|
||||
return comp; |
||||
} |
||||
|
||||
/* |
||||
* 记录正在编辑的index |
||||
*/ |
||||
private void setEditingIndex(int idx) { |
||||
editingIndex = idx; |
||||
} |
||||
|
||||
/** |
||||
* 编辑取消 |
||||
* |
||||
* @param e 事件 |
||||
*/ |
||||
public void editingCanceled(ChangeEvent e) { |
||||
removeComp(); |
||||
} |
||||
|
||||
/** |
||||
* 编辑结束 |
||||
* |
||||
* @param e 事件 |
||||
*/ |
||||
public void editingStopped(ChangeEvent e) { |
||||
doAfterLostFocus(); |
||||
stopEditing(); |
||||
} |
||||
|
||||
/** |
||||
* 停止编辑事件 |
||||
*/ |
||||
public void stopEditing() { |
||||
ListCellEditor editor = getCellEditor(); |
||||
if (editor != null && editorComp != null) { |
||||
Object value = editor.getCellEditorValue(); |
||||
String name = StringUtils.isBlank(value.toString()) ? oldName : value.toString(); |
||||
setNameAt(name, editingIndex); |
||||
removeComp(); |
||||
} |
||||
} |
||||
|
||||
public String[] getAllNames() { |
||||
int length = this.getModel().getSize(); |
||||
String[] names = new String[length]; |
||||
for (int i = 0; i < length; i++) { |
||||
names[i] = getNameAt(i); |
||||
} |
||||
return names; |
||||
} |
||||
|
||||
public Object[] getAllTypes() { |
||||
int length = this.getModel().getSize(); |
||||
Object[] types = new Object[length]; |
||||
for (int i = 0; i < length; i++) { |
||||
types[i] = getType(i); |
||||
} |
||||
return types; |
||||
} |
||||
|
||||
|
||||
/* |
||||
* 移除编辑器的Component |
||||
*/ |
||||
private void removeComp() { |
||||
if (editorComp != null) { |
||||
remove(editorComp); |
||||
} |
||||
Rectangle cellRect = this.getCellBounds(editingIndex, editingIndex); |
||||
setEditingIndex(-1); |
||||
editorComp = null; |
||||
repaint(cellRect); |
||||
} |
||||
|
||||
/** |
||||
* 主函数 |
||||
* |
||||
* @param args 参数 |
||||
*/ |
||||
public static void main(String... args) { |
||||
JFrame f = new JFrame(); |
||||
JPanel c = (JPanel) f.getContentPane(); |
||||
c.setLayout(new BorderLayout()); |
||||
ListModelElement[] data = new ListModelElement[TEST_LIST_LENTH]; |
||||
for (int i = 0; i < TEST_LIST_LENTH; i++) { |
||||
data[i] = new ListModelElement(new NameObject(i + 1 + "", i)); |
||||
} |
||||
final UINameEdList list = new UINameEdList(data); |
||||
list.setEditable(true); |
||||
list.addMouseListener(new MouseAdapter() { |
||||
public void mouseReleased(MouseEvent evt) { |
||||
list.stopEditing(); |
||||
if (evt.getClickCount() >= 2 |
||||
&& SwingUtilities.isLeftMouseButton(evt)) { |
||||
list.editItemAt(list.getSelectedIndex()); |
||||
} |
||||
} |
||||
}) |
||||
; |
||||
|
||||
list.setCellEditor(new DefaultListCellEditor(new UITextField())); |
||||
list.setCellRenderer(new NameableListCellRenderer()); |
||||
c.add(list, BorderLayout.CENTER); |
||||
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); |
||||
f.setSize(400, 600); |
||||
f.setVisible(true); |
||||
} |
||||
|
||||
private static class NameableListCellRenderer extends DefaultListCellRenderer { |
||||
@Override |
||||
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, |
||||
boolean cellHasFocus) { |
||||
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); |
||||
|
||||
if (value instanceof Nameable) { |
||||
Nameable wrappee = (Nameable) value; |
||||
this.setText(wrappee.getName()); |
||||
} |
||||
return this; |
||||
} |
||||
} |
||||
|
||||
} |
Loading…
Reference in new issue