You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
441 lines
14 KiB
441 lines
14 KiB
package com.fr.design.gui.controlpane; |
|
|
|
import com.fr.design.beans.BasicBeanPane; |
|
import com.fr.design.constants.UIConstants; |
|
import com.fr.design.gui.icontainer.UIScrollPane; |
|
import com.fr.design.gui.ilist.JNameEdList; |
|
import com.fr.design.gui.ilist.ListModelElement; |
|
import com.fr.design.gui.ilist.UINameEdList; |
|
import com.fr.design.mainframe.DesignerContext; |
|
import com.fr.design.os.impl.PopupDialogSaveAction; |
|
import com.fr.design.utils.gui.GUICoreUtils; |
|
import com.fr.stable.ArrayUtils; |
|
import com.fr.stable.Nameable; |
|
import com.fr.stable.os.support.OSSupportCenter; |
|
|
|
import javax.swing.DefaultListModel; |
|
import javax.swing.JList; |
|
import javax.swing.JPanel; |
|
import javax.swing.JPopupMenu; |
|
import javax.swing.ListSelectionModel; |
|
import javax.swing.SwingUtilities; |
|
import javax.swing.event.ListDataEvent; |
|
import javax.swing.event.ListDataListener; |
|
import javax.swing.event.ListSelectionEvent; |
|
import javax.swing.event.ListSelectionListener; |
|
import java.awt.BorderLayout; |
|
import java.awt.Point; |
|
import java.awt.Rectangle; |
|
import java.awt.Toolkit; |
|
import java.awt.Window; |
|
import java.awt.event.InputEvent; |
|
import java.awt.event.MouseAdapter; |
|
import java.awt.event.MouseEvent; |
|
import java.awt.event.MouseListener; |
|
import java.lang.reflect.Constructor; |
|
import java.lang.reflect.InvocationTargetException; |
|
|
|
/** |
|
* Created by plough on 2017/7/19. |
|
*/ |
|
|
|
public abstract class UIListControlPane extends UIControlPane implements ListControlPaneProvider { |
|
private static final String LIST_NAME = "UIControl_List"; |
|
private static final int EDIT_RANGE = 25; // 编辑按钮的x坐标范围 |
|
|
|
protected UINameEdList nameableList; |
|
private int editingIndex; |
|
protected String selectedName; |
|
protected boolean isPopulating = false; |
|
private CommonShortCutHandlers commonHandlers; |
|
private ListControlPaneHelper helper; |
|
|
|
|
|
public UIListControlPane() { |
|
super(); |
|
|
|
} |
|
|
|
private ListControlPaneHelper getHelper() { |
|
if (helper == null) { |
|
helper = ListControlPaneHelper.newInstance(this); |
|
} |
|
return helper; |
|
} |
|
|
|
private CommonShortCutHandlers getCommonHandlers() { |
|
if (commonHandlers == null) { |
|
commonHandlers = CommonShortCutHandlers.newInstance(this); |
|
} |
|
return commonHandlers; |
|
} |
|
|
|
@Override |
|
protected JPanel createControlUpdatePane() { |
|
return JControlUpdatePane.newInstance(this); |
|
} |
|
|
|
/** |
|
* 生成添加按钮的NameableCreator |
|
* |
|
* @return 按钮的NameableCreator |
|
*/ |
|
@Override |
|
public abstract NameableCreator[] createNameableCreators(); |
|
|
|
|
|
@Override |
|
protected void initLeftPane(JPanel leftPane) { |
|
nameableList = createJNameList(); |
|
nameableList.setName(LIST_NAME); |
|
nameableList.setSelectionBackground(UIConstants.ATTRIBUTE_PRESS); |
|
leftPane.add(new UIScrollPane(nameableList), BorderLayout.CENTER); |
|
|
|
|
|
nameableList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); |
|
nameableList.addMouseListener(getListMouseListener()); |
|
nameableList.addListSelectionListener(new ListSelectionListener() { |
|
public void valueChanged(ListSelectionEvent evt) { |
|
// richie:避免多次update和populate大大降低效率 |
|
if (!evt.getValueIsAdjusting()) { |
|
// shoc 切换的时候加检验 |
|
if (hasInvalid(false)) { |
|
return; |
|
} |
|
((JControlUpdatePane) UIListControlPane.this.controlUpdatePane).update(); |
|
((JControlUpdatePane) UIListControlPane.this.controlUpdatePane).populate(); |
|
UIListControlPane.this.checkButtonEnabled(); |
|
} |
|
} |
|
}); |
|
if (isNewStyle()) { |
|
nameableList.getModel().addListDataListener(new ListDataListener() { |
|
@Override |
|
public void intervalAdded(ListDataEvent e) { |
|
saveSettings(); |
|
} |
|
|
|
@Override |
|
public void intervalRemoved(ListDataEvent e) { |
|
saveSettings(); |
|
} |
|
|
|
@Override |
|
public void contentsChanged(ListDataEvent e) { |
|
saveSettings(); |
|
} |
|
}); |
|
} |
|
} |
|
|
|
private UINameEdList createJNameList() { |
|
UINameEdList nameEdList = new UINameEdList(new DefaultListModel()) { |
|
@Override |
|
protected void doAfterLostFocus() { |
|
UIListControlPane.this.updateControlUpdatePane(); |
|
} |
|
@Override |
|
protected void doAfterStopEditing() { |
|
saveSettings(); |
|
} |
|
}; |
|
nameEdList.setCellRenderer(new UINameableListCellRenderer(this)); |
|
return nameEdList; |
|
} |
|
|
|
private void updateControlUpdatePane() { |
|
((JControlUpdatePane) controlUpdatePane).update(); |
|
} |
|
|
|
protected void setNameListEditable(boolean editable) { |
|
this.nameableList.setEditable(editable); |
|
} |
|
|
|
@Override |
|
public Nameable[] update() { |
|
return getHelper().update(); |
|
} |
|
|
|
@Override |
|
public void populate(Nameable[] nameableArray) { |
|
isPopulating = true; // 加一个标识位,避免切换单元格时,触发 saveSettings |
|
nameableList.getCellEditor().stopCellEditing(); |
|
DefaultListModel listModel = (DefaultListModel) this.nameableList.getModel(); |
|
listModel.removeAllElements(); |
|
if (ArrayUtils.isEmpty(nameableArray)) { |
|
isPopulating = false; |
|
return; |
|
} |
|
|
|
listModel.setSize(nameableArray.length); |
|
for (int i = 0; i < nameableArray.length; i++) { |
|
listModel.set(i, new ListModelElement(nameableArray[i])); |
|
} |
|
|
|
if (listModel.size() > 0 || this.nameableList.getSelectedIndex() != 0) { |
|
this.nameableList.setSelectedIndex(0); |
|
} |
|
this.checkButtonEnabled(); |
|
|
|
isPopulating = false; |
|
} |
|
|
|
|
|
/** |
|
* 获取选中的名字 |
|
*/ |
|
public String getSelectedName() { |
|
return getHelper().getSelectedName(); |
|
} |
|
|
|
/** |
|
* 添加 Nameable |
|
* |
|
* @param nameable 添加的Nameable |
|
* @param index 序号 |
|
*/ |
|
public void addNameable(Nameable nameable, int index) { |
|
getHelper().addNameable(nameable, index); |
|
popupEditDialog(); |
|
} |
|
|
|
public DefaultListModel getModel() { |
|
return (DefaultListModel) UIListControlPane.this.nameableList.getModel(); |
|
} |
|
|
|
private void popupEditDialog() { |
|
popupEditDialog(null); |
|
} |
|
|
|
protected void popupEditDialog(Point mousePos) { |
|
if (isNewStyle()) { |
|
Rectangle currentCellBounds = nameableList.getCellBounds(editingIndex, editingIndex); |
|
if (editingIndex < 0 || (mousePos != null && !currentCellBounds.contains(mousePos))) { |
|
return; |
|
} |
|
popupEditDialog.setLocation(getPopupDialogLocation()); |
|
if (popupEditDialog instanceof PopupEditDialog) { |
|
((PopupEditDialog)popupEditDialog).setTitle(getSelectedName()); |
|
} |
|
popupEditDialog.setVisible(true); |
|
PopupDialogSaveAction osBasedAction = OSSupportCenter.getAction(PopupDialogSaveAction.class); |
|
osBasedAction.register(this, popupEditDialog); |
|
} |
|
} |
|
|
|
private Point getPopupDialogLocation() { |
|
Point resultPos = new Point(0, 0); |
|
Point listPos = nameableList.getLocationOnScreen(); |
|
resultPos.x = listPos.x - popupEditDialog.getWidth(); |
|
resultPos.y = listPos.y + (nameableList.getSelectedIndex() - 1) * EDIT_RANGE; |
|
|
|
// 当对象在屏幕上的位置比较靠下时,往下移动弹窗至与属性面板平齐 |
|
Window frame = DesignerContext.getDesignerFrame(); |
|
// 不能太低 |
|
int maxY = frame.getLocationOnScreen().y + frame.getHeight() - popupEditDialog.getHeight(); |
|
if (resultPos.y > maxY) { |
|
resultPos.y = maxY; |
|
} |
|
// 也不能太高 |
|
int minY = frame.getLocationOnScreen().y + EDIT_RANGE; |
|
if (resultPos.y < minY) { |
|
resultPos.y = minY; |
|
} |
|
|
|
// 当在左侧显示不下时,在右侧弹出弹窗 |
|
if (resultPos.x < 0) { |
|
resultPos.x = listPos.x + nameableList.getParent().getWidth(); |
|
} |
|
// 如果右侧显示不下,可以向左移动 |
|
int maxX = frame.getLocationOnScreen().x + frame.getWidth() - popupEditDialog.getWidth() - EDIT_RANGE; |
|
if (resultPos.x > maxX) { |
|
resultPos.x = maxX; |
|
} |
|
|
|
return resultPos; |
|
} |
|
|
|
/** |
|
* 生成不重复的名字 |
|
* |
|
* @param prefix 名字前缀 |
|
* @return 名字 |
|
*/ |
|
@Override |
|
public String createUnrepeatedName(String prefix) { |
|
return getCommonHandlers().createUnrepeatedName(prefix); |
|
} |
|
|
|
@Override |
|
public void onAddItem(NameableCreator creator) { |
|
getCommonHandlers().onAddItem(creator); |
|
} |
|
|
|
@Override |
|
public void onRemoveItem() { |
|
getCommonHandlers().onRemoveItem(); |
|
} |
|
|
|
@Override |
|
public void onCopyItem() { |
|
getCommonHandlers().onCopyItem(); |
|
} |
|
|
|
@Override |
|
public void onMoveUpItem() { |
|
getCommonHandlers().onMoveUpItem(); |
|
} |
|
|
|
@Override |
|
public void onMoveDownItem() { |
|
getCommonHandlers().onMoveDownItem(); |
|
} |
|
|
|
@Override |
|
public void onSortItem(boolean isAtoZ) { |
|
getCommonHandlers().onSortItem(isAtoZ); |
|
} |
|
|
|
@Override |
|
public boolean isItemSelected() { |
|
return getModel().getSize() > 0 && nameableList.getSelectedIndex() != -1; |
|
} |
|
|
|
/* |
|
* UINameEdList的鼠标事件 |
|
*/ |
|
private MouseListener getListMouseListener() { |
|
return new MouseAdapter() { |
|
@Override |
|
public void mouseReleased(MouseEvent evt) { |
|
nameableList.stopEditing(); |
|
if (evt.getClickCount() >= 2 |
|
&& SwingUtilities.isLeftMouseButton(evt) && evt.getX() > EDIT_RANGE) { |
|
editingIndex = nameableList.getSelectedIndex(); |
|
selectedName = nameableList.getNameAt(editingIndex); |
|
nameableList.editItemAt(nameableList.getSelectedIndex()); |
|
} else if (SwingUtilities.isLeftMouseButton(evt) && evt.getX() <= EDIT_RANGE) { |
|
editingIndex = nameableList.getSelectedIndex(); |
|
selectedName = nameableList.getNameAt(editingIndex); |
|
popupEditDialog(evt.getPoint()); |
|
} |
|
|
|
// peter:处理右键的弹出菜单 |
|
if (!SwingUtilities.isRightMouseButton(evt)) { |
|
return; |
|
} |
|
|
|
// peter: 注意,在checkButtonEnabled()方法里面,设置了所有的Action的Enabled. |
|
checkButtonEnabled(); |
|
|
|
// p:右键菜单. |
|
JPopupMenu popupMenu = new JPopupMenu(); |
|
|
|
for (ShortCut4JControlPane sj : getShorts()) { |
|
sj.getShortCut().intoJPopupMenu(popupMenu); |
|
} |
|
|
|
// peter: 只有弹出菜单有子菜单的时候,才需要弹出来. |
|
GUICoreUtils.showPopupMenu(popupMenu, nameableList, evt.getX() - 1, |
|
evt.getY() - 1); |
|
} |
|
|
|
@Override |
|
public void mouseClicked(MouseEvent e) { |
|
JList list = (JList) e.getSource(); |
|
if (list.locationToIndex(e.getPoint()) == -1 && !e.isShiftDown() |
|
&& !isMenuShortcutKeyDown(e)) { |
|
list.clearSelection(); |
|
} |
|
} |
|
|
|
private boolean isMenuShortcutKeyDown(InputEvent event) { |
|
return (event.getModifiers() & Toolkit.getDefaultToolkit() |
|
.getMenuShortcutKeyMask()) != 0; |
|
} |
|
|
|
@Override |
|
public void mouseMoved(MouseEvent e) { |
|
|
|
} |
|
}; |
|
} |
|
|
|
/** |
|
* 检查按钮可用状态 Check button enabled. |
|
*/ |
|
@Override |
|
public void checkButtonEnabled() { |
|
getHelper().checkButtonEnabled(); |
|
} |
|
|
|
public BasicBeanPane createPaneByCreators(NameableCreator creator) { |
|
try { |
|
return creator.getUpdatePane().newInstance(); |
|
} catch (InstantiationException e) { |
|
throw new RuntimeException(e); |
|
} catch (IllegalAccessException e) { |
|
throw new RuntimeException(e); |
|
} |
|
} |
|
|
|
public BasicBeanPane createPaneByCreators(NameableCreator creator, String string) { |
|
Constructor constructor = null; |
|
try { |
|
constructor = creator.getUpdatePane().getDeclaredConstructor(new Class[]{String.class}); |
|
constructor.setAccessible(true); |
|
return (BasicBeanPane) constructor.newInstance(string); |
|
} catch (NoSuchMethodException e) { |
|
throw new RuntimeException(e); |
|
} catch (InstantiationException e) { |
|
throw new RuntimeException(e); |
|
} catch (IllegalAccessException e) { |
|
throw new RuntimeException(e); |
|
} catch (InvocationTargetException e) { |
|
throw new RuntimeException(e); |
|
} |
|
} |
|
|
|
/** |
|
* 检查是否符合规范 |
|
* |
|
* @throws Exception |
|
*/ |
|
@Override |
|
public void checkValid() throws Exception { |
|
((JControlUpdatePane) this.controlUpdatePane).checkValid(); |
|
} |
|
|
|
@Override |
|
public boolean hasInvalid(boolean isAdd) { |
|
return getHelper().hasInvalid(isAdd); |
|
} |
|
/** |
|
* 设置选中项 |
|
* |
|
* @param index 选中项的序列号 |
|
*/ |
|
public void setSelectedIndex(int index) { |
|
nameableList.setSelectedIndex(index); |
|
} |
|
|
|
@Override |
|
public int getSelectedIndex() { |
|
return nameableList.getSelectedIndex(); |
|
} |
|
|
|
@Override |
|
public ListModelElement getSelectedValue() { |
|
return (ListModelElement) this.nameableList.getSelectedValue(); |
|
} |
|
|
|
@Override |
|
public JControlUpdatePane getControlUpdatePane() { |
|
return (JControlUpdatePane) controlUpdatePane; |
|
} |
|
|
|
@Override |
|
public JNameEdList getNameableList() { |
|
return nameableList; |
|
} |
|
}
|
|
|