/* 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.awt.Graphics; import java.awt.FontMetrics; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; import util.PlatformUtils; import com.leafdigital.ui.api.*; import leafchat.core.api.BugException; /** * Provides a basic text button. */ public class ButtonImp extends JComponent implements ActionListener,HierarchyListener,BaseGroup { ButtonInterface bi=new ButtonInterface(); private String onAction=null; private boolean isDefault; private String baseGroup=null; private JButton b=new JButton("Action"); // Default text needed for size calculation int topOffset=0; /** * Constructs. */ public ButtonImp() { b.addActionListener(this); b.addHierarchyListener(this); b.setOpaque(false); add(b); addAncestorListener(new AncestorListener() { @Override public void ancestorAdded(AncestorEvent ae) { reallySetDefault(); } @Override public void ancestorRemoved(AncestorEvent ae) { reallySetDefault(); } @Override public void ancestorMoved(AncestorEvent arg0) { } }); } @Override public void setBounds(int x,int y,int width,int height) { super.setBounds(x,y,width,height); relayout(); } private void relayout() { int preferredHeight=b.getPreferredSize().height; b.setBounds(0,topOffset,getWidth(),preferredHeight); } Button getInterface() { return bi; } class ButtonInterface extends BasicWidget implements Button,InternalWidget { @Override public int getContentType() { return CONTENT_NONE; } @Override public void setLabel(String text) { b.setText(text); } @Override public void setOnAction(String callback) { getOwner().getCallbackHandler().check(callback); ButtonImp.this.onAction=callback; } @Override public JComponent getJComponent() { return ButtonImp.this; } @Override public int getPreferredWidth() { return b.getPreferredSize().width; } @Override public int getPreferredHeight(int width) { return b.getPreferredSize().height; } @Override public void addXMLChild(String slotName, Widget child) { throw new BugException("Buttons cannot contain children"); } @Override public void setDefault(boolean isDefault) { ButtonImp.this.isDefault=isDefault; reallySetDefault(); } @Override public void setEnabled(boolean enabled) { if(isEnabled()!=enabled) b.setEnabled(enabled); } @Override public boolean isEnabled() { return b.isEnabled(); } @Override public void setBaseGroup(String group) { if(baseGroup!=null) { BaseGroup.Updater.removeFromGroup(ButtonImp.this,baseGroup); baseGroup=null; } if(group!=null) { baseGroup=group; BaseGroup.Updater.addToGroup(ButtonImp.this,baseGroup); } } @Override public void focus() { getUI().focus(b); } } private void reallySetDefault() { JRootPane rp=getRootPane(); if(rp==null) return; if(!isShowing()) return; if(isDefault) { JButton def=rp.getDefaultButton(); if(def!=b) rp.setDefaultButton(b); } else { JButton def=rp.getDefaultButton(); if(def==b) rp.setDefaultButton(null); } } @Override public void actionPerformed(ActionEvent e) { // Only send event if button is showing. It's just possible that queued // events happen after button was hidden (I think) - see #17 if(onAction!=null && isShowing() && isEnabled()) { getInterface().getOwner().getCallbackHandler().callHandleErrors(onAction); } } @Override public void hierarchyChanged(HierarchyEvent he) { if( ((he.getChangeFlags() & HierarchyEvent.PARENT_CHANGED)!=0) || ((he.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED)!=0)) reallySetDefault(); } // BaseGroup methods //////////////////// @Override public int getBaseline() { FontMetrics fm=b.getFontMetrics(b.getFont()); int border=(b.getPreferredSize().height-fm.getHeight())/2; int bestGuess=border+fm.getAscent(); if(PlatformUtils.isMac()) bestGuess+=1; return bestGuess; } @Override public InternalWidgetOwner getInternalWidgetOwner() { return (InternalWidgetOwner)bi.getOwner(); } @Override public void setTopOffset(int topOffset) { if(this.topOffset==topOffset) return; this.topOffset=topOffset; relayout(); } // Debugging @Override protected void paintChildren(Graphics g) { super.paintChildren(g); BaseGroup.Debug.paint(g,this,topOffset); } }