kerry
7 years ago
53 changed files with 3101 additions and 812 deletions
@ -0,0 +1,483 @@ |
|||||||
|
package com.fr.design.gui.controlpane; |
||||||
|
|
||||||
|
import com.fr.base.BaseUtils; |
||||||
|
import com.fr.design.actions.UpdateAction; |
||||||
|
import com.fr.design.constants.UIConstants; |
||||||
|
import com.fr.design.dialog.BasicPane; |
||||||
|
import com.fr.design.gui.icontainer.UIScrollPane; |
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.gui.ilist.ListModelElement; |
||||||
|
import com.fr.design.gui.ilist.UIList; |
||||||
|
import com.fr.design.gui.itoolbar.UIToolBarUI; |
||||||
|
import com.fr.design.gui.itoolbar.UIToolbar; |
||||||
|
import com.fr.design.layout.FRGUIPaneFactory; |
||||||
|
import com.fr.design.menu.ShortCut; |
||||||
|
import com.fr.design.menu.ToolBarDef; |
||||||
|
import com.fr.general.ComparatorUtils; |
||||||
|
import com.fr.general.Inter; |
||||||
|
import com.fr.stable.ArrayUtils; |
||||||
|
import com.fr.stable.Nameable; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
import sun.swing.DefaultLookup; |
||||||
|
|
||||||
|
import javax.swing.BorderFactory; |
||||||
|
import javax.swing.DefaultListModel; |
||||||
|
import javax.swing.JComponent; |
||||||
|
import javax.swing.JList; |
||||||
|
import javax.swing.JPanel; |
||||||
|
import javax.swing.ListCellRenderer; |
||||||
|
import javax.swing.ListSelectionModel; |
||||||
|
import javax.swing.border.Border; |
||||||
|
import javax.swing.event.ListSelectionEvent; |
||||||
|
import javax.swing.event.ListSelectionListener; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Color; |
||||||
|
import java.awt.Component; |
||||||
|
import java.awt.Graphics; |
||||||
|
import java.awt.Graphics2D; |
||||||
|
import java.awt.Point; |
||||||
|
import java.awt.Toolkit; |
||||||
|
import java.awt.event.ActionEvent; |
||||||
|
import java.awt.event.InputEvent; |
||||||
|
import java.awt.event.MouseAdapter; |
||||||
|
import java.awt.event.MouseEvent; |
||||||
|
import java.awt.event.MouseListener; |
||||||
|
import java.util.Arrays; |
||||||
|
import java.util.Comparator; |
||||||
|
|
||||||
|
/** |
||||||
|
* 简单列表面板 |
||||||
|
* Created by plough on 2018/2/1. |
||||||
|
*/ |
||||||
|
public class UISimpleListControlPane extends BasicPane { |
||||||
|
public static final String LIST_NAME = "UISimpleControl_List"; |
||||||
|
|
||||||
|
protected UIList nameList; |
||||||
|
protected String selectedName; |
||||||
|
private ShortCut4JControlPane[] shorts; |
||||||
|
private ToolBarDef toolbarDef; |
||||||
|
private UIToolbar toolBar; |
||||||
|
|
||||||
|
public UISimpleListControlPane() { |
||||||
|
initComponentPane(); |
||||||
|
} |
||||||
|
|
||||||
|
public ShortCut4JControlPane[] getShorts() { |
||||||
|
return shorts; |
||||||
|
} |
||||||
|
|
||||||
|
protected void initComponentPane() { |
||||||
|
this.setLayout(FRGUIPaneFactory.createBorderLayout()); |
||||||
|
this.add(getContentPane(), BorderLayout.CENTER); |
||||||
|
this.checkButtonEnabled(); |
||||||
|
} |
||||||
|
|
||||||
|
protected JPanel getContentPane() { |
||||||
|
JPanel contentPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||||
|
|
||||||
|
JPanel listPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||||
|
initListPane(listPane); |
||||||
|
contentPane.add(listPane, BorderLayout.CENTER); |
||||||
|
|
||||||
|
shorts = this.createShortcuts(); |
||||||
|
if (ArrayUtils.isEmpty(shorts)) { |
||||||
|
return contentPane; |
||||||
|
} |
||||||
|
|
||||||
|
toolbarDef = new ToolBarDef(); |
||||||
|
for (ShortCut4JControlPane sj : shorts) { |
||||||
|
toolbarDef.addShortCut(sj.getShortCut()); |
||||||
|
} |
||||||
|
toolBar = ToolBarDef.createJToolBar(); |
||||||
|
toolBar.setUI(new UIToolBarUI(){ |
||||||
|
@Override |
||||||
|
public void paint(Graphics g, JComponent c) { |
||||||
|
Graphics2D g2 = (Graphics2D) g; |
||||||
|
g2.setColor(Color.WHITE); |
||||||
|
g2.fillRect(0, 0, c.getWidth(), c.getHeight()); |
||||||
|
} |
||||||
|
}); |
||||||
|
toolbarDef.updateToolBar(toolBar); |
||||||
|
// 封装一层,加边框
|
||||||
|
JPanel toolBarPane = new JPanel(new BorderLayout()); |
||||||
|
toolBarPane.add(toolBar, BorderLayout.CENTER); |
||||||
|
toolBarPane.setBorder(BorderFactory.createMatteBorder(1, 1, 0, 1, UIConstants.RULER_LINE_COLOR)); |
||||||
|
|
||||||
|
listPane.add(toolBarPane, BorderLayout.NORTH); |
||||||
|
|
||||||
|
return contentPane; |
||||||
|
} |
||||||
|
|
||||||
|
protected ShortCut4JControlPane[] createShortcuts() { |
||||||
|
return new ShortCut4JControlPane[]{ |
||||||
|
moveUpItemShortCut(), |
||||||
|
moveDownItemShortCut(), |
||||||
|
sortItemShortCut(), |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
protected void initListPane(JPanel listPane) { |
||||||
|
nameList = createJNameList(); |
||||||
|
nameList.setName(LIST_NAME); |
||||||
|
nameList.setSelectionBackground(UIConstants.ATTRIBUTE_PRESS); |
||||||
|
listPane.add(new UIScrollPane(nameList), BorderLayout.CENTER); |
||||||
|
|
||||||
|
|
||||||
|
nameList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); |
||||||
|
nameList.addMouseListener(listMouseListener); |
||||||
|
nameList.addListSelectionListener(new ListSelectionListener() { |
||||||
|
public void valueChanged(ListSelectionEvent evt) { |
||||||
|
// richie:避免多次update和populate大大降低效率
|
||||||
|
if (!evt.getValueIsAdjusting()) { |
||||||
|
UISimpleListControlPane.this.checkButtonEnabled(); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
public UIList createJNameList() { |
||||||
|
UIList nameList = new UIList(new DefaultListModel()) { |
||||||
|
@Override |
||||||
|
public int locationToIndex(Point location) { |
||||||
|
int index = super.locationToIndex(location); |
||||||
|
if (index != -1 && !getCellBounds(index, index).contains(location)) { |
||||||
|
return -1; |
||||||
|
} |
||||||
|
else { |
||||||
|
return index; |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
nameList.setCellRenderer(new NameableListCellRenderer(this)); |
||||||
|
return nameList; |
||||||
|
} |
||||||
|
|
||||||
|
protected ShortCut4JControlPane moveUpItemShortCut() { |
||||||
|
return new NormalEnableShortCut(new MoveUpItemAction()); |
||||||
|
} |
||||||
|
|
||||||
|
protected ShortCut4JControlPane moveDownItemShortCut() { |
||||||
|
return new NormalEnableShortCut(new MoveDownItemAction()); |
||||||
|
} |
||||||
|
|
||||||
|
protected ShortCut4JControlPane sortItemShortCut() { |
||||||
|
return new NormalEnableShortCut(new SortItemAction()); |
||||||
|
} |
||||||
|
|
||||||
|
public Nameable[] update() { |
||||||
|
java.util.List<Nameable> res = new java.util.ArrayList<Nameable>(); |
||||||
|
DefaultListModel listModel = (DefaultListModel) this.nameList.getModel(); |
||||||
|
for (int i = 0, len = listModel.getSize(); i < len; i++) { |
||||||
|
res.add(((ListModelElement) listModel.getElementAt(i)).wrapper); |
||||||
|
} |
||||||
|
|
||||||
|
return res.toArray(new Nameable[res.size()]); |
||||||
|
} |
||||||
|
|
||||||
|
public void populate(Nameable[] nameableArray) { |
||||||
|
DefaultListModel listModel = (DefaultListModel) this.nameList.getModel(); |
||||||
|
listModel.removeAllElements(); |
||||||
|
if (ArrayUtils.isEmpty(nameableArray)) { |
||||||
|
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.nameList.getSelectedIndex() != 0) { |
||||||
|
this.nameList.setSelectedIndex(0); |
||||||
|
} |
||||||
|
this.checkButtonEnabled(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 根据name,选中UINameEdList中的item |
||||||
|
*/ |
||||||
|
public void setSelectedName(String name) { |
||||||
|
DefaultListModel listModel = (DefaultListModel) this.nameList.getModel(); |
||||||
|
for (int i = 0, len = listModel.getSize(); i < len; i++) { |
||||||
|
Nameable item = ((ListModelElement) listModel.getElementAt(i)).wrapper; |
||||||
|
if (ComparatorUtils.equals(name, item.getName())) { |
||||||
|
this.nameList.setSelectedIndex(i); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取选中的名字 |
||||||
|
*/ |
||||||
|
public String getSelectedName() { |
||||||
|
ListModelElement el = (ListModelElement) this.nameList.getSelectedValue(); |
||||||
|
|
||||||
|
return el == null ? null : el.wrapper.getName(); |
||||||
|
} |
||||||
|
|
||||||
|
protected DefaultListModel getModel() { |
||||||
|
return (DefaultListModel) this.nameList.getModel(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String title4PopupWindow() { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
/* |
||||||
|
* 上移Item |
||||||
|
*/ |
||||||
|
private class MoveUpItemAction extends UpdateAction { |
||||||
|
public MoveUpItemAction() { |
||||||
|
this.setName(Inter.getLocText("Utils-Move_Up")); |
||||||
|
this.setMnemonic('U'); |
||||||
|
this.setSmallIcon(BaseUtils |
||||||
|
.readIcon("/com/fr/design/images/control/up.png")); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent evt) { |
||||||
|
int selectedIndex = nameList.getSelectedIndex(); |
||||||
|
if (selectedIndex == -1) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
// 上移
|
||||||
|
if (selectedIndex > 0) { |
||||||
|
DefaultListModel listModel = (DefaultListModel) nameList.getModel(); |
||||||
|
|
||||||
|
Object prevObj = listModel.get(selectedIndex - 1); |
||||||
|
Object currentObj = listModel.get(selectedIndex); |
||||||
|
listModel.set(selectedIndex - 1, currentObj); |
||||||
|
listModel.set(selectedIndex, prevObj); |
||||||
|
|
||||||
|
nameList.setSelectedIndex(selectedIndex - 1); |
||||||
|
nameList.ensureIndexIsVisible(selectedIndex - 1); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/* |
||||||
|
* 下移Item |
||||||
|
*/ |
||||||
|
private class MoveDownItemAction extends UpdateAction { |
||||||
|
public MoveDownItemAction() { |
||||||
|
this.setName(Inter.getLocText("Utils-Move_Down")); |
||||||
|
this.setMnemonic('D'); |
||||||
|
this.setSmallIcon(BaseUtils |
||||||
|
.readIcon("/com/fr/design/images/control/down.png")); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent evt) { |
||||||
|
int selectedIndex = nameList.getSelectedIndex(); |
||||||
|
if (selectedIndex == -1) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if (selectedIndex < nameList.getModel().getSize() - 1) { |
||||||
|
DefaultListModel listModel = (DefaultListModel) nameList.getModel(); |
||||||
|
|
||||||
|
Object nextObj = listModel.get(selectedIndex + 1); |
||||||
|
Object currentObj = listModel.get(selectedIndex); |
||||||
|
listModel.set(selectedIndex + 1, currentObj); |
||||||
|
listModel.set(selectedIndex, nextObj); |
||||||
|
|
||||||
|
nameList.setSelectedIndex(selectedIndex + 1); |
||||||
|
nameList.ensureIndexIsVisible(selectedIndex + 1); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private class SortItemAction extends UpdateAction { |
||||||
|
private boolean isAtoZ = false; |
||||||
|
|
||||||
|
public SortItemAction() { |
||||||
|
this.setName(Inter.getLocText("FR-Action_Sort")); |
||||||
|
this.setMnemonic('S'); |
||||||
|
this.setSmallIcon(BaseUtils |
||||||
|
.readIcon("/com/fr/design/images/control/sortAsc.png")); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent evt) { |
||||||
|
// p:选中的值.
|
||||||
|
Object selectedValue = nameList.getSelectedValue(); |
||||||
|
|
||||||
|
DefaultListModel listModel = (DefaultListModel) nameList.getModel(); |
||||||
|
if (listModel.getSize() <= 0) { |
||||||
|
return; |
||||||
|
} |
||||||
|
Nameable[] nameableArray = new Nameable[listModel.getSize()]; |
||||||
|
|
||||||
|
for (int i = 0; i < listModel.getSize(); i++) { |
||||||
|
nameableArray[i] = ((ListModelElement) listModel.getElementAt(i)).wrapper; |
||||||
|
} |
||||||
|
|
||||||
|
// p:排序.
|
||||||
|
if (isAtoZ) { // 升序
|
||||||
|
Comparator<Nameable> nameableComparator = new Comparator<Nameable>() { |
||||||
|
@Override |
||||||
|
public int compare(Nameable o1, Nameable o2) { |
||||||
|
return ComparatorUtils.compare(o2.getName(), o1.getName()); |
||||||
|
} |
||||||
|
}; |
||||||
|
isAtoZ = !isAtoZ; |
||||||
|
Arrays.sort(nameableArray, nameableComparator); |
||||||
|
} else { // 降序
|
||||||
|
Comparator<Nameable> nameableComparator = new Comparator<Nameable>() { |
||||||
|
@Override |
||||||
|
public int compare(Nameable o1, Nameable o2) { |
||||||
|
return ComparatorUtils.compare(o1.getName(), o2 |
||||||
|
.getName()); |
||||||
|
} |
||||||
|
}; |
||||||
|
isAtoZ = !isAtoZ; |
||||||
|
Arrays.sort(nameableArray, nameableComparator); |
||||||
|
} |
||||||
|
|
||||||
|
for (int i = 0; i < nameableArray.length; i++) { |
||||||
|
listModel.set(i, new ListModelElement(nameableArray[i])); |
||||||
|
} |
||||||
|
|
||||||
|
// p:需要选中以前的那个值.
|
||||||
|
if (selectedValue != null) { |
||||||
|
nameList.setSelectedValue(selectedValue, true); |
||||||
|
} |
||||||
|
|
||||||
|
checkButtonEnabled(); |
||||||
|
// p:需要repaint.
|
||||||
|
nameList.repaint(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/* |
||||||
|
* UIList的鼠标事件 |
||||||
|
*/ |
||||||
|
private MouseListener listMouseListener = new MouseAdapter() { |
||||||
|
@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; |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* 检查按钮可用状态 Check button enabled. |
||||||
|
*/ |
||||||
|
public void checkButtonEnabled() { |
||||||
|
for (ShortCut4JControlPane sj : getShorts()) { |
||||||
|
sj.checkEnable(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 设置选中项 |
||||||
|
* |
||||||
|
* @param index 选中项的序列号 |
||||||
|
*/ |
||||||
|
public void setSelectedIndex(int index) { |
||||||
|
nameList.setSelectedIndex(index); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public class NormalEnableShortCut extends ShortCut4JControlPane { |
||||||
|
public NormalEnableShortCut(ShortCut shortCut) { |
||||||
|
this.shortCut = shortCut; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 检查是否可用 |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public void checkEnable() { |
||||||
|
this.shortCut.setEnabled(getModel() |
||||||
|
.getSize() > 0 |
||||||
|
&& UISimpleListControlPane.this.nameList.getSelectedIndex() != -1); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private class NameableListCellRenderer extends |
||||||
|
JPanel implements ListCellRenderer { |
||||||
|
|
||||||
|
private UILabel label; |
||||||
|
private UISimpleListControlPane listControlPane; |
||||||
|
private Color initialLabelForeground; |
||||||
|
|
||||||
|
public NameableListCellRenderer(UISimpleListControlPane listControlPane) { |
||||||
|
super(); |
||||||
|
this.listControlPane = listControlPane; |
||||||
|
initComponents(); |
||||||
|
setOpaque(true); |
||||||
|
setBorder(getNoFocusBorder()); |
||||||
|
setName("List.cellRenderer"); |
||||||
|
} |
||||||
|
|
||||||
|
private void initComponents() { |
||||||
|
label = new UILabel(); |
||||||
|
label.setBorder(BorderFactory.createEmptyBorder(3, 10, 3, 0)); |
||||||
|
initialLabelForeground = label.getForeground(); |
||||||
|
this.setLayout(new BorderLayout()); |
||||||
|
this.add(label, BorderLayout.CENTER); |
||||||
|
} |
||||||
|
|
||||||
|
private Border getNoFocusBorder() { |
||||||
|
return BorderFactory.createMatteBorder(0, 0, 1, 0, UIConstants.LIST_ITEM_SPLIT_LINE); |
||||||
|
} |
||||||
|
|
||||||
|
private void setText(String t) { |
||||||
|
label.setText(t); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Component getListCellRendererComponent(JList list, Object value, |
||||||
|
int index, boolean isSelected, boolean cellHasFocus) { |
||||||
|
setComponentOrientation(list.getComponentOrientation()); |
||||||
|
|
||||||
|
Color bg = null; |
||||||
|
Color fg = null; |
||||||
|
|
||||||
|
JList.DropLocation dropLocation = list.getDropLocation(); |
||||||
|
if (dropLocation != null |
||||||
|
&& !dropLocation.isInsert() |
||||||
|
&& dropLocation.getIndex() == index) { |
||||||
|
|
||||||
|
bg = DefaultLookup.getColor(this, ui, "List.dropCellBackground"); |
||||||
|
fg = DefaultLookup.getColor(this, ui, "List.dropCellForeground"); |
||||||
|
|
||||||
|
isSelected = true; |
||||||
|
} |
||||||
|
|
||||||
|
if (isSelected) { |
||||||
|
setBackground(bg == null ? list.getSelectionBackground() : bg); |
||||||
|
setForeground(fg == null ? list.getSelectionForeground() : fg); |
||||||
|
label.setForeground(Color.WHITE); |
||||||
|
} |
||||||
|
else { |
||||||
|
setBackground(list.getBackground()); |
||||||
|
setForeground(list.getForeground()); |
||||||
|
label.setForeground(initialLabelForeground); |
||||||
|
} |
||||||
|
|
||||||
|
setText((value == null) ? StringUtils.EMPTY : value.toString()); |
||||||
|
|
||||||
|
setEnabled(list.isEnabled()); |
||||||
|
setFont(list.getFont()); |
||||||
|
|
||||||
|
if (value instanceof ListModelElement) { |
||||||
|
Nameable wrappee = ((ListModelElement) value).wrapper; |
||||||
|
this.setText(wrappee.getName()); |
||||||
|
} |
||||||
|
|
||||||
|
return this; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,154 @@ |
|||||||
|
package com.fr.design.gui.frpane; |
||||||
|
|
||||||
|
import com.fr.base.BaseUtils; |
||||||
|
import com.fr.base.Style; |
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.style.background.image.ImageFileChooser; |
||||||
|
import com.fr.design.style.background.image.ImagePreviewer; |
||||||
|
import com.fr.design.utils.ImageUtils; |
||||||
|
import com.fr.general.ImageWithSuffix; |
||||||
|
import com.fr.general.Inter; |
||||||
|
import com.fr.stable.CoreGraphHelper; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
|
||||||
|
import javax.swing.JFileChooser; |
||||||
|
import javax.swing.SwingWorker; |
||||||
|
import javax.swing.event.ChangeEvent; |
||||||
|
import javax.swing.event.ChangeListener; |
||||||
|
import java.awt.Image; |
||||||
|
import java.io.File; |
||||||
|
|
||||||
|
/** |
||||||
|
* 图片选择框包装类 |
||||||
|
* Created by zack on 2018/3/9. |
||||||
|
*/ |
||||||
|
public class ImgChooseWrapper { |
||||||
|
private ImagePreviewer previewPane = null; |
||||||
|
|
||||||
|
private ImageFileChooser imageFileChooser = null; |
||||||
|
|
||||||
|
private Style imageStyle = null; |
||||||
|
|
||||||
|
private SwingWorker<Void, Void> imageWorker; |
||||||
|
private ChangeListener changeListener; |
||||||
|
|
||||||
|
private transient Image selectImage; |
||||||
|
private UILabel imageSizeLabel; |
||||||
|
|
||||||
|
public static ImgChooseWrapper getInstance(ImagePreviewer previewPane, ImageFileChooser imageFileChooser, Style imageStyle) { |
||||||
|
return getInstance(previewPane, imageFileChooser, imageStyle, null); |
||||||
|
} |
||||||
|
|
||||||
|
public static ImgChooseWrapper getInstance(ImagePreviewer previewPane, ImageFileChooser imageFileChooser, Style imageStyle, ChangeListener changeListener) { |
||||||
|
return new ImgChooseWrapper(previewPane, imageFileChooser, imageStyle, changeListener, null, null); |
||||||
|
} |
||||||
|
|
||||||
|
public static ImgChooseWrapper getInstance(Image selectImage, UILabel imageSizeLabel, ImageFileChooser imageFileChooser) { |
||||||
|
return new ImgChooseWrapper(null, imageFileChooser, null, null, selectImage, imageSizeLabel); |
||||||
|
} |
||||||
|
|
||||||
|
private ImgChooseWrapper(ImagePreviewer previewPane, ImageFileChooser imageFileChooser, Style imageStyle, ChangeListener changeListener, Image selectImage, UILabel imageSizeLabel) { |
||||||
|
this.previewPane = previewPane; |
||||||
|
this.imageFileChooser = imageFileChooser; |
||||||
|
this.imageStyle = imageStyle; |
||||||
|
this.changeListener = changeListener; |
||||||
|
this.selectImage = selectImage; |
||||||
|
this.imageSizeLabel = imageSizeLabel; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public void setPreviewPane(ImagePreviewer previewPane) { |
||||||
|
this.previewPane = previewPane; |
||||||
|
} |
||||||
|
|
||||||
|
public ImageFileChooser getImageFileChooser() { |
||||||
|
return imageFileChooser; |
||||||
|
} |
||||||
|
|
||||||
|
public void setImageFileChooser(ImageFileChooser imageFileChooser) { |
||||||
|
this.imageFileChooser = imageFileChooser; |
||||||
|
} |
||||||
|
|
||||||
|
public Style getImageStyle() { |
||||||
|
return imageStyle; |
||||||
|
} |
||||||
|
|
||||||
|
public void setImageStyle(Style imageStyle) { |
||||||
|
this.imageStyle = imageStyle; |
||||||
|
} |
||||||
|
|
||||||
|
public SwingWorker<Void, Void> getImageWorker() { |
||||||
|
return imageWorker; |
||||||
|
} |
||||||
|
|
||||||
|
public void setImageWorker(SwingWorker<Void, Void> imageWorker) { |
||||||
|
this.imageWorker = imageWorker; |
||||||
|
} |
||||||
|
|
||||||
|
public void dealWithImageFile(int returnVal) { |
||||||
|
if (returnVal != JFileChooser.CANCEL_OPTION) { |
||||||
|
final File selectedFile = imageFileChooser.getSelectedFile(); |
||||||
|
|
||||||
|
if (selectedFile != null && selectedFile.isFile()) { |
||||||
|
if (previewPane != null) { |
||||||
|
previewPane.showLoading(); |
||||||
|
} |
||||||
|
if (imageWorker != null && !imageWorker.isDone()) { |
||||||
|
imageWorker = null; |
||||||
|
} |
||||||
|
imageWorker = new SwingWorker<Void, Void>() { |
||||||
|
@Override |
||||||
|
protected Void doInBackground() throws Exception { |
||||||
|
ImageWithSuffix imageWithSuffix = null; |
||||||
|
if (imageFileChooser.isCheckSelected()) { |
||||||
|
imageWithSuffix = ImageUtils.defaultImageCompWithSuff(selectedFile); |
||||||
|
} else { |
||||||
|
Image image = BaseUtils.readImage(selectedFile.getPath()); |
||||||
|
String type = ImageUtils.getImageType(selectedFile); |
||||||
|
imageWithSuffix = new ImageWithSuffix(image, type); |
||||||
|
} |
||||||
|
|
||||||
|
CoreGraphHelper.waitForImage(imageWithSuffix); |
||||||
|
|
||||||
|
if (previewPane != null) { |
||||||
|
previewPane.setImageStyle(imageStyle); |
||||||
|
previewPane.setImageWithSuffix(imageWithSuffix); |
||||||
|
previewPane.repaint(); |
||||||
|
} |
||||||
|
checkLabelText(); |
||||||
|
fireChangeListener(); |
||||||
|
return null; |
||||||
|
} |
||||||
|
}; |
||||||
|
imageWorker.execute(); |
||||||
|
} else { |
||||||
|
if (previewPane != null) { |
||||||
|
previewPane.setImage(null); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
if (previewPane != null) { |
||||||
|
previewPane.repaint(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void fireChangeListener() { |
||||||
|
if (this.changeListener != null) { |
||||||
|
ChangeEvent evt = new ChangeEvent(this); |
||||||
|
this.changeListener.stateChanged(evt); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void checkLabelText() { |
||||||
|
if (imageSizeLabel == null) { |
||||||
|
return; |
||||||
|
} |
||||||
|
if (selectImage == null) { |
||||||
|
imageSizeLabel.setText(StringUtils.EMPTY); |
||||||
|
} else { |
||||||
|
imageSizeLabel.setText(selectImage.getWidth(null) + "x" |
||||||
|
+ selectImage.getHeight(null) + Inter.getLocText("px")); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -1,4 +1,4 @@ |
|||||||
package com.fr.design.report.freeze; |
package com.fr.design.gui.itextfield; |
||||||
|
|
||||||
import com.fr.design.gui.itextfield.UINumberField; |
import com.fr.design.gui.itextfield.UINumberField; |
||||||
|
|
@ -0,0 +1,196 @@ |
|||||||
|
package com.fr.design.style.background.image; |
||||||
|
|
||||||
|
import com.fr.base.BaseUtils; |
||||||
|
import com.fr.design.DesignerEnvManager; |
||||||
|
import com.fr.design.gui.ibutton.UIButton; |
||||||
|
import com.fr.design.gui.icheckbox.UICheckBox; |
||||||
|
import com.fr.design.layout.FRGUIPaneFactory; |
||||||
|
import com.fr.design.utils.gui.GUICoreUtils; |
||||||
|
import com.fr.general.Inter; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
|
||||||
|
import javax.swing.JDialog; |
||||||
|
import javax.swing.JFileChooser; |
||||||
|
import javax.swing.JPanel; |
||||||
|
import javax.swing.plaf.metal.MetalFileChooserUI; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Component; |
||||||
|
import java.awt.Container; |
||||||
|
import java.awt.Dimension; |
||||||
|
import java.awt.Insets; |
||||||
|
import java.awt.LayoutManager; |
||||||
|
import java.awt.event.ActionListener; |
||||||
|
|
||||||
|
/** |
||||||
|
* 扩展的文件选择框(底部控制区域扩展一个复选框) |
||||||
|
* Created by zack on 2018/3/8. |
||||||
|
*/ |
||||||
|
public class ExpandFileChooser extends JFileChooser { |
||||||
|
private JDialog dialog; |
||||||
|
private UICheckBox checkBox;//选择框底部的复选按钮
|
||||||
|
private int retVal = ERROR_OPTION; |
||||||
|
private UIButton approve; |
||||||
|
private UIButton cancel; |
||||||
|
private static final int DEFAULT_WIDTH = 520; |
||||||
|
|
||||||
|
public ExpandFileChooser() { |
||||||
|
this(StringUtils.EMPTY, StringUtils.EMPTY); |
||||||
|
} |
||||||
|
|
||||||
|
public ExpandFileChooser(String checkBoxText, String approveButtonText) { |
||||||
|
JPanel previewContainerPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||||
|
MetalFileChooserUI chooserUI = (MetalFileChooserUI) getUI(); |
||||||
|
String approveText = StringUtils.isEmpty(approveButtonText) ? chooserUI.getApproveButtonText(this) : approveButtonText; |
||||||
|
dialog = new JDialog(); |
||||||
|
|
||||||
|
dialog.setSize(new Dimension(DEFAULT_WIDTH, 362)); |
||||||
|
dialog.add(previewContainerPane); |
||||||
|
dialog.setIconImage(BaseUtils.readImage("/com/fr/base/images/oem/logo.png")); |
||||||
|
dialog.setTitle(approveText); |
||||||
|
previewContainerPane.add(this, BorderLayout.CENTER); |
||||||
|
|
||||||
|
|
||||||
|
JPanel bottomControlPanel = new JPanel(); |
||||||
|
bottomControlPanel.setLayout(new ImageAreaLayout()); |
||||||
|
bottomControlPanel.setPreferredSize(new Dimension(DEFAULT_WIDTH, 40)); |
||||||
|
|
||||||
|
approve = new UIButton(approveText); |
||||||
|
cancel = new UIButton(Inter.getLocText("FR-Designer_Button-Cancel")); |
||||||
|
if (StringUtils.isNotEmpty(checkBoxText)) { |
||||||
|
checkBox = new UICheckBox(checkBoxText); |
||||||
|
checkBox.setSelected(DesignerEnvManager.getEnvManager().isImageCompress()); |
||||||
|
bottomControlPanel.add(checkBox); |
||||||
|
checkBox.addActionListener(checkAction()); |
||||||
|
} |
||||||
|
bottomControlPanel.add(approve); |
||||||
|
approve.addActionListener(chooserUI.getApproveSelectionAction()); |
||||||
|
cancel.addActionListener(chooserUI.getCancelSelectionAction()); |
||||||
|
bottomControlPanel.add(cancel); |
||||||
|
previewContainerPane.add(bottomControlPanel, BorderLayout.SOUTH); |
||||||
|
GUICoreUtils.centerWindow(dialog); |
||||||
|
} |
||||||
|
|
||||||
|
public ActionListener checkAction() { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isCheckSelected() { |
||||||
|
if (checkBox != null) { |
||||||
|
return checkBox.isSelected(); |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public int showDialog(Component parent, String approveButtonText) { |
||||||
|
dialog.setModal(true); |
||||||
|
dialog.setVisible(true); |
||||||
|
return retVal; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void approveSelection() { |
||||||
|
retVal = APPROVE_OPTION; |
||||||
|
if (dialog != null) { |
||||||
|
dialog.setVisible(false); |
||||||
|
} |
||||||
|
fireActionPerformed(APPROVE_SELECTION); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void cancelSelection() { |
||||||
|
retVal = CANCEL_OPTION; |
||||||
|
if (dialog != null) { |
||||||
|
dialog.setVisible(false); |
||||||
|
} |
||||||
|
fireActionPerformed(CANCEL_SELECTION); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean getControlButtonsAreShown() { |
||||||
|
return false;//隐藏默认的控制按钮(打开/取消)
|
||||||
|
} |
||||||
|
|
||||||
|
private class ImageAreaLayout implements LayoutManager { |
||||||
|
private static final int TEN = 10; |
||||||
|
private int hGap = 5; |
||||||
|
private int topMargin = TEN; |
||||||
|
private int leftMargin = TEN; |
||||||
|
private int leftStart = 8; |
||||||
|
|
||||||
|
@Override |
||||||
|
public void addLayoutComponent(String string, Component comp) { |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void layoutContainer(Container container) { |
||||||
|
Component[] children = container.getComponents(); |
||||||
|
|
||||||
|
if (children != null && children.length > 0) { |
||||||
|
int numChildren = children.length; |
||||||
|
Dimension[] sizes = new Dimension[numChildren]; |
||||||
|
Insets insets = container.getInsets(); |
||||||
|
int yLocation = insets.top + topMargin; |
||||||
|
int maxWidth = 0; |
||||||
|
|
||||||
|
for (int counter = 0; counter < numChildren; counter++) { |
||||||
|
sizes[counter] = children[counter].getPreferredSize(); |
||||||
|
maxWidth = Math.max(maxWidth, sizes[counter].width); |
||||||
|
} |
||||||
|
int xLocation, xOffset; |
||||||
|
if (container.getComponentOrientation().isLeftToRight()) { |
||||||
|
xLocation = container.getSize().width - insets.left - maxWidth - leftMargin; |
||||||
|
xOffset = hGap + maxWidth; |
||||||
|
} else { |
||||||
|
xLocation = insets.left; |
||||||
|
xOffset = -(hGap + maxWidth); |
||||||
|
} |
||||||
|
//单独设置图片压缩按钮的位置
|
||||||
|
children[0].setBounds(leftStart, yLocation, |
||||||
|
maxWidth, sizes[0].height); |
||||||
|
|
||||||
|
for (int counter = numChildren - 1; counter >= 1; counter--) { |
||||||
|
children[counter].setBounds(xLocation, yLocation, |
||||||
|
maxWidth, sizes[counter].height); |
||||||
|
xLocation -= xOffset; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Dimension minimumLayoutSize(Container c) { |
||||||
|
if (c != null) { |
||||||
|
Component[] children = c.getComponents(); |
||||||
|
|
||||||
|
if (children != null && children.length > 0) { |
||||||
|
int numChildren = children.length; |
||||||
|
int height = 0; |
||||||
|
Insets cInsets = c.getInsets(); |
||||||
|
int extraHeight = topMargin + cInsets.top + cInsets.bottom; |
||||||
|
int extraWidth = cInsets.left + cInsets.right; |
||||||
|
int maxWidth = 0; |
||||||
|
|
||||||
|
for (int counter = 0; counter < numChildren; counter++) { |
||||||
|
Dimension aSize = children[counter].getPreferredSize(); |
||||||
|
height = Math.max(height, aSize.height); |
||||||
|
maxWidth = Math.max(maxWidth, aSize.width); |
||||||
|
} |
||||||
|
return new Dimension(extraWidth + numChildren * maxWidth + |
||||||
|
(numChildren - 1) * hGap, |
||||||
|
extraHeight + height); |
||||||
|
} |
||||||
|
} |
||||||
|
return new Dimension(0, 0); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Dimension preferredLayoutSize(Container c) { |
||||||
|
return minimumLayoutSize(c); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void removeLayoutComponent(Component c) { |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,40 @@ |
|||||||
|
package com.fr.design.style.background.image; |
||||||
|
|
||||||
|
import com.fr.base.Style; |
||||||
|
import com.fr.general.ImageWithSuffix; |
||||||
|
|
||||||
|
import java.awt.Image; |
||||||
|
|
||||||
|
/** |
||||||
|
* 图片预览接口(由于子类上层父类差别较大,无奈的接口) |
||||||
|
* Created by zack on 2018/3/10. |
||||||
|
*/ |
||||||
|
public interface ImagePreviewer { |
||||||
|
/** |
||||||
|
* 设置图片样式(平铺,拉伸) |
||||||
|
* @param style 样式 |
||||||
|
*/ |
||||||
|
void setImageStyle(Style style); |
||||||
|
|
||||||
|
/** |
||||||
|
* 设置图片 |
||||||
|
* @param image 图片 |
||||||
|
*/ |
||||||
|
void setImage(Image image); |
||||||
|
|
||||||
|
/** |
||||||
|
* 设置图片(带格式) |
||||||
|
* @param image 图片 |
||||||
|
*/ |
||||||
|
void setImageWithSuffix(ImageWithSuffix image); |
||||||
|
|
||||||
|
/** |
||||||
|
* 显示正在加载 |
||||||
|
*/ |
||||||
|
void showLoading(); |
||||||
|
|
||||||
|
/** |
||||||
|
* 重绘 |
||||||
|
*/ |
||||||
|
void repaint(); |
||||||
|
} |
@ -0,0 +1,285 @@ |
|||||||
|
package com.fr.design.utils; |
||||||
|
|
||||||
|
import com.fr.base.BaseUtils; |
||||||
|
import com.fr.general.ComparatorUtils; |
||||||
|
import com.fr.general.FRLogger; |
||||||
|
import com.fr.general.ImageWithSuffix; |
||||||
|
import com.fr.stable.CoreGraphHelper; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
|
||||||
|
import javax.imageio.IIOImage; |
||||||
|
import javax.imageio.ImageIO; |
||||||
|
import javax.imageio.ImageReader; |
||||||
|
import javax.imageio.ImageWriteParam; |
||||||
|
import javax.imageio.ImageWriter; |
||||||
|
import javax.imageio.stream.ImageInputStream; |
||||||
|
import javax.imageio.stream.ImageOutputStream; |
||||||
|
import java.awt.Graphics; |
||||||
|
import java.awt.Graphics2D; |
||||||
|
import java.awt.Image; |
||||||
|
import java.awt.Transparency; |
||||||
|
import java.awt.image.BufferedImage; |
||||||
|
import java.io.ByteArrayInputStream; |
||||||
|
import java.io.ByteArrayOutputStream; |
||||||
|
import java.io.File; |
||||||
|
import java.io.IOException; |
||||||
|
import java.math.BigDecimal; |
||||||
|
import java.util.Iterator; |
||||||
|
|
||||||
|
/** |
||||||
|
* 设计器部分的图片处理工具类 |
||||||
|
* Created by zack on 2018/3/8. |
||||||
|
*/ |
||||||
|
public class ImageUtils { |
||||||
|
public static final String TYPE_JPEG = "JPEG"; |
||||||
|
public static final String TYPE_PNG = "png"; |
||||||
|
|
||||||
|
/** |
||||||
|
* 默认压缩算法,采用75%质量压缩,带透明度的png默认使用缩放的方式实现压缩尺寸压缩50%,大小大约为1/4 |
||||||
|
* |
||||||
|
* @param imageFile 原文件 |
||||||
|
* @return 压缩后的BufferedImage对象 |
||||||
|
*/ |
||||||
|
public static Image defaultImageCompress(File imageFile) { |
||||||
|
if (imageFile == null || !imageFile.exists()) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
try { |
||||||
|
BufferedImage srcImg = BaseUtils.readImage(imageFile.getPath()); |
||||||
|
if (canbeCompressedToJPEG(imageFile)) { |
||||||
|
return jpegCompress(srcImg, 0.75f); |
||||||
|
} else if (isPNGType(imageFile)) { |
||||||
|
//带透明度的采用缩放的方式
|
||||||
|
return scale(srcImg, 0.5f, true); |
||||||
|
} |
||||||
|
} catch (IOException e) { |
||||||
|
FRLogger.getLogger().info("image compress failed!"); |
||||||
|
|
||||||
|
} |
||||||
|
return BaseUtils.readImage(imageFile.getPath()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 默认压缩算法,返回带格式的image |
||||||
|
* |
||||||
|
* @param imageFile 原文件 |
||||||
|
* @return 压缩后的BufferedImage对象 |
||||||
|
*/ |
||||||
|
public static ImageWithSuffix defaultImageCompWithSuff(File imageFile) { |
||||||
|
if (imageFile == null || !imageFile.exists()) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
BufferedImage srcImg = BaseUtils.readImage(imageFile.getPath()); |
||||||
|
Image desImg = srcImg; |
||||||
|
try { |
||||||
|
|
||||||
|
if (canbeCompressedToJPEG(imageFile)) { |
||||||
|
return new ImageWithSuffix(jpegCompress(srcImg, 0.75f), TYPE_JPEG); |
||||||
|
} else if (isPNGType(imageFile)) { |
||||||
|
//带透明度的采用缩放的方式
|
||||||
|
desImg = scale(srcImg, 0.5f, true); |
||||||
|
} |
||||||
|
} catch (IOException e) { |
||||||
|
FRLogger.getLogger().info("image compress failed!"); |
||||||
|
|
||||||
|
} |
||||||
|
return new ImageWithSuffix(desImg, TYPE_PNG); |
||||||
|
} |
||||||
|
|
||||||
|
public static boolean canbeCompressedToJPEG(File imageFile) { |
||||||
|
String imageType = getImageType(imageFile); |
||||||
|
if (ComparatorUtils.equals(imageType, TYPE_JPEG)) {//JPEG大写
|
||||||
|
return true; |
||||||
|
} |
||||||
|
if (ComparatorUtils.equals(imageType, TYPE_PNG)) {//png小写
|
||||||
|
return !isAlphaAreaOverload(imageFile);//少量透明度系数的png直接压缩jpg
|
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 判断图片是否是png类型 |
||||||
|
* |
||||||
|
* @param imageFile |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static boolean isPNGType(File imageFile) { |
||||||
|
if (ComparatorUtils.equals(getImageType(imageFile), TYPE_PNG)) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* JPEG格式图片压缩 |
||||||
|
* |
||||||
|
* @param image 压缩源图片 |
||||||
|
* @param quality 压缩质量,在0-1之间, |
||||||
|
* @return 返回的字节数组 |
||||||
|
*/ |
||||||
|
public static BufferedImage jpegCompress(BufferedImage image, float quality) throws IOException { |
||||||
|
if (image == null) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
// 得到指定Format图片的writer
|
||||||
|
Iterator<ImageWriter> iter = ImageIO |
||||||
|
.getImageWritersByFormatName("jpeg");// 得到迭代器
|
||||||
|
ImageWriter writer = iter.next(); |
||||||
|
|
||||||
|
// 得到指定writer的输出参数设置(ImageWriteParam )
|
||||||
|
ImageWriteParam iwp = writer.getDefaultWriteParam(); |
||||||
|
iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); // 设置可否压缩
|
||||||
|
iwp.setCompressionQuality(quality); // 设置压缩质量参数
|
||||||
|
iwp.setProgressiveMode(ImageWriteParam.MODE_DISABLED); |
||||||
|
|
||||||
|
// 开始打包图片,写入byte[]
|
||||||
|
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); |
||||||
|
ImageOutputStream ios = null; |
||||||
|
ByteArrayInputStream in = null; |
||||||
|
try { |
||||||
|
image = copy(image, BufferedImage.TYPE_INT_RGB); |
||||||
|
ios = ImageIO.createImageOutputStream(byteArrayOutputStream); |
||||||
|
writer.setOutput(ios); |
||||||
|
writer.write(null, new IIOImage(image, null, null), iwp); |
||||||
|
in = new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); |
||||||
|
if (ios == null || in == null) { |
||||||
|
throw new IOException("The image file cannot be compressed"); |
||||||
|
} |
||||||
|
return ImageIO.read(in); |
||||||
|
} finally { |
||||||
|
writer.dispose(); |
||||||
|
byteArrayOutputStream.close(); |
||||||
|
if (ios != null) { |
||||||
|
ios.close(); |
||||||
|
} |
||||||
|
if (in != null) { |
||||||
|
in.close(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 判断图片中是否包含多于5%的透明区域,这个5%随便定的 |
||||||
|
* |
||||||
|
* @param imageFile 目标图片 |
||||||
|
* @return 含透明度像素占比 |
||||||
|
*/ |
||||||
|
public static boolean isAlphaAreaOverload(File imageFile) { |
||||||
|
if (imageFile == null || !imageFile.isFile()) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
BufferedImage bufferedImage = BaseUtils.readImage(imageFile.getPath()); |
||||||
|
int width = bufferedImage.getWidth(); |
||||||
|
int height = bufferedImage.getHeight(); |
||||||
|
long alphaCount = 0; |
||||||
|
for (int i = 0; i < width; i++) { |
||||||
|
for (int j = 0; j < height; j++) { |
||||||
|
int rgb = bufferedImage.getRGB(i, j); |
||||||
|
int a = (0xff & (rgb >> 24)); |
||||||
|
if (a != 0xff) { |
||||||
|
alphaCount++; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return alphaCount / (double) (width * height) > 0.05; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取图片类型 |
||||||
|
* |
||||||
|
* @param imageFile 图片文件 |
||||||
|
* @return 图片类型(JPEG, PNG, GIF) |
||||||
|
*/ |
||||||
|
public static String getImageType(File imageFile) { |
||||||
|
try { |
||||||
|
ImageInputStream iis = ImageIO.createImageInputStream(imageFile); |
||||||
|
Iterator<ImageReader> iter = ImageIO.getImageReaders(iis); |
||||||
|
if (!iter.hasNext()) { |
||||||
|
return StringUtils.EMPTY; |
||||||
|
} |
||||||
|
ImageReader reader = iter.next(); |
||||||
|
iis.close(); |
||||||
|
return reader.getFormatName(); |
||||||
|
} catch (IOException ignore) { |
||||||
|
} |
||||||
|
return StringUtils.EMPTY; |
||||||
|
} |
||||||
|
|
||||||
|
private static BufferedImage copy(BufferedImage img, int imageType) { |
||||||
|
int width = img.getWidth(); |
||||||
|
int height = img.getHeight(); |
||||||
|
|
||||||
|
BufferedImage newImage = CoreGraphHelper.createBufferedImage(width, height, imageType); |
||||||
|
Graphics g = newImage.createGraphics(); |
||||||
|
|
||||||
|
g.drawImage(img, 0, 0, null); |
||||||
|
|
||||||
|
g.dispose(); |
||||||
|
|
||||||
|
return newImage; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 缩放图像(按比例缩放) |
||||||
|
* |
||||||
|
* @param srcImg 源图像来源流 |
||||||
|
* @param scale 缩放比例。比例大于1时为放大,小于1大于0为缩小 |
||||||
|
* @param opacityCompatible 是否处理背景透明 |
||||||
|
*/ |
||||||
|
public static Image scale(BufferedImage srcImg, float scale, boolean opacityCompatible) { |
||||||
|
if (scale < 0) { |
||||||
|
// 自动修正负数
|
||||||
|
scale = -scale; |
||||||
|
} |
||||||
|
|
||||||
|
int width = mul(Integer.toString(srcImg.getWidth(null)), Float.toString(scale)).intValue(); // 得到源图宽
|
||||||
|
int height = mul(Integer.toString(srcImg.getHeight(null)), Float.toString(scale)).intValue(); // 得到源图长
|
||||||
|
return scale(srcImg, width, height, opacityCompatible); |
||||||
|
} |
||||||
|
|
||||||
|
private static BigDecimal mul(String v1, String v2) { |
||||||
|
return mul(new BigDecimal(v1), new BigDecimal(v2)); |
||||||
|
} |
||||||
|
|
||||||
|
private static BigDecimal mul(BigDecimal v1, BigDecimal v2) { |
||||||
|
return v1.multiply(v2); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 缩放图像(按长宽缩放) |
||||||
|
* 目标长宽与原图不成比例会变形 |
||||||
|
* |
||||||
|
* @param srcImg 源图像来源流 |
||||||
|
* @param width 目标宽度 |
||||||
|
* @param height 目标高度 |
||||||
|
* @param opacityCompatible 是否处理背景透明 |
||||||
|
* @return {@link Image} |
||||||
|
*/ |
||||||
|
private static Image scale(BufferedImage srcImg, int width, int height, boolean opacityCompatible) { |
||||||
|
int srcHeight = srcImg.getHeight(null); |
||||||
|
int srcWidth = srcImg.getWidth(null); |
||||||
|
int scaleType; |
||||||
|
if (srcHeight == height && srcWidth == width) { |
||||||
|
// 源与目标长宽一致返回原图
|
||||||
|
return srcImg; |
||||||
|
} else if (srcHeight < height || srcWidth < width) { |
||||||
|
// 放大图片使用平滑模式
|
||||||
|
scaleType = Image.SCALE_SMOOTH; |
||||||
|
} else { |
||||||
|
scaleType = Image.SCALE_DEFAULT; |
||||||
|
} |
||||||
|
if (opacityCompatible) {//需要保留透明度背景
|
||||||
|
BufferedImage toImg = CoreGraphHelper.createBufferedImage(width, height, srcImg.getType()); |
||||||
|
Graphics2D g2d = toImg.createGraphics(); |
||||||
|
toImg = g2d.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT); |
||||||
|
g2d.dispose(); |
||||||
|
|
||||||
|
g2d = toImg.createGraphics(); |
||||||
|
Image from = srcImg.getScaledInstance(width, height, scaleType); |
||||||
|
g2d.drawImage(from, 0, 0, null); |
||||||
|
g2d.dispose(); |
||||||
|
return toImg; |
||||||
|
} |
||||||
|
return srcImg.getScaledInstance(width, height, scaleType); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,47 @@ |
|||||||
|
package com.fr.design.widget.mobile; |
||||||
|
|
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.layout.FRGUIPaneFactory; |
||||||
|
import com.fr.form.ui.Widget; |
||||||
|
import com.fr.general.Inter; |
||||||
|
|
||||||
|
import javax.swing.BorderFactory; |
||||||
|
import javax.swing.JPanel; |
||||||
|
import javax.swing.SwingConstants; |
||||||
|
|
||||||
|
/** |
||||||
|
* 单元格控件的"移动端"面板。默认显示"无可用配置项",在子类中扩展 |
||||||
|
* Created by plough on 2018/4/25. |
||||||
|
*/ |
||||||
|
public class WidgetMobilePane extends JPanel { |
||||||
|
public static WidgetMobilePane DEFAULT_PANE = new WidgetMobilePane(); |
||||||
|
|
||||||
|
public WidgetMobilePane() { |
||||||
|
this.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); |
||||||
|
init(); |
||||||
|
} |
||||||
|
|
||||||
|
protected void init() { |
||||||
|
this.setLayout(FRGUIPaneFactory.createBorderLayout()); |
||||||
|
UILabel label = new UILabel(Inter.getLocText("FR-Designer_No_Settings_Available")); |
||||||
|
label.setHorizontalAlignment(SwingConstants.CENTER); |
||||||
|
this.add(label); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 从 widget 中提取数据展示在属性面板中 |
||||||
|
* |
||||||
|
* @param widget |
||||||
|
*/ |
||||||
|
public void populate(Widget widget) { |
||||||
|
// do nothing
|
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 从属性面板把数据保存到 widget 中 |
||||||
|
* @param widget |
||||||
|
*/ |
||||||
|
public void update(Widget widget) { |
||||||
|
// do nothing
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,145 @@ |
|||||||
|
package com.fr.env; |
||||||
|
|
||||||
|
import com.fr.core.env.resource.RemoteEnvConfig; |
||||||
|
import com.fr.design.beans.BasicBeanPane; |
||||||
|
import com.fr.design.border.UITitledBorder; |
||||||
|
import com.fr.design.gui.ibutton.UIButton; |
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.gui.ipasswordfield.UIPassWordField; |
||||||
|
import com.fr.design.gui.itextfield.UIIntNumberField; |
||||||
|
import com.fr.design.gui.itextfield.UITextField; |
||||||
|
import com.fr.design.layout.TableLayout; |
||||||
|
import com.fr.design.layout.TableLayoutHelper; |
||||||
|
import com.fr.design.utils.gui.GUICoreUtils; |
||||||
|
import com.fr.general.Inter; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
|
||||||
|
import javax.swing.*; |
||||||
|
import javax.swing.border.EmptyBorder; |
||||||
|
import java.awt.*; |
||||||
|
import java.awt.event.ActionEvent; |
||||||
|
import java.awt.event.ActionListener; |
||||||
|
import java.util.concurrent.ExecutionException; |
||||||
|
|
||||||
|
/** |
||||||
|
* 远程环境设置界面,暂时命名为2,待做完功能直接替代掉老的RemoteEnvPane |
||||||
|
*/ |
||||||
|
public class RemoteEnvPane2 extends BasicBeanPane<RemoteEnvConfig> { |
||||||
|
|
||||||
|
private UITextField hostTextField; |
||||||
|
private UIIntNumberField portTextField; |
||||||
|
private UITextField usernameTextField; |
||||||
|
private UIPassWordField passwordTextField; |
||||||
|
|
||||||
|
public RemoteEnvPane2() { |
||||||
|
initComponents(); |
||||||
|
} |
||||||
|
|
||||||
|
private void initComponents() { |
||||||
|
setLayout(new BorderLayout()); |
||||||
|
|
||||||
|
JPanel contentPanel = new JPanel(new BorderLayout()); |
||||||
|
add(contentPanel, BorderLayout.CENTER); |
||||||
|
|
||||||
|
contentPanel.setBorder( |
||||||
|
BorderFactory.createCompoundBorder( |
||||||
|
new EmptyBorder(6, 0, 0, 0), |
||||||
|
UITitledBorder.createBorderWithTitle(Inter.getLocText("Fine-Designer_Basic_Remote_Env_Config"))) |
||||||
|
); |
||||||
|
|
||||||
|
double p = TableLayout.PREFERRED; |
||||||
|
double f = TableLayout.FILL; |
||||||
|
double[] rowSize = new double[]{p, p, p, p, p}; |
||||||
|
double[] columnSize = new double[]{p, f}; |
||||||
|
UIButton testConnectionButton = new UIButton(Inter.getLocText("Fine-Designer_Basic_Remote_Env_Try")); |
||||||
|
hostTextField = new UITextField(); |
||||||
|
hostTextField.setPlaceholder("192.168.100.200"); |
||||||
|
portTextField = new UIIntNumberField(); |
||||||
|
portTextField.setPlaceholder("39999"); |
||||||
|
JPanel valuePane = TableLayoutHelper.createTableLayoutPane( |
||||||
|
new Component[][]{ |
||||||
|
{new UILabel(Inter.getLocText("Fine-Designer_Basic_Remote_Env_Host") + ":", SwingConstants.RIGHT), hostTextField}, |
||||||
|
{new UILabel(Inter.getLocText("Fine-Designer_Basic_Remote_Env_Port") + ":", SwingConstants.RIGHT),portTextField}, |
||||||
|
{new UILabel(Inter.getLocText("Fine-Designer_Basic_Remote_Env_User") + ":", SwingConstants.RIGHT), usernameTextField = new UITextField()}, |
||||||
|
{new UILabel(Inter.getLocText("Fine-Designer_Basic_Remote_Env_Password") + ":", SwingConstants.RIGHT), passwordTextField = new UIPassWordField()}, |
||||||
|
{null, GUICoreUtils.createFlowPane(testConnectionButton, FlowLayout.LEFT)} |
||||||
|
}, |
||||||
|
rowSize, columnSize |
||||||
|
); |
||||||
|
testConnectionButton.addActionListener(new ActionListener() { |
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
tryConnectRemoteEnv(); |
||||||
|
} |
||||||
|
}); |
||||||
|
contentPanel.add(valuePane, BorderLayout.CENTER); |
||||||
|
} |
||||||
|
|
||||||
|
private void tryConnectRemoteEnv() { |
||||||
|
final RemoteEnv remoteEnv = new RemoteEnv(this.updateBean()); |
||||||
|
new SwingWorker<Void, Void>() { |
||||||
|
|
||||||
|
@Override |
||||||
|
protected Void doInBackground() throws Exception { |
||||||
|
remoteEnv.connectOnce(); |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void done() { |
||||||
|
try { |
||||||
|
get(); |
||||||
|
showConnectMessage(); |
||||||
|
} catch (Exception e) { |
||||||
|
showCannotConnectMessage(); |
||||||
|
} |
||||||
|
} |
||||||
|
}.execute(); |
||||||
|
} |
||||||
|
|
||||||
|
private void showCannotConnectMessage() { |
||||||
|
JOptionPane.showMessageDialog( |
||||||
|
this, |
||||||
|
Inter.getLocText("Fine-Designer_Basic_Remote_Connect_Failed"), |
||||||
|
UIManager.getString("OptionPane.messageDialogTitle", this.getLocale()), |
||||||
|
JOptionPane.ERROR_MESSAGE |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
private void showConnectMessage() { |
||||||
|
JOptionPane.showMessageDialog( |
||||||
|
this, |
||||||
|
Inter.getLocText("Fine-Designer_Basic_Remote_Connect_Successful"), |
||||||
|
UIManager.getString("OptionPane.messageDialogTitle", this.getLocale()), |
||||||
|
JOptionPane.INFORMATION_MESSAGE |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String title4PopupWindow() { |
||||||
|
return "RemoteEnv"; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void populateBean(RemoteEnvConfig config) { |
||||||
|
if (config == null) { |
||||||
|
return; |
||||||
|
} |
||||||
|
hostTextField.setText(config.getPath()); |
||||||
|
if (config.getPort() != 0) { |
||||||
|
portTextField.setValue(config.getPort()); |
||||||
|
} |
||||||
|
usernameTextField.setText(config.getUsername()); |
||||||
|
passwordTextField.setText(config.getPassword()); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public RemoteEnvConfig updateBean() { |
||||||
|
RemoteEnvConfig config = new RemoteEnvConfig(); |
||||||
|
config.setHost(hostTextField.getText()); |
||||||
|
config.setPort((int) portTextField.getValue()); |
||||||
|
config.setUsername(usernameTextField.getText()); |
||||||
|
config.setPassword(passwordTextField.getText()); |
||||||
|
return config; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,36 @@ |
|||||||
|
package com.fr.design.designer.properties.mobile; |
||||||
|
|
||||||
|
import com.fr.design.designer.creator.XChartEditor; |
||||||
|
import com.fr.design.designer.creator.XCreator; |
||||||
|
import com.fr.design.dialog.BasicPane; |
||||||
|
import com.fr.design.fun.impl.AbstractWidgetPropertyUIProvider; |
||||||
|
import com.fr.design.gui.itable.AbstractPropertyTable; |
||||||
|
import com.fr.design.widget.ui.designer.mobile.ChartEditorDefinePane; |
||||||
|
import com.fr.general.Inter; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by plough on 2018/1/18. |
||||||
|
*/ |
||||||
|
public class ChartEditorPropertyUI extends AbstractWidgetPropertyUIProvider { |
||||||
|
|
||||||
|
private XCreator xCreator; |
||||||
|
|
||||||
|
public ChartEditorPropertyUI(XChartEditor xChartEditor) { |
||||||
|
this.xCreator = xChartEditor; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public AbstractPropertyTable createWidgetAttrTable() { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public BasicPane createWidgetAttrPane() { |
||||||
|
return new ChartEditorDefinePane(xCreator); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String tableTitle() { |
||||||
|
return Inter.getLocText("FR-Designer_Mobile-Attr"); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,36 @@ |
|||||||
|
package com.fr.design.designer.properties.mobile; |
||||||
|
|
||||||
|
import com.fr.design.designer.creator.XCreator; |
||||||
|
import com.fr.design.designer.creator.XWParameterLayout; |
||||||
|
import com.fr.design.dialog.BasicPane; |
||||||
|
import com.fr.design.fun.impl.AbstractWidgetPropertyUIProvider; |
||||||
|
import com.fr.design.gui.itable.AbstractPropertyTable; |
||||||
|
import com.fr.design.widget.ui.designer.mobile.ParaMobileDefinePane; |
||||||
|
import com.fr.general.Inter; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by Administrator on 2016/5/16/0016. |
||||||
|
*/ |
||||||
|
public class ParaMobilePropertyUI extends AbstractWidgetPropertyUIProvider { |
||||||
|
|
||||||
|
private XCreator xCreator; |
||||||
|
|
||||||
|
public ParaMobilePropertyUI(XWParameterLayout xwParameterLayout) { |
||||||
|
this.xCreator = xwParameterLayout; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public AbstractPropertyTable createWidgetAttrTable() { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public BasicPane createWidgetAttrPane() { |
||||||
|
return new ParaMobileDefinePane(xCreator); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String tableTitle() { |
||||||
|
return Inter.getLocText("FR-Designer_Mobile-Attr"); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,71 @@ |
|||||||
|
package com.fr.design.mainframe; |
||||||
|
|
||||||
|
import com.fr.design.designer.creator.XCreator; |
||||||
|
import com.fr.design.gui.controlpane.UISimpleListControlPane; |
||||||
|
import com.fr.form.ui.Widget; |
||||||
|
import com.fr.form.ui.container.WSortLayout; |
||||||
|
import com.fr.general.NameObject; |
||||||
|
import com.fr.stable.ArrayUtils; |
||||||
|
import com.fr.stable.Nameable; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by plough on 2018/1/31. |
||||||
|
*/ |
||||||
|
public class MobileWidgetListPane extends UISimpleListControlPane { |
||||||
|
public static final String LIST_NAME = "Widget_List"; |
||||||
|
|
||||||
|
private FormDesigner designer; |
||||||
|
private WSortLayout wSortLayout; |
||||||
|
private String[] widgetNameList; |
||||||
|
|
||||||
|
public MobileWidgetListPane(FormDesigner designer, WSortLayout wSortLayout) { |
||||||
|
super(); |
||||||
|
this.designer = designer; |
||||||
|
this.wSortLayout = wSortLayout; |
||||||
|
widgetNameList = getData(); |
||||||
|
|
||||||
|
List<NameObject> nameObjectList = new ArrayList<NameObject>(); |
||||||
|
for (String name : widgetNameList) { |
||||||
|
nameObjectList.add(new NameObject(name, null)); |
||||||
|
} |
||||||
|
populate(nameObjectList.toArray(new NameObject[nameObjectList.size()])); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 保存移动端控件列表顺序 |
||||||
|
*/ |
||||||
|
public void updateToDesigner() { |
||||||
|
Nameable[] nameableList = update(); |
||||||
|
List<String> newMobileWidgetList = new ArrayList<>(); |
||||||
|
for (Nameable nameable : nameableList) { |
||||||
|
newMobileWidgetList.add(nameable.getName()); |
||||||
|
} |
||||||
|
wSortLayout.updateSortedMobileWidgetList(newMobileWidgetList); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取选中控件的控件列表 |
||||||
|
* |
||||||
|
* @return List<String> widgetNameList |
||||||
|
*/ |
||||||
|
private String[] getData() { |
||||||
|
//选择的控件
|
||||||
|
XCreator selectedCreator = designer.getSelectionModel().getSelection().getSelectedCreator(); |
||||||
|
Widget selectedModel = selectedCreator != null ? selectedCreator.toData() : null; |
||||||
|
|
||||||
|
if (selectedModel == null || !selectedModel.acceptType(WSortLayout.class)) { |
||||||
|
return ArrayUtils.EMPTY_STRING_ARRAY; |
||||||
|
} |
||||||
|
|
||||||
|
// 选择的控件有两种类型,一种是WLayout,代表容器,一种是Widget,代表控件
|
||||||
|
List<String> mobileWidgetList = ((WSortLayout) selectedModel).getOrderedMobileWidgetList(); |
||||||
|
String[] widgetNames = new String[mobileWidgetList.size()]; |
||||||
|
for (int i = 0; i < mobileWidgetList.size(); i++) { |
||||||
|
widgetNames[i] = mobileWidgetList.get(i); |
||||||
|
} |
||||||
|
return widgetNames; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,124 @@ |
|||||||
|
package com.fr.design.widget.ui.designer.mobile; |
||||||
|
|
||||||
|
import com.fr.design.designer.beans.events.DesignerEvent; |
||||||
|
import com.fr.design.designer.creator.XCreator; |
||||||
|
import com.fr.design.foldablepane.UIExpandablePane; |
||||||
|
import com.fr.design.gui.frpane.AttributeChangeListener; |
||||||
|
import com.fr.design.gui.icheckbox.UICheckBox; |
||||||
|
import com.fr.design.layout.FRGUIPaneFactory; |
||||||
|
import com.fr.design.mainframe.FormDesigner; |
||||||
|
import com.fr.design.mainframe.MobileWidgetListPane; |
||||||
|
import com.fr.design.mainframe.WidgetPropertyPane; |
||||||
|
import com.fr.form.ui.container.WSortLayout; |
||||||
|
import com.fr.general.Inter; |
||||||
|
|
||||||
|
import javax.swing.BorderFactory; |
||||||
|
import javax.swing.JPanel; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.lang.reflect.Method; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by plough on 2018/2/1. |
||||||
|
*/ |
||||||
|
public class BodyMobileDefinePane extends MobileWidgetDefinePane { |
||||||
|
private XCreator bodyCreator; |
||||||
|
private FormDesigner designer; |
||||||
|
private AttributeChangeListener changeListener; |
||||||
|
private UICheckBox appRelayoutCheck; |
||||||
|
private MobileWidgetListPane mobileWidgetListPane; |
||||||
|
|
||||||
|
public BodyMobileDefinePane(XCreator xCreator) { |
||||||
|
this.bodyCreator = xCreator; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void initPropertyGroups(Object source) { |
||||||
|
this.setLayout(FRGUIPaneFactory.createBorderLayout()); |
||||||
|
this.designer = WidgetPropertyPane.getInstance().getEditingFormDesigner(); |
||||||
|
this.add(getMobilePropertyPane(), BorderLayout.NORTH); |
||||||
|
this.add(getMobileWidgetListPane(), BorderLayout.CENTER); |
||||||
|
this.repaint(); |
||||||
|
} |
||||||
|
|
||||||
|
// 手机属性
|
||||||
|
private UIExpandablePane getMobilePropertyPane() { |
||||||
|
JPanel panel = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||||
|
appRelayoutCheck = new UICheckBox(Inter.getLocText("FR-Designer-App_ReLayout"), true); |
||||||
|
appRelayoutCheck.setBorder(BorderFactory.createEmptyBorder(0, 0, 10, 0)); |
||||||
|
panel.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0)); |
||||||
|
panel.add(appRelayoutCheck); |
||||||
|
|
||||||
|
final JPanel panelWrapper = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||||
|
panelWrapper.add(panel, BorderLayout.NORTH); |
||||||
|
|
||||||
|
return new UIExpandablePane(Inter.getLocText("FR-Designer_Properties_Mobile"), 280, 20, panelWrapper); |
||||||
|
} |
||||||
|
|
||||||
|
// 控件顺序
|
||||||
|
private UIExpandablePane getMobileWidgetListPane() { |
||||||
|
mobileWidgetListPane = new MobileWidgetListPane(designer, (WSortLayout) bodyCreator.toData()); |
||||||
|
mobileWidgetListPane.setBorder(BorderFactory.createEmptyBorder(10, 0, 5, 0)); |
||||||
|
JPanel panelWrapper = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||||
|
panelWrapper.add(mobileWidgetListPane, BorderLayout.CENTER); |
||||||
|
|
||||||
|
return new UIExpandablePane(Inter.getLocText("FR-Designer_WidgetOrder"), 280, 20, panelWrapper); |
||||||
|
} |
||||||
|
|
||||||
|
private void bindListeners2Widgets() { |
||||||
|
reInitAllListeners(); |
||||||
|
this.changeListener = new AttributeChangeListener() { |
||||||
|
@Override |
||||||
|
public void attributeChange() { |
||||||
|
update(); |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 后台初始化所有事件. |
||||||
|
*/ |
||||||
|
private void reInitAllListeners() { |
||||||
|
initListener(this); |
||||||
|
} |
||||||
|
|
||||||
|
// body是否开启手机重布局
|
||||||
|
private boolean isAppRelayout() { |
||||||
|
boolean result = false; |
||||||
|
try { |
||||||
|
Method m = bodyCreator.toData().getClass().getMethod("isAppRelayout"); |
||||||
|
result = (boolean)m.invoke(bodyCreator.toData()); |
||||||
|
} catch (Exception e) { |
||||||
|
// do nothing
|
||||||
|
} |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
private void setAppRelayout(boolean appRelayoutSeleted) { |
||||||
|
if (appRelayoutSeleted == isAppRelayout()) { |
||||||
|
return; |
||||||
|
} |
||||||
|
try { |
||||||
|
Method m = bodyCreator.toData().getClass().getMethod("setAppRelayout", boolean.class); |
||||||
|
m.invoke(bodyCreator.toData(), appRelayoutSeleted); |
||||||
|
} catch (Exception e) { |
||||||
|
// do nothing
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void populate(FormDesigner designer) { |
||||||
|
this.designer = designer; |
||||||
|
appRelayoutCheck.setSelected(isAppRelayout()); |
||||||
|
|
||||||
|
// 数据 populate 完成后,再设置监听
|
||||||
|
this.bindListeners2Widgets(); |
||||||
|
this.addAttributeChangeListener(changeListener); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void update() { |
||||||
|
setAppRelayout(appRelayoutCheck.isSelected()); |
||||||
|
mobileWidgetListPane.updateToDesigner(); |
||||||
|
designer.getEditListenerTable().fireCreatorModified(DesignerEvent.CREATOR_EDITED); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,196 @@ |
|||||||
|
package com.fr.design.widget.ui.designer.mobile; |
||||||
|
|
||||||
|
import com.fr.base.mobile.ChartMobileAttrProvider; |
||||||
|
import com.fr.base.mobile.ChartMobileFitAttrState; |
||||||
|
import com.fr.base.mobile.ChartMobileFitAttrStateProvider; |
||||||
|
import com.fr.design.constants.LayoutConstants; |
||||||
|
import com.fr.design.designer.creator.XCreator; |
||||||
|
import com.fr.design.designer.creator.XWAbsoluteBodyLayout; |
||||||
|
import com.fr.design.designer.creator.XWAbsoluteLayout; |
||||||
|
import com.fr.design.designer.properties.items.Item; |
||||||
|
import com.fr.design.foldablepane.UIExpandablePane; |
||||||
|
import com.fr.design.gui.frpane.AttributeChangeListener; |
||||||
|
import com.fr.design.gui.icombobox.UIComboBox; |
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.layout.FRGUIPaneFactory; |
||||||
|
import com.fr.design.layout.TableLayout; |
||||||
|
import com.fr.design.layout.TableLayoutHelper; |
||||||
|
import com.fr.design.mainframe.DesignerContext; |
||||||
|
import com.fr.design.mainframe.FormDesigner; |
||||||
|
import com.fr.design.mainframe.WidgetPropertyPane; |
||||||
|
import com.fr.form.FormFunctionProcessor; |
||||||
|
import com.fr.form.ui.BaseChartEditor; |
||||||
|
import com.fr.form.ui.container.WFitLayout; |
||||||
|
import com.fr.general.Inter; |
||||||
|
import com.fr.plugin.ExtraClassManager; |
||||||
|
import com.fr.stable.fun.FunctionProcessor; |
||||||
|
|
||||||
|
import javax.swing.BorderFactory; |
||||||
|
import javax.swing.JPanel; |
||||||
|
import javax.swing.SwingConstants; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Color; |
||||||
|
import java.awt.Component; |
||||||
|
import java.awt.Container; |
||||||
|
import java.awt.event.ItemEvent; |
||||||
|
import java.awt.event.ItemListener; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by plough on 2018/1/18. |
||||||
|
*/ |
||||||
|
public class ChartEditorDefinePane extends MobileWidgetDefinePane { |
||||||
|
private static final Item[] ITEMS = { |
||||||
|
new Item(ChartMobileFitAttrState.AUTO.description(), ChartMobileFitAttrState.AUTO), |
||||||
|
new Item(ChartMobileFitAttrState.AREA.description(), ChartMobileFitAttrState.AREA), |
||||||
|
new Item(ChartMobileFitAttrState.PROPORTION.description(), ChartMobileFitAttrState.PROPORTION) |
||||||
|
}; |
||||||
|
|
||||||
|
private XCreator xCreator; // 当前选中控件的xCreator
|
||||||
|
private FormDesigner designer; // 当前设计器
|
||||||
|
private UIComboBox zoomOutComboBox;// 缩小逻辑下拉框
|
||||||
|
private AttributeChangeListener changeListener; |
||||||
|
private UILabel tipLabel; |
||||||
|
|
||||||
|
public ChartEditorDefinePane(XCreator xCreator) { |
||||||
|
this.xCreator = xCreator; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void initPropertyGroups(Object source) { |
||||||
|
this.setLayout(FRGUIPaneFactory.createBorderLayout()); |
||||||
|
this.designer = WidgetPropertyPane.getInstance().getEditingFormDesigner(); |
||||||
|
JPanel mobileSettingsPane; |
||||||
|
if (isInAbsoluteLayout()) { |
||||||
|
mobileSettingsPane = getUnavailableTipPane(Inter.getLocText("FR-Designer_Tip_Chart_Adaptivity_Unavailable_In_Absolute_Layout")); |
||||||
|
} else if (!isAppRelayout()) { |
||||||
|
mobileSettingsPane = getUnavailableTipPane(Inter.getLocText("FR-Designer_Tip_Chart_Adaptivity_Unavailable")); |
||||||
|
} else { |
||||||
|
mobileSettingsPane = getMobileSettingsPane(); |
||||||
|
} |
||||||
|
this.add(mobileSettingsPane, BorderLayout.NORTH); |
||||||
|
this.repaint(); |
||||||
|
} |
||||||
|
|
||||||
|
private boolean isInAbsoluteLayout() { |
||||||
|
Container parent = xCreator.getParent(); |
||||||
|
while (parent != null) { |
||||||
|
if (parent instanceof XWAbsoluteLayout && !(parent instanceof XWAbsoluteBodyLayout)) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
parent = parent.getParent(); |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
// body是否开启手机重布局
|
||||||
|
private boolean isAppRelayout() { |
||||||
|
return ((WFitLayout)designer.getRootComponent().toData()).isAppRelayout(); |
||||||
|
} |
||||||
|
|
||||||
|
private JPanel getUnavailableTipPane(String tipText) { |
||||||
|
JPanel panel = new JPanel(new BorderLayout()); |
||||||
|
UILabel unavailableTipLabel = new UILabel(); |
||||||
|
unavailableTipLabel.setText("<html>" + tipText + "<html>"); |
||||||
|
unavailableTipLabel.setForeground(Color.gray); |
||||||
|
panel.add(unavailableTipLabel, BorderLayout.NORTH); |
||||||
|
return panel; |
||||||
|
} |
||||||
|
|
||||||
|
private UIExpandablePane getMobileSettingsPane() { |
||||||
|
initZoomOutComboBox(); |
||||||
|
|
||||||
|
tipLabel = new UILabel(); |
||||||
|
tipLabel.setForeground(Color.gray); |
||||||
|
updateTipLabel(); |
||||||
|
|
||||||
|
Component[][] components = new Component[][]{ |
||||||
|
new Component[] {new UILabel(Inter.getLocText("FR-Designer_Zoom_In_Logic"), SwingConstants.LEFT), new UILabel(ChartMobileFitAttrState.PROPORTION.description())}, |
||||||
|
new Component[] {new UILabel(Inter.getLocText("FR-Designer_Zoom_Out_Logic"), SwingConstants.LEFT), zoomOutComboBox}, |
||||||
|
new Component[] {tipLabel, null} |
||||||
|
}; |
||||||
|
|
||||||
|
double f = TableLayout.FILL; |
||||||
|
double p = TableLayout.PREFERRED; |
||||||
|
double[] rowSize = {p, p, p}; |
||||||
|
double[] columnSize = {p,f}; |
||||||
|
int[][] rowCount = {{1, 1}, {1, 1}, {1, 1}}; |
||||||
|
final JPanel panel = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, 30, LayoutConstants.VGAP_LARGE); |
||||||
|
panel.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0)); |
||||||
|
final JPanel panelWrapper = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||||
|
panelWrapper.add(panel, BorderLayout.NORTH); |
||||||
|
|
||||||
|
return new UIExpandablePane(Inter.getLocText("FR-Designer_Chart_Adaptivity"), 280, 20, panelWrapper); |
||||||
|
} |
||||||
|
|
||||||
|
private void initZoomOutComboBox() { |
||||||
|
this.zoomOutComboBox = new UIComboBox(ITEMS); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private void updateTipLabel() { |
||||||
|
ChartMobileFitAttrState fitAttrState = (ChartMobileFitAttrState) ((Item)zoomOutComboBox.getSelectedItem()).getValue(); |
||||||
|
// 使用 html,可以自动换行
|
||||||
|
tipLabel.setText("<html>" + fitAttrState.tip() + "</html>"); |
||||||
|
} |
||||||
|
|
||||||
|
private void bindListeners2Widgets() { |
||||||
|
reInitAllListeners(); |
||||||
|
this.changeListener = new AttributeChangeListener() { |
||||||
|
@Override |
||||||
|
public void attributeChange() { |
||||||
|
update(); |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 后台初始化所有事件. |
||||||
|
*/ |
||||||
|
private void reInitAllListeners() { |
||||||
|
initListener(this); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void populate(FormDesigner designer) { |
||||||
|
this.designer = designer; |
||||||
|
|
||||||
|
if (!isAppRelayout() || isInAbsoluteLayout()) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
BaseChartEditor chartEditor = (BaseChartEditor)xCreator.toData(); |
||||||
|
ChartMobileFitAttrStateProvider zoomOutAttr = chartEditor.getMobileAttr().getZoomOutAttr(); |
||||||
|
this.zoomOutComboBox.setSelectedItem(new Item(zoomOutAttr.description(), zoomOutAttr)); |
||||||
|
updateTipLabel(); |
||||||
|
|
||||||
|
// 数据 populate 完成后,再设置监听
|
||||||
|
this.bindListeners2Widgets(); |
||||||
|
this.zoomOutComboBox.addItemListener(new ItemListener() { |
||||||
|
@Override |
||||||
|
public void itemStateChanged(ItemEvent e) { |
||||||
|
// 只响应选中事件
|
||||||
|
if (e.getStateChange() != ItemEvent.SELECTED) { |
||||||
|
return; |
||||||
|
} |
||||||
|
updateTipLabel(); |
||||||
|
ChartMobileFitAttrState selectedAttr = (ChartMobileFitAttrState)((Item)e.getItem()).getValue(); |
||||||
|
if (selectedAttr.getState() != ChartMobileFitAttrState.AUTO.getState()) { |
||||||
|
// 功能埋点
|
||||||
|
FunctionProcessor processor = ExtraClassManager.getInstance().getFunctionProcessor(); |
||||||
|
if (processor != null) { |
||||||
|
processor.recordFunction(FormFunctionProcessor.MOBILE_CHART_ADAPTIVITY); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
this.addAttributeChangeListener(changeListener); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void update() { |
||||||
|
ChartMobileAttrProvider mobileAttr = ((BaseChartEditor)xCreator.toData()).getMobileAttr(); |
||||||
|
mobileAttr.setZoomInAttr(ChartMobileFitAttrState.PROPORTION); |
||||||
|
mobileAttr.setZoomOutAttr((ChartMobileFitAttrState)((Item)zoomOutComboBox.getSelectedItem()).getValue()); |
||||||
|
DesignerContext.getDesignerFrame().getSelectedJTemplate().fireTargetModified(); // 触发设计器保存按钮亮起来
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,110 @@ |
|||||||
|
package com.fr.design.widget.ui.designer.mobile; |
||||||
|
|
||||||
|
import com.fr.base.mobile.FileUploadModeState; |
||||||
|
import com.fr.base.mobile.MultiFileUploaderMobileAttr; |
||||||
|
import com.fr.design.constants.LayoutConstants; |
||||||
|
import com.fr.design.designer.creator.XCreator; |
||||||
|
import com.fr.design.designer.properties.items.Item; |
||||||
|
import com.fr.design.foldablepane.UIExpandablePane; |
||||||
|
import com.fr.design.gui.frpane.AttributeChangeListener; |
||||||
|
import com.fr.design.gui.icombobox.UIComboBox; |
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.layout.FRGUIPaneFactory; |
||||||
|
import com.fr.design.layout.TableLayout; |
||||||
|
import com.fr.design.layout.TableLayoutHelper; |
||||||
|
import com.fr.design.mainframe.DesignerContext; |
||||||
|
import com.fr.design.mainframe.FormDesigner; |
||||||
|
import com.fr.form.ui.MultiFileEditor; |
||||||
|
import com.fr.general.Inter; |
||||||
|
|
||||||
|
import javax.swing.BorderFactory; |
||||||
|
import javax.swing.JPanel; |
||||||
|
import javax.swing.SwingConstants; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Component; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by plough on 2018/4/19. |
||||||
|
*/ |
||||||
|
public class MultiFileUploaderDefinePane extends MobileWidgetDefinePane { |
||||||
|
private static final Item[] ITEMS = { |
||||||
|
new Item(Inter.getLocText("FR-Designer_Take_Photos_And_Choose_From_Album"), FileUploadModeState.TAKE_PHOTOS_AND_CHOOSE_FROM_ALBUM), |
||||||
|
new Item(Inter.getLocText("FR-Designer_Only_Take_Photos"), FileUploadModeState.ONLY_TAKE_PHOTOS) |
||||||
|
}; |
||||||
|
|
||||||
|
private XCreator xCreator; // 当前选中控件的xCreator
|
||||||
|
private UIComboBox uploadModeComboBox;// 上传方式下拉框
|
||||||
|
|
||||||
|
public MultiFileUploaderDefinePane(XCreator xCreator) { |
||||||
|
this.xCreator = xCreator; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void initPropertyGroups(Object source) { |
||||||
|
this.setLayout(FRGUIPaneFactory.createBorderLayout()); |
||||||
|
JPanel mobileSettingsPane; |
||||||
|
mobileSettingsPane = getMobileSettingsPane(); |
||||||
|
|
||||||
|
this.add(mobileSettingsPane, BorderLayout.NORTH); |
||||||
|
this.repaint(); |
||||||
|
} |
||||||
|
|
||||||
|
private UIExpandablePane getMobileSettingsPane() { |
||||||
|
initUploadModeComboBox(); |
||||||
|
|
||||||
|
// 以后可能会扩展,还是用 TableLayout 吧
|
||||||
|
Component[][] components = new Component[][]{ |
||||||
|
new Component[] {new UILabel(Inter.getLocText("FR-Designer_Upload_Mode"), SwingConstants.LEFT), uploadModeComboBox} |
||||||
|
}; |
||||||
|
|
||||||
|
double f = TableLayout.FILL; |
||||||
|
double p = TableLayout.PREFERRED; |
||||||
|
double[] rowSize = {p}; |
||||||
|
double[] columnSize = {p,f}; |
||||||
|
int[][] rowCount = {{1, 1}}; |
||||||
|
final JPanel panel = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, 30, LayoutConstants.VGAP_LARGE); |
||||||
|
panel.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0)); |
||||||
|
final JPanel panelWrapper = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||||
|
panelWrapper.add(panel, BorderLayout.NORTH); |
||||||
|
|
||||||
|
return new UIExpandablePane(Inter.getLocText("FR-Designer_Terminal"), 280, 20, panelWrapper); |
||||||
|
} |
||||||
|
|
||||||
|
private void initUploadModeComboBox() { |
||||||
|
this.uploadModeComboBox = new UIComboBox(ITEMS); |
||||||
|
} |
||||||
|
|
||||||
|
private void bindListeners2Widgets() { |
||||||
|
reInitAllListeners(); |
||||||
|
AttributeChangeListener changeListener = new AttributeChangeListener() { |
||||||
|
@Override |
||||||
|
public void attributeChange() { |
||||||
|
update(); |
||||||
|
} |
||||||
|
}; |
||||||
|
this.addAttributeChangeListener(changeListener); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 后台初始化所有事件. |
||||||
|
*/ |
||||||
|
private void reInitAllListeners() { |
||||||
|
initListener(this); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void populate(FormDesigner designer) { |
||||||
|
MultiFileUploaderMobileAttr mobileAttr = ((MultiFileEditor)xCreator.toData()).getMobileAttr(); |
||||||
|
FileUploadModeState fileUploadModeState = mobileAttr.getFileUploadModeState(); |
||||||
|
uploadModeComboBox.setSelectedIndex(fileUploadModeState.getState()); |
||||||
|
// 数据 populate 完成后,再设置监听
|
||||||
|
this.bindListeners2Widgets(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void update() { |
||||||
|
MultiFileUploaderMobileAttr mobileAttr = ((MultiFileEditor)xCreator.toData()).getMobileAttr(); |
||||||
|
mobileAttr.setFileUploadModeState((FileUploadModeState) ((Item)uploadModeComboBox.getSelectedItem()).getValue()); |
||||||
|
DesignerContext.getDesignerFrame().getSelectedJTemplate().fireTargetModified(); // 触发设计器保存按钮亮起来
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,81 @@ |
|||||||
|
package com.fr.design.widget.ui.designer.mobile; |
||||||
|
|
||||||
|
import com.fr.design.designer.beans.events.DesignerEvent; |
||||||
|
import com.fr.design.designer.creator.XCreator; |
||||||
|
import com.fr.design.foldablepane.UIExpandablePane; |
||||||
|
import com.fr.design.gui.frpane.AttributeChangeListener; |
||||||
|
import com.fr.design.layout.FRGUIPaneFactory; |
||||||
|
import com.fr.design.mainframe.FormDesigner; |
||||||
|
import com.fr.design.mainframe.MobileWidgetListPane; |
||||||
|
import com.fr.design.mainframe.WidgetPropertyPane; |
||||||
|
import com.fr.form.ui.container.WSortLayout; |
||||||
|
import com.fr.general.Inter; |
||||||
|
|
||||||
|
import javax.swing.BorderFactory; |
||||||
|
import javax.swing.JPanel; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by plough on 2018/2/5. |
||||||
|
*/ |
||||||
|
public class ParaMobileDefinePane extends MobileWidgetDefinePane { |
||||||
|
private XCreator paraCreator; |
||||||
|
private FormDesigner designer; |
||||||
|
private AttributeChangeListener changeListener; |
||||||
|
private MobileWidgetListPane mobileWidgetListPane; |
||||||
|
|
||||||
|
public ParaMobileDefinePane(XCreator xCreator) { |
||||||
|
this.paraCreator = xCreator; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void initPropertyGroups(Object source) { |
||||||
|
this.setLayout(FRGUIPaneFactory.createBorderLayout()); |
||||||
|
this.designer = WidgetPropertyPane.getInstance().getEditingFormDesigner(); |
||||||
|
this.add(getMobileWidgetListPane(), BorderLayout.CENTER); |
||||||
|
this.repaint(); |
||||||
|
} |
||||||
|
|
||||||
|
// 控件顺序
|
||||||
|
private UIExpandablePane getMobileWidgetListPane() { |
||||||
|
mobileWidgetListPane = new MobileWidgetListPane(designer, (WSortLayout) paraCreator.toData()); |
||||||
|
mobileWidgetListPane.setBorder(BorderFactory.createEmptyBorder(10, 0, 5, 0)); |
||||||
|
JPanel panelWrapper = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||||
|
panelWrapper.add(mobileWidgetListPane, BorderLayout.CENTER); |
||||||
|
|
||||||
|
return new UIExpandablePane(Inter.getLocText("FR-Designer_WidgetOrder"), 280, 20, panelWrapper); |
||||||
|
} |
||||||
|
|
||||||
|
private void bindListeners2Widgets() { |
||||||
|
reInitAllListeners(); |
||||||
|
this.changeListener = new AttributeChangeListener() { |
||||||
|
@Override |
||||||
|
public void attributeChange() { |
||||||
|
update(); |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 后台初始化所有事件. |
||||||
|
*/ |
||||||
|
private void reInitAllListeners() { |
||||||
|
initListener(this); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public void populate(FormDesigner designer) { |
||||||
|
this.designer = designer; |
||||||
|
|
||||||
|
// 设置监听
|
||||||
|
this.bindListeners2Widgets(); |
||||||
|
this.addAttributeChangeListener(changeListener); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void update() { |
||||||
|
mobileWidgetListPane.updateToDesigner(); |
||||||
|
designer.getEditListenerTable().fireCreatorModified(DesignerEvent.CREATOR_EDITED); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,39 @@ |
|||||||
|
package com.fr.design.widget; |
||||||
|
|
||||||
|
import com.fr.base.FRContext; |
||||||
|
import com.fr.design.ExtraDesignClassManager; |
||||||
|
import com.fr.design.widget.mobile.WidgetMobilePane; |
||||||
|
import com.fr.design.widget.ui.mobile.MultiFileEditorMobilePane; |
||||||
|
import com.fr.form.ui.MultiFileEditor; |
||||||
|
import com.fr.form.ui.Widget; |
||||||
|
|
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by plough on 2018/4/25. |
||||||
|
*/ |
||||||
|
public class WidgetMobilePaneFactory { |
||||||
|
private static Map<Class<? extends Widget>, Class<? extends WidgetMobilePane>> mobilePaneMap = new HashMap<>(); |
||||||
|
|
||||||
|
static { |
||||||
|
mobilePaneMap.put(MultiFileEditor.class, MultiFileEditorMobilePane.class); |
||||||
|
mobilePaneMap.putAll(ExtraDesignClassManager.getInstance().getCellWidgetMobileOptionsMap()); |
||||||
|
} |
||||||
|
|
||||||
|
private WidgetMobilePaneFactory() { |
||||||
|
} |
||||||
|
|
||||||
|
public static WidgetMobilePane createWidgetMobilePane(Widget widget) { |
||||||
|
WidgetMobilePane mobilePane = WidgetMobilePane.DEFAULT_PANE; |
||||||
|
try { |
||||||
|
if (mobilePaneMap.containsKey(widget.getClass())) { |
||||||
|
mobilePane = mobilePaneMap.get(widget.getClass()).newInstance(); |
||||||
|
mobilePane.populate(widget); |
||||||
|
} |
||||||
|
} catch (Exception e) { |
||||||
|
FRContext.getLogger().error(e.getMessage(), e); |
||||||
|
} |
||||||
|
return mobilePane; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,84 @@ |
|||||||
|
package com.fr.design.widget.ui.mobile; |
||||||
|
|
||||||
|
import com.fr.base.mobile.FileUploadModeState; |
||||||
|
import com.fr.base.mobile.MultiFileUploaderMobileAttr; |
||||||
|
import com.fr.design.constants.LayoutConstants; |
||||||
|
import com.fr.design.designer.properties.items.Item; |
||||||
|
import com.fr.design.foldablepane.UIExpandablePane; |
||||||
|
import com.fr.design.gui.icombobox.UIComboBox; |
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.layout.FRGUIPaneFactory; |
||||||
|
import com.fr.design.layout.TableLayout; |
||||||
|
import com.fr.design.layout.TableLayoutHelper; |
||||||
|
import com.fr.design.widget.mobile.WidgetMobilePane; |
||||||
|
import com.fr.form.ui.MultiFileEditor; |
||||||
|
import com.fr.form.ui.Widget; |
||||||
|
import com.fr.general.Inter; |
||||||
|
|
||||||
|
import javax.swing.BorderFactory; |
||||||
|
import javax.swing.JPanel; |
||||||
|
import javax.swing.SwingConstants; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Component; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by plough on 2018/4/25. |
||||||
|
*/ |
||||||
|
public class MultiFileEditorMobilePane extends WidgetMobilePane { |
||||||
|
private static final Item[] ITEMS = { |
||||||
|
new Item(Inter.getLocText("FR-Designer_Take_Photos_And_Choose_From_Album"), FileUploadModeState.TAKE_PHOTOS_AND_CHOOSE_FROM_ALBUM), |
||||||
|
new Item(Inter.getLocText("FR-Designer_Only_Take_Photos"), FileUploadModeState.ONLY_TAKE_PHOTOS) |
||||||
|
}; |
||||||
|
|
||||||
|
private UIComboBox uploadModeComboBox;// 上传方式下拉框
|
||||||
|
|
||||||
|
protected void init() { |
||||||
|
this.setLayout(FRGUIPaneFactory.createBorderLayout()); |
||||||
|
this.add(getMobileSettingsPane(), BorderLayout.NORTH); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 从 widget 中提取数据展示在属性面板中 |
||||||
|
* |
||||||
|
* @param widget |
||||||
|
*/ |
||||||
|
public void populate(Widget widget) { |
||||||
|
MultiFileUploaderMobileAttr mobileAttr = ((MultiFileEditor)widget).getMobileAttr(); |
||||||
|
FileUploadModeState fileUploadModeState = mobileAttr.getFileUploadModeState(); |
||||||
|
uploadModeComboBox.setSelectedIndex(fileUploadModeState.getState()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 从属性面板把数据保存到 widget 中 |
||||||
|
* @param widget |
||||||
|
*/ |
||||||
|
public void update(Widget widget) { |
||||||
|
MultiFileUploaderMobileAttr mobileAttr = ((MultiFileEditor)widget).getMobileAttr(); |
||||||
|
mobileAttr.setFileUploadModeState((FileUploadModeState) ((Item)uploadModeComboBox.getSelectedItem()).getValue()); |
||||||
|
} |
||||||
|
|
||||||
|
private UIExpandablePane getMobileSettingsPane() { |
||||||
|
initUploadModeComboBox(); |
||||||
|
|
||||||
|
// 以后可能会扩展
|
||||||
|
Component[][] components = new Component[][]{ |
||||||
|
new Component[] {new UILabel(Inter.getLocText("FR-Designer_Upload_Mode"), SwingConstants.LEFT), uploadModeComboBox} |
||||||
|
}; |
||||||
|
|
||||||
|
double f = TableLayout.FILL; |
||||||
|
double p = TableLayout.PREFERRED; |
||||||
|
double[] rowSize = {p}; |
||||||
|
double[] columnSize = {p,f}; |
||||||
|
int[][] rowCount = {{1, 1}}; |
||||||
|
final JPanel panel = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, 30, LayoutConstants.VGAP_LARGE); |
||||||
|
panel.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0)); |
||||||
|
final JPanel panelWrapper = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||||
|
panelWrapper.add(panel, BorderLayout.NORTH); |
||||||
|
|
||||||
|
return new UIExpandablePane(Inter.getLocText("FR-Designer_Terminal"), 280, 20, panelWrapper); |
||||||
|
} |
||||||
|
|
||||||
|
private void initUploadModeComboBox() { |
||||||
|
this.uploadModeComboBox = new UIComboBox(ITEMS); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue