/**
* eAdventure (formerly <e-Adventure> and <e-Game>) is a research project of the
* <e-UCM> research group.
*
* Copyright 2005-2010 <e-UCM> research group.
*
* You can access a list of all the contributors to eAdventure at:
* http://e-adventure.e-ucm.es/contributors
*
* <e-UCM> is a research group of the Department of Software Engineering
* and Artificial Intelligence at the Complutense University of Madrid
* (School of Computer Science).
*
* C Profesor Jose Garcia Santesmases sn,
* 28040 Madrid (Madrid), Spain.
*
* For more info please visit: <http://e-adventure.e-ucm.es> or
* <http://www.e-ucm.es>
*
* ****************************************************************************
*
* This file is part of eAdventure, version 2.0
*
* eAdventure is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* eAdventure 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with eAdventure. If not, see <http://www.gnu.org/licenses/>.
*/
package es.eucm.ead.editor.view.generic;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.Rectangle;
import es.eucm.ead.editor.control.CommandManager;
import es.eucm.ead.editor.model.ModelEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.Scrollable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PanelImpl implements OptionPanel {
static private Logger logger = LoggerFactory.getLogger(PanelImpl.class);
private List<Option> elements;
private String title;
private LayoutPolicy layoutPolicy;
private JPanel basePanel;
private int insets;
private LayoutBuilder builder;
public PanelImpl(String title, LayoutPolicy layoutPolicy, int insets) {
elements = new ArrayList<Option>();
this.title = title;
this.layoutPolicy = layoutPolicy;
this.insets = insets;
switch (layoutPolicy) {
case Flow: {
builder = new FlowBuilder();
break;
}
case VerticalEquallySpaced: {
builder = new VerticalEquallySpacedBuilder();
break;
}
case HorizontalBlocks: {
builder = new HorizontalBlocksBuilder();
break;
}
case VerticalBlocks: {
builder = new VerticalBlocksBuilder();
break;
}
default:
throw new IllegalArgumentException("No builder for " + layoutPolicy);
}
}
@Override
public List<Option> getElements() {
return elements;
}
@Override
public String getTitle() {
return title;
}
@Override
public PanelImpl add(Option element) {
elements.add(element);
return this;
}
@Override
public LayoutPolicy getLayoutPolicy() {
return layoutPolicy;
}
//TODO Should support different element positioning policies
@Override
public JPanel getComponent(CommandManager manager) {
basePanel = new ScrollablePanel();
JScrollPane scrollPane = new JScrollPane(basePanel);
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BorderLayout());
mainPanel.add(scrollPane, BorderLayout.CENTER);
builder.start();
for (Option e : getElements()) {
builder.add(e, manager);
}
builder.finish();
basePanel.revalidate();
return mainPanel;
}
@Override
public void modelChanged(ModelEvent event) {
for (Option ie : elements) {
ie.modelChanged(event);
}
}
@Override
public String getToolTipText() {
return null;
}
private class ScrollablePanel extends JPanel implements Scrollable {
private static final long serialVersionUID = -8779328786327371343L;
@Override
public Dimension getPreferredSize() {
Dimension preferred = super.getPreferredSize();
Dimension container = super.getParent().getParent().getSize();
int w = Math.max(preferred.width, container.width);
int h = Math.max(preferred.height, container.height);
return new Dimension(w, h - 10);
}
@Override
public Dimension getPreferredScrollableViewportSize() {
return super.getPreferredSize();
}
@Override
public int getScrollableBlockIncrement(Rectangle visibleRect,
int orientation, int direction) {
return 16;
}
@Override
public boolean getScrollableTracksViewportHeight() {
return false;
}
@Override
public boolean getScrollableTracksViewportWidth() {
return true;
}
@Override
public int getScrollableUnitIncrement(Rectangle visibleRect,
int orientation, int direction) {
return 16;
}
}
// ----- layout builders here -----
public interface LayoutBuilder {
void start();
void add(Option element, CommandManager manager);
void finish();
}
public abstract class SimpleBuilder implements LayoutBuilder {
public abstract LayoutManager getLayout();
@Override
public void start() {
basePanel.setLayout(getLayout());
}
@Override
public void add(Option element, CommandManager manager) {
basePanel.add(element.getComponent(manager));
}
@Override
public void finish() {
// nothing to do.
}
}
public class FlowBuilder extends SimpleBuilder {
@Override
public LayoutManager getLayout() {
return new FlowLayout(FlowLayout.CENTER, insets, insets);
}
}
public class VerticalEquallySpacedBuilder extends SimpleBuilder {
@Override
public LayoutManager getLayout() {
return new GridLayout(0, 1, insets, insets);
}
}
public abstract class GridBuilder implements LayoutBuilder {
protected GridBagConstraints gbc = new GridBagConstraints(0, 0, 1, 1,
0, 0, GridBagConstraints.CENTER, GridBagConstraints.NONE,
new Insets(insets, insets, insets, insets), 0, 0);
@Override
public void start() {
basePanel.setLayout(new GridBagLayout());
}
@Override
public void add(Option element, CommandManager manager) {
if (element.getTitle() != null) {
JLabel label = new JLabel(element.getTitle());
prepareLabel();
basePanel.add(label, gbc);
endLabel();
}
prepareField();
basePanel.add(element.getComponent(manager), gbc);
endField();
}
public abstract void prepareLabel();
public abstract void endLabel();
public abstract void prepareField();
public abstract void endField();
@Override
public void finish() {
JPanel spacer = new JPanel();
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.insets = new Insets(0, 0, 0, 0);
basePanel.add(spacer, gbc);
}
}
public class VerticalBlocksBuilder extends GridBuilder {
@Override
public void prepareLabel() {
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0;
gbc.anchor = GridBagConstraints.EAST;
}
@Override
public void endLabel() {
gbc.gridx++;
}
@Override
public void prepareField() {
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 5.0;
}
@Override
public void endField() {
gbc.gridx = 0;
gbc.gridy++;
}
}
public class HorizontalBlocksBuilder extends GridBuilder {
@Override
public void prepareLabel() {
gbc.fill = GridBagConstraints.NONE;
gbc.weighty = 0;
gbc.anchor = GridBagConstraints.SOUTH;
}
@Override
public void endLabel() {
gbc.gridy++;
}
@Override
public void prepareField() {
gbc.fill = GridBagConstraints.VERTICAL;
gbc.weighty = 1.0;
}
@Override
public void endField() {
gbc.gridx++;
gbc.gridy = 0;
}
}
}