package com.inter6.mail.gui.component.content; import java.awt.BorderLayout; import java.awt.Color; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Vector; import javax.swing.BoxLayout; import javax.swing.DefaultComboBoxModel; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JPanel; import javax.swing.border.CompoundBorder; import javax.swing.border.EmptyBorder; import javax.swing.border.LineBorder; import lombok.Getter; import org.apache.commons.collections4.CollectionUtils; import com.inter6.mail.gui.action.LogPanel; import com.inter6.mail.gui.tab.TabComponentPanel; import com.inter6.mail.model.ContentType; import com.inter6.mail.model.component.content.PartData; import com.inter6.mail.module.ModuleService; import com.inter6.mail.module.TabComponentManager; public abstract class ContentPartPanel extends TabComponentPanel { private static final long serialVersionUID = -3928978805796944620L; @Getter protected final ContentType contentType; private final int nested; private final List<ChildWrapPanel> childWrapPanels = new ArrayList<>(); protected final JPanel wrapPanel = new JPanel(); private final JPanel childContainerPanel = new JPanel(); private final JPanel actionPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); private final JComboBox<ContentType> childTypeSelectBox = new JComboBox<>(); private final JButton addChildButton = new JButton("Add Child Part"); public static ContentPartPanel createPanel(String tabName, ContentType contentType, int nested) throws Exception { Class<? extends ContentPartPanel> panelClass = contentType.getPanelClass(); ContentPartPanel contentPanel = panelClass.getDeclaredConstructor(String.class, ContentType.class, Integer.class).newInstance(tabName, contentType, nested); contentPanel.initLayout(); return contentPanel; } public static ContentPartPanel createPanelByRoot(String tabName, ContentType contentType) throws Exception { return createPanel(tabName, contentType, 0); } protected ContentPartPanel(String tabName, ContentType contentType, Integer nested) { super(tabName); this.contentType = contentType; this.nested = nested; this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); this.setBorder(new CompoundBorder(new EmptyBorder(10, nested * 20, 10, 10), new LineBorder(Color.RED))); this.add(this.wrapPanel); this.childContainerPanel.setLayout(new BoxLayout(this.childContainerPanel, BoxLayout.Y_AXIS)); this.add(this.childContainerPanel); // JPanel actionPanel { this.actionPanel.add(this.childTypeSelectBox); this.addChildButton.addActionListener(this.addChildEvent); this.actionPanel.add(this.addChildButton); this.setActionComponents(); } this.add(this.actionPanel); } private void setActionComponents() { Vector<ContentType> availableChildTypes = this.getAvailableChildTypes(this.getUnwrapChildPanels()); if (CollectionUtils.isNotEmpty(availableChildTypes)) { this.childTypeSelectBox.setModel(new DefaultComboBoxModel<>(availableChildTypes)); this.actionPanel.setVisible(true); } else { this.actionPanel.setVisible(false); } } protected List<ContentPartPanel> getUnwrapChildPanels() { List<ContentPartPanel> childPanels = new ArrayList<>(); for (ChildWrapPanel childWrapPanel : this.childWrapPanels) { childPanels.add(childWrapPanel.contentPanel); } return childPanels; } private final ActionListener addChildEvent = new ActionListener() { @Override public void actionPerformed(ActionEvent event) { ContentPartPanel.this.addChildPanel((ContentType) ContentPartPanel.this.childTypeSelectBox.getSelectedItem()); } }; private ContentPartPanel addChildPanel(ContentType childType) { try { ContentPartPanel childPanel = createPanel(this.tabName, childType, this.nested + 1); ChildWrapPanel childWrapPanel = new ChildWrapPanel(childPanel); this.childWrapPanels.add(childWrapPanel); this.childContainerPanel.add(childWrapPanel); this.setActionComponents(); return childPanel; } catch (Exception e) { LogPanel logPanel = ModuleService.getBean(TabComponentManager.class).getTabComponent(tabName, LogPanel.class); logPanel.error("create content panel fail ! - TYPE:" + childType, e); return null; } } protected abstract void initLayout(); public abstract Object buildContentPart() throws Throwable; protected abstract Vector<ContentType> getAvailableChildTypes(List<ContentPartPanel> addedChildPanels); public PartData getPartData() { PartData partData = this.getPartDataFromComponents(); partData.setContentType(this.contentType); List<PartData> childPartDatas = new ArrayList<>(); for (ContentPartPanel childPanel : this.getUnwrapChildPanels()) { childPartDatas.add(childPanel.getPartData()); } partData.setChildPartDatas(childPartDatas); return partData; } protected abstract PartData getPartDataFromComponents(); public void setPartData(PartData partData) { for (ChildWrapPanel childWrapPanel : new ArrayList<>(this.childWrapPanels)) { this.removeChildPanel(childWrapPanel); } if (partData == null) { return; } this.setComponentsFromPartData(partData); if (CollectionUtils.isEmpty(partData.getChildPartDatas())) { return; } for (PartData childPartData : partData.getChildPartDatas()) { ContentPartPanel childPartPanel = this.addChildPanel(childPartData.getContentType()); if (childPartPanel != null) { childPartPanel.setPartData(childPartData); } } } protected abstract void setComponentsFromPartData(PartData partData); protected class ChildWrapPanel extends JPanel { private static final long serialVersionUID = -3478585608809305772L; private final ContentPartPanel contentPanel; public ChildWrapPanel(ContentPartPanel contentPanel) { super(); this.contentPanel = contentPanel; this.setLayout(new BorderLayout()); JPanel actionPanel = new JPanel(); actionPanel.setLayout(new BoxLayout(actionPanel, BoxLayout.Y_AXIS)); actionPanel.setBorder(new EmptyBorder(10, 0, 0, 0)); { JButton upButton = new JButton("Up"); JButton downButton = new JButton("Down"); JButton removeButton = new JButton("Remove"); upButton.addActionListener(this.createUpEvent()); downButton.addActionListener(this.createDownEvent()); removeButton.addActionListener(this.createRemoveEvent()); actionPanel.add(upButton); actionPanel.add(downButton); actionPanel.add(removeButton); } this.add(actionPanel, BorderLayout.EAST); this.add(this.contentPanel, BorderLayout.CENTER); } private ActionListener createUpEvent() { return new ActionListener() { @Override public void actionPerformed(ActionEvent e) { ContentPartPanel.this.upChildPanel(ChildWrapPanel.this); } }; } private ActionListener createDownEvent() { return new ActionListener() { @Override public void actionPerformed(ActionEvent e) { ContentPartPanel.this.downChildPanel(ChildWrapPanel.this); } }; } private ActionListener createRemoveEvent() { return new ActionListener() { @Override public void actionPerformed(ActionEvent e) { ContentPartPanel.this.removeChildPanel(ChildWrapPanel.this); } }; } } protected void upChildPanel(ChildWrapPanel childWrapPanel) { int index = this.childWrapPanels.indexOf(childWrapPanel); if (index == 0) { return; } Collections.swap(this.childWrapPanels, index - 1, index); this.childContainerPanel.remove(index); this.childContainerPanel.add(childWrapPanel, index - 1); this.setActionComponents(); } protected void downChildPanel(ChildWrapPanel childWrapPanel) { int index = this.childWrapPanels.indexOf(childWrapPanel); if (index >= this.childWrapPanels.size() - 1) { return; } Collections.swap(this.childWrapPanels, index, index + 1); this.childContainerPanel.remove(index); this.childContainerPanel.add(childWrapPanel, index + 1); this.setActionComponents(); } private void removeChildPanel(ChildWrapPanel childPanel) { this.childWrapPanels.remove(childPanel); this.childContainerPanel.remove(childPanel); this.setActionComponents(); } }