/* This file is part of leafdigital leafChat. leafChat 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. leafChat 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. You should have received a copy of the GNU General Public License along with leafChat. If not, see <http://www.gnu.org/licenses/>. Copyright 2012 Samuel Marshall. */ package com.leafdigital.ui; import java.util.*; import javax.swing.JComponent; import com.leafdigital.ui.api.*; /** * Implements HorizontalPanel */ public class HorizontalPanelImp extends JComponent { /** Spacing between grid squares */ private int spacing=0; /** Border at edge of grid */ private int border=0; /** Keep record of held components */ private List<InternalWidget> components = new LinkedList<InternalWidget>(); /** Constructor */ HorizontalPanelImp() { setLayout(null); } @Override public void setBounds(int x, int y, int width, int height) { super.setBounds(x, y, width, height); updateLayout(); } @Override public void validate() { super.validate(); updateLayout(); } /** Move all components to their correct place in new layout */ private void updateLayout() { UISingleton.checkSwing(); int x=border; // Go through components laying them out synchronized(components) { for(InternalWidget iw : components) { if(!iw.isVisible()) continue; int thisWidth=iw.getPreferredWidth(); //int iWidgetHeight=iw.getPreferredHeight(iThisWidth); iw.getJComponent().setBounds(x,border,thisWidth,getHeight()-2*border); x+=thisWidth; x+=spacing; } } repaint(); } /** * @return Interface giving limited public access */ HorizontalPanel getInterface() { return externalInterface; } /** Interface available to public */ private HorizontalPanel externalInterface=new HorizontalPanelInterface(); /** Interface available to public */ class HorizontalPanelInterface extends BasicWidget implements HorizontalPanel,InternalWidget { @Override public int getContentType() { return CONTENT_UNNAMEDSLOTS; } @Override public JComponent getJComponent() { return HorizontalPanelImp.this; } @Override public int getPreferredWidth() { int width=0; synchronized(components) { for(InternalWidget iw : components) { if(!iw.isVisible()) continue; width+=iw.getPreferredWidth(); width+=spacing; } } width-=spacing; // Compensate for adding last space return width+2*border; } @Override public int getPreferredHeight(int width) { // Find largest component height int height=0; synchronized(components) { for(InternalWidget iw : components) { if(!iw.isVisible()) continue; int thisHeight=iw.getPreferredHeight(iw.getPreferredWidth()); height=Math.max(height,thisHeight); } } return height+2*border; } @Override public void setSpacing(final int spacing) { UISingleton.runInSwing(new Runnable() { @Override public void run() { HorizontalPanelImp.this.spacing=spacing; updateLayout(); } }); } @Override public void setBorder(final int border) { UISingleton.runInSwing(new Runnable() { @Override public void run() { HorizontalPanelImp.this.border=border; updateLayout(); } }); } @Override public void addXMLChild(String slotName, Widget child) { add(child); } @Override public void add(Widget w) { final InternalWidget iw=(InternalWidget)w; iw.setParent(this); UISingleton.runInSwing(new Runnable() { @Override public void run() { HorizontalPanelImp.this.add(iw.getJComponent()); synchronized(components) { components.add(iw); } updateLayout(); } }); } @Override public Widget[] getWidgets() { List<Widget> all = new LinkedList<Widget>(); synchronized(components) { for(InternalWidget w : components) { if(w != null) { all.add(w); } } } return all.toArray(new Widget[all.size()]); } @Override public void remove(Widget w) { final InternalWidget iw=(InternalWidget)w; UISingleton.runInSwing(new Runnable() { @Override public void run() { HorizontalPanelImp.this.remove(iw.getJComponent()); synchronized(components) { components.remove(iw); } updateLayout(); } }); } @Override public void removeAll() { UISingleton.runInSwing(new Runnable() { @Override public void run() { InternalWidget[] aiw; synchronized(components) { aiw=components.toArray(new InternalWidget[components.size()]); components.clear(); } for(int i=0;i<aiw.length;i++) { HorizontalPanelImp.this.remove(aiw[i].getJComponent()); } updateLayout(); } }); } }; }