All Downloads are FREE. Search and download functionalities are using the official Maven repository.

xy.reflect.ui.control.swing.plugin.DetailedListControlPlugin Maven / Gradle / Ivy

/*******************************************************************************
 * Copyright (C) 2018 OTK Software
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * The GNU General Public License allows you also to freely redistribute 
 * the libraries under the same license, if you provide the terms of the 
 * GNU General Public License with them and add the following 
 * copyright notice at the appropriate place (with a link to 
 * http://javacollection.net/reflectionui/ web site when possible).
 ******************************************************************************/
package xy.reflect.ui.control.swing.plugin;

import java.awt.AWTEvent;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.AWTEventListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.event.AncestorEvent;
import javax.swing.event.AncestorListener;

import xy.reflect.ui.control.IFieldControlInput;
import xy.reflect.ui.control.plugin.AbstractSimpleCustomizableFieldControlPlugin;
import xy.reflect.ui.control.swing.ListControl;
import xy.reflect.ui.control.swing.renderer.Form;
import xy.reflect.ui.control.swing.renderer.SwingRenderer;
import xy.reflect.ui.info.type.iterable.IListTypeInfo;
import xy.reflect.ui.info.type.iterable.item.BufferedItemPosition;
import xy.reflect.ui.info.type.iterable.item.IListItemDetailsAccessMode;
import xy.reflect.ui.info.type.iterable.item.ItemDetailsAreaPosition;
import xy.reflect.ui.util.ReflectionUIError;
import xy.reflect.ui.util.SwingRendererUtils;
import xy.reflect.ui.util.component.ControlPanel;

public class DetailedListControlPlugin extends AbstractSimpleCustomizableFieldControlPlugin {

	@Override
	public String getControlTitle() {
		return "Detailed List Control";
	}

	@Override
	protected boolean handles(Class javaType) {
		throw new ReflectionUIError();
	}

	@Override
	public boolean handles(IFieldControlInput input) {
		if (!(input.getControlData().getType() instanceof IListTypeInfo)) {
			return false;
		}
		return true;
	}

	@Override
	public boolean canDisplayDistinctNullValue() {
		return false;
	}

	@Override
	public AbstractConfiguration getDefaultControlCustomization() {
		return new DetailedListConfiguration();
	}

	@Override
	public DetailedListControl createControl(Object renderer, IFieldControlInput input) {
		return new DetailedListControl((SwingRenderer) renderer, input);
	}

	public static class DetailedListConfiguration extends AbstractConfiguration {

		private static final long serialVersionUID = 1L;

		public DetailedListLayout layout = DetailedListLayout.VERTICAL_FLOW;
		public int gridDimension = 0;
		public boolean stretchCellsVertically = true;
		public boolean stretchCellsHorizontally = true;

		private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
			stretchCellsVertically = true;
			stretchCellsHorizontally = true;
			in.defaultReadObject();
		}

	}

	public enum DetailedListLayout {
		HORIZONTAL_FLOW, VERTICAL_FLOW
	}

	public class DetailedListControl extends ListControl {
		private static final long serialVersionUID = 1L;

		protected JPanel detailedCellsContainer;
		protected List detailedCellControlList;

		public DetailedListControl(SwingRenderer swingRenderer, final IFieldControlInput input) {
			super(swingRenderer, input);
		}

		@Override
		protected void initializeTreeTableModelAndControl() {
			itemPositionFactory = createItemPositionfactory();
			detailedCellsContainer = new ControlPanel();
			{
				detailedCellsContainer.setLayout(new GridBagLayout());
			}
			treeTableComponentScrollPane = createScrollPane();
			treeTableComponentScrollPane.setViewportView(detailedCellsContainer);
		}

		@Override
		protected void layoutControls() {
			setLayout(new BorderLayout());
			add(treeTableComponentScrollPane, BorderLayout.CENTER);
			add(toolbar, BorderLayout.EAST);
		}

		@Override
		public void refreshTreeTableModelAndControl(boolean refreshStructure) {
			itemPositionFactory = createItemPositionfactory();
			int itemCount = itemPositionFactory.getRootItemPosition(-1).getContainingListSize();
			if (detailedCellControlList == null) {
				detailedCellControlList = new ArrayList();
			}
			if (itemCount == detailedCellControlList.size()) {
				for (int i = 0; i < itemCount; i++) {
					DetailedCellControl detailedCellControl = detailedCellControlList.get(i);
					detailedCellControl.refreshUI(refreshStructure);
					if (refreshStructure) {
						detailedCellsContainer.remove(detailedCellControl);
						detailedCellsContainer.add(detailedCellControl, getDetailedCellLayoutConstraints(i));
					}
				}
			} else {
				for (DetailedCellControl c : detailedCellControlList) {
					detailedCellsContainer.remove(c);
				}
				detailedCellControlList.clear();
				for (int i = 0; i < itemCount; i++) {
					BufferedItemPosition itemPosition = itemPositionFactory.getRootItemPosition(i);
					DetailedCellControl detailedCellControl = new DetailedCellControl(itemPosition);
					{
						detailedCellControlList.add(detailedCellControl);
						detailedCellsContainer.add(detailedCellControl, getDetailedCellLayoutConstraints(i));
					}
				}
			}
			if (refreshStructure) {
				SwingRendererUtils.handleComponentSizeChange(detailedCellsContainer);
			}
		}

		protected Object getDetailedCellLayoutConstraints(int i) {
			DetailedListConfiguration controlCustomization = (DetailedListConfiguration) loadControlCustomization(
					input);
			GridBagConstraints result = new GridBagConstraints();
			if (controlCustomization.layout == DetailedListLayout.VERTICAL_FLOW) {
				result.gridx = 0;
				result.gridy = i;
				if (controlCustomization.gridDimension > 0) {
					result.gridx = result.gridy / controlCustomization.gridDimension;
					result.gridy = result.gridy % controlCustomization.gridDimension;
				}
			} else if (controlCustomization.layout == DetailedListLayout.HORIZONTAL_FLOW) {
				result.gridy = 0;
				result.gridx = i;
				if (controlCustomization.gridDimension > 0) {
					result.gridy = result.gridx / controlCustomization.gridDimension;
					result.gridx = result.gridx % controlCustomization.gridDimension;
				}
			} else {
				throw new ReflectionUIError();
			}
			if (controlCustomization.stretchCellsHorizontally && controlCustomization.stretchCellsVertically) {
				result.fill = GridBagConstraints.BOTH;
			} else if (controlCustomization.stretchCellsHorizontally) {
				result.fill = GridBagConstraints.HORIZONTAL;
			} else if (controlCustomization.stretchCellsVertically) {
				result.fill = GridBagConstraints.VERTICAL;
			} else {
				result.fill = GridBagConstraints.NONE;
			}
			result.weightx = 1.0;
			result.weighty = 1.0;
			return result;
		}

		@Override
		public List getSelection() {
			List result = new ArrayList();
			if (detailedCellsContainer != null) {
				for (Component c : detailedCellsContainer.getComponents()) {
					DetailedCellControl detailedCellControl = (DetailedCellControl) c;
					if (detailedCellControl.isSelected()) {
						result.add(detailedCellControl.getItemPosition());
					}
				}
			}
			return result;
		}

		@Override
		public void setSelection(List toSelect) {
			if (getSelection().equals(toSelect)) {
				return;
			}
			if (detailedCellsContainer != null) {
				for (Component c : detailedCellsContainer.getComponents()) {
					DetailedCellControl detailedCellControl = (DetailedCellControl) c;
					if (toSelect.contains(detailedCellControl.getItemPosition())) {
						detailedCellControl.setSelected(true);
					} else {
						detailedCellControl.setSelected(false);
					}
				}
				fireSelectionEvent();
			}
		}

		@Override
		protected void setupContexteMenu() {
		}

		@Override
		protected void initializeSelectionListening() {
		}

		@Override
		protected void updateDetailsAreaOnSelection() {
		}

		@Override
		protected void openDetailsDialogOnItemDoubleClick() {
		}

		@Override
		public boolean requestCustomFocus() {
			if (getRootListSize() > 0) {
				setSingleSelection(getRootListItemPosition(0));
			}
			if (SwingRendererUtils.requestAnyComponentFocus(detailedCellsContainer, swingRenderer)) {
				return true;
			}
			return false;
		}

		@Override
		protected void restoringColumnWidthsAsMuchAsPossible(Runnable runnable) {
			throw new ReflectionUIError();
		}

		@Override
		public void scrollUntilVisible(BufferedItemPosition itemPosition) {
			throw new ReflectionUIError();
		}

		@Override
		protected void updateDetailsArea(boolean refreshStructure) {
			throw new ReflectionUIError();
		}

		@Override
		public IListItemDetailsAccessMode getDetailsAccessMode() {
			return new IListItemDetailsAccessMode() {

				private static final long serialVersionUID = 1L;

				@Override
				public boolean hasDetailsDisplayOption() {
					return false;
				}

				@Override
				public boolean hasDetailsDisplayArea() {
					return false;
				}

				@Override
				public ItemDetailsAreaPosition getDetailsAreaPosition() {
					throw new ReflectionUIError();
				}

				@Override
				public double getDefaultDetailsAreaOccupationRatio() {
					throw new ReflectionUIError();
				}
			};
		}

		@Override
		public String toString() {
			return "DetailedListControl [data=" + listData + "]";
		}

		public class DetailedCellControl extends ControlPanel {

			private static final long serialVersionUID = 1L;

			protected BufferedItemPosition itemPosition;
			protected boolean selected = false;

			private Form form;

			private ItemUIBuilder formBuilder;

			public DetailedCellControl(BufferedItemPosition itemPosition) {
				this.itemPosition = itemPosition;
				setLayout(new GridBagLayout());
				formBuilder = new ItemUIBuilder(itemPosition);
				form = formBuilder.createEditorForm(true, false);
				{
					GridBagConstraints formConstraints = new GridBagConstraints();
					formConstraints.fill = GridBagConstraints.BOTH;
					formConstraints.weightx = 1.0;
					formConstraints.weighty = 1.0;
					int insetsThickness = SwingRendererUtils.getStandardCharacterWidth(this) * 2;
					formConstraints.insets = new Insets(insetsThickness, insetsThickness, insetsThickness,
							insetsThickness);
					add(form, formConstraints);
				}
				enableSelection();
			}

			protected void enableSelection() {
				addMouseListener(new MouseAdapter() {

					@Override
					public void mouseClicked(MouseEvent e) {
						setSingleSelection(DetailedCellControl.this.itemPosition);
					}

					@Override
					public void mousePressed(MouseEvent e) {
						setSingleSelection(DetailedCellControl.this.itemPosition);
					}
				});
				final AWTEventListener selectionListener = new AWTEventListener() {
					@Override
					public void eventDispatched(AWTEvent event) {
						if (!(event instanceof MouseEvent)) {
							return;
						}
						MouseEvent moueseEvent = (MouseEvent) event;
						if ((moueseEvent.getID() != MouseEvent.MOUSE_PRESSED)
								&& (moueseEvent.getID() != MouseEvent.MOUSE_CLICKED)) {
							return;
						}
						Component c = moueseEvent.getComponent();
						if (c == null) {
							return;
						}
						if (SwingUtilities.getAncestorOfClass(DetailedCellControl.class,
								c) != DetailedCellControl.this) {
							return;
						}
						setSingleSelection(DetailedCellControl.this.itemPosition);
					}
				};
				addAncestorListener(new AncestorListener() {

					@Override
					public void ancestorAdded(AncestorEvent event) {
						Toolkit.getDefaultToolkit().addAWTEventListener(selectionListener, AWTEvent.MOUSE_EVENT_MASK);
					}

					@Override
					public void ancestorRemoved(AncestorEvent event) {
						Toolkit.getDefaultToolkit().removeAWTEventListener(selectionListener);
					}

					@Override
					public void ancestorMoved(AncestorEvent event) {
					}

				});
				updateSelectionState();
			}

			protected void updateSelectionState() {
				int borderThickness = 1;
				if (selected) {
					setBorder(BorderFactory.createLineBorder(SwingRendererUtils.getListSelectionBackgroundColor(),
							borderThickness));
				} else {
					setBorder(BorderFactory.createEmptyBorder(borderThickness, borderThickness, borderThickness,
							borderThickness));
				}
			}

			public BufferedItemPosition getItemPosition() {
				return itemPosition;
			}

			public boolean isSelected() {
				return selected;
			}

			public void setSelected(boolean b) {
				selected = b;
				updateSelectionState();
			}

			public void refreshUI(boolean refreshStructure) {
				formBuilder.refreshEditorForm(form, refreshStructure);
			}

			@Override
			public String toString() {
				return "DetailedCellControl [itemPosition=" + itemPosition + "]";
			}

		}

	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy