/* Copyright 2003, Carnegie Mellon, All Rights Reserved */ package edu.cmu.minorthird.util.gui; import java.awt.GridBagLayout; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import javax.swing.JTabbedPane; import javax.swing.SwingConstants; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; /** * Conceptually this allows one to view several parallel aspects of a single * object. This is mapped to a JTabbedPane. * * <p> * Note: when content is sent to a ParallelViewer, the viewer immediate forwards * the content only to the currently selected subview. This means that the * non-default subviews can be expensive to compute - no extra overhead will be * incurred unless the user actually selects these views. <b>However</b>, * before the ParallelViewer recieves content, it also checks that <b>every</b> * subview can receive the content, using that subview's canRecieve * method. So * if a subview's canRecieve method is expensive (e.g., if it simply calls * receive to see if there is an error, as the default implementation of * ComponentViewer does) then this extra overhead will be incurred. * * @author William cohen */ public class ParallelViewer extends Viewer{ static final long serialVersionUID=20080517L; private JTabbedPane parallelPane; private List<Viewer> subViewList; public ParallelViewer(){ super(); } /** Called at creation time. */ @Override protected void initialize(){ setLayout(new GridBagLayout()); parallelPane=new JTabbedPane(); subViewList=new ArrayList<Viewer>(); add(parallelPane,fillerGBC()); parallelPane.addChangeListener(new ChangeListener(){ @Override public void stateChanged(ChangeEvent ev){ // update the content of the currently selected view receiveContent(ParallelViewer.this.getContent()); } }); } /** Change default look of tabbed pane to put tabs on the left */ public void putTabsOnLeft(){ parallelPane.setTabPlacement(SwingConstants.LEFT); parallelPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT); } /** Add a new way of viewing the content object. */ public void addSubView(String title,Viewer view){ view.setSuperView(this,title); subViewList.add(view); parallelPane.add(title,view); } @Override public void receiveContent(Object content){ // just send content to the currently selected subview Viewer subView=subViewList.get(parallelPane.getSelectedIndex()); subView.setContent(content); } /* * override the default definition, to make sure the subView returned is * current. */ @Override public Viewer getNamedSubView(String name){ Viewer subviewer=super.getNamedSubView(name); subviewer.setContent(getContent()); return subviewer; } @Override public boolean canReceive(Object content){ for(Iterator<Viewer> i=subViewList.iterator();i.hasNext();){ Viewer subView=i.next(); if(!subView.canReceive(content)) return false; } return true; } @Override public void clearContent(){ for(Iterator<Viewer> i=subViewList.iterator();i.hasNext();){ Viewer subView=i.next(); subView.clearContent(); } } @Override protected void handle(int signal,Object argument,List<Viewer> senders){ throw new IllegalStateException("signal:"+signal+" argument:"+argument+ " at:"+this); } @Override protected boolean canHandle(int signal,Object argument,List<Viewer> senders){ return false; } }