001 /* 002 * This program is free software; you can redistribute it and/or modify 003 * it under the terms of the GNU General Public License as published by 004 * the Free Software Foundation; version 2 of the License. 005 * 006 * This program is distributed in the hope that it will be useful, 007 * but WITHOUT ANY WARRANTY; without even the implied warranty of 008 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 009 * GNU General Public License for more details. 010 * 011 * You should have received a copy of the GNU General Public License along 012 * with this program; if not, write to the Free Software Foundation, Inc., 013 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 014 */ 015 package org.tastybug.bugwerk.bugtrail.widget.ticket; 016 017 import java.awt.Dimension; 018 import java.util.Arrays; 019 import java.util.Date; 020 import java.util.Iterator; 021 022 import javax.swing.JScrollPane; 023 import javax.swing.JTabbedPane; 024 import javax.swing.SwingConstants; 025 import javax.swing.ToolTipManager; 026 027 import org.apache.commons.logging.Log; 028 import org.apache.commons.logging.LogFactory; 029 import org.tastybug.bugwerk.blueprint.event.IncidentChangeListener; 030 import org.tastybug.bugwerk.blueprint.event.TicketChangeListener; 031 import org.tastybug.bugwerk.blueprint.model.Incident; 032 import org.tastybug.bugwerk.blueprint.model.Ticket; 033 import org.tastybug.bugwerk.bugtrail.widget.incident.IncidentTable; 034 035 036 /** 037 * This <code>JTabbedPane</code> displays a ticket. 038 * <br> 039 * One tab is created for the base data of the Ticket, one tab for each contained <code>Incident</code>, 040 * containing an <code>IncidentTable</code>. 041 * <br><br> 042 * 043 * <hr> 044 * Copyright 2006 Philipp Bartsch.<br> 045 * <a href="http://www.tastybug.com">www.tastybug.com</a><br> 046 * <hr> 047 * Created on Feb 8, 2006<br> 048 * @author Philipp Bartsch, philipp.bartsch{at}tastybug{dot}com</a> 049 */ 050 public class TicketDisplayTabPane extends JTabbedPane implements TicketChangeListener, IncidentChangeListener { 051 052 /**Comment for <code>serialVersionUID</code>*/ 053 private static final long serialVersionUID = -6451931754422314904L; 054 055 /**The commons logger.*/ 056 private static final Log logger = LogFactory.getLog(TicketDisplayTabPane.class); 057 058 059 private Ticket ticket; 060 private Incident[] incidents; 061 private final Dimension scrollerDimension; 062 063 /** 064 * Creates the tab pane with TOP tab layout. 065 * 066 * @param _scrollerDimension the dimension of the scroller that holds the tabs content 067 */ 068 public TicketDisplayTabPane (Dimension _scrollerDimension) { 069 super(SwingConstants.TOP, JTabbedPane.SCROLL_TAB_LAYOUT); 070 scrollerDimension = _scrollerDimension; 071 ToolTipManager.sharedInstance().registerComponent(this); 072 // erstmal eine null-Sicht 073 setTicket(null); 074 } 075 076 /** 077 * Sets a new <code>Ticket</code> that is to be displayed. The display unregisters 078 * from the old ticket. 079 * 080 * @param _ticket the new ticket - can be <code>null</code> to empty the display 081 */ 082 public void setTicket (Ticket _ticket) { 083 084 // beim alten ticket und seinen incidents abmelden 085 if (ticket != null) { 086 ticket.removeTicketChangeListener(this); 087 for (Iterator incidentsIt = Arrays.asList(incidents).iterator(); incidentsIt.hasNext();) 088 ((Incident)incidentsIt.next()).removeIncidentChangeListener(this); 089 } 090 091 // neues ticket merken 092 ticket = _ticket; 093 094 // alle alten tabs entfernen 095 removeAll(); 096 097 // common-tab bauen 098 JScrollPane scroller = new JScrollPane(new TicketTable(ticket)); 099 scroller.setPreferredSize(scrollerDimension); 100 addTab("Common", null, scroller, "bla"); 101 102 // gibts ein neues ticket oder wird die komponente "zurueckgesetzt"? 103 if (ticket == null) { 104 incidents = null; 105 } else { 106 incidents = ticket.getIncidents(); 107 ticket.addTicketChangeListener(this); 108 109 // incident-tabs bauen 110 Incident incident; 111 for (Iterator incidentsIt = Arrays.asList(incidents).iterator(); incidentsIt.hasNext();) { 112 incident = (Incident)incidentsIt.next(); 113 // gleich mal beim incident als listener anemelden 114 incident.addIncidentChangeListener(this); 115 addIncidentTab(incident); 116 } 117 } 118 } 119 120 /** 121 * Adds a tab for <code>incident</code>. 122 * 123 * @param incident the incident 124 */ 125 private void addIncidentTab (Incident incident) { 126 127 IncidentTable incidentTable = new IncidentTable(incident); 128 incidentTable.setName(incident.getOccurrenceDate() + ""); // noch markieren, damit wirs wieder finden 129 JScrollPane scroller = new JScrollPane(incidentTable); 130 scroller.setPreferredSize(scrollerDimension); 131 132 addTab(new Date(incident.getOccurrenceDate().longValue()).toString(), null, scroller, "Lists the incident from " + new Date(incident.getOccurrenceDate().longValue()).toString() + "."); 133 } 134 135 /** 136 * Removes the tab of <code>incident</code> 137 * 138 * @param incident the incident 139 */ 140 private void removeIncidentTab (Incident incident) { 141 // durch alle tabs iterieren und dasjenige loeschen, hinter dem sich der incident verbirgt 142 int incidentIndex = getIndexOfIncident(incident); 143 if (incidentIndex != -1) 144 removeTabAt(incidentIndex); 145 else 146 logger.error("Incident '" + incident.getIncidentSignature() + "' has been removed, but i couldn`t find its tab within me!"); 147 } 148 149 /** 150 * Returns the tab index at which <code>incident</code> is displayed. 151 * 152 * @param incident the incident 153 * @return the index or -1, if <code>incident</code> was not found 154 */ 155 private int getIndexOfIncident (Incident incident) { 156 if (getTabCount() <= 1) 157 return -1; 158 159 for (int i = 1; i < getTabCount(); i++) { 160 // hier gucken, ob der name der komponente mit dem incident-datum uebereinstimmt 161 if (getComponentAt(i).getName().equals(incident.getOccurrenceDate() + "")) { 162 return i; 163 } 164 } 165 return -1; 166 } 167 168 /** 169 * Results in the removal of the corresponding incident tab. 170 * 171 * @see org.tastybug.bugwerk.blueprint.event.TicketChangeListener#performIncidentRemovedEvent(org.tastybug.bugwerk.blueprint.event.TicketChangeListener.IncidentEvent) 172 */ 173 public void performIncidentRemovedEvent(IncidentEvent event) { 174 // keine ueberpruefung, obs ueberhaupt incidents gibt (incidents.length > 0), da es 175 // keinen event gibt, wenns keine incidents gibt 176 removeIncidentTab(event.getIncident()); 177 } 178 179 /** 180 * Results in the appendage of a display tab for the new incident 181 * 182 * @see org.tastybug.bugwerk.blueprint.event.TicketChangeListener#performIncidentAddedEvent(org.tastybug.bugwerk.blueprint.event.TicketChangeListener.IncidentEvent) 183 */ 184 public void performIncidentAddedEvent(IncidentEvent event) { 185 addIncidentTab(event.getIncident()); 186 } 187 188 /** 189 * Results in an update of the base data tab. 190 * 191 * @see org.tastybug.bugwerk.blueprint.event.TicketChangeListener#performTicketChangedEvent(org.tastybug.bugwerk.blueprint.event.TicketChangeListener.TicketChangeEvent) 192 */ 193 public void performTicketChangedEvent(TicketChangeEvent event) { 194 setTicket(event.getTicket()); 195 } 196 197 /** 198 * Results in an update of the corresponding incident tab. 199 * 200 * @see org.tastybug.bugwerk.blueprint.event.IncidentChangeListener#performIncidentChangedEvent(org.tastybug.bugwerk.blueprint.event.IncidentChangeListener.IncidentChangeEvent) 201 */ 202 public void performIncidentChangedEvent(IncidentChangeEvent event) { 203 // alten display loeschen 204 removeIncidentTab(event.getIncident()); 205 // neuen display hinzufuegen 206 addIncidentTab(event.getIncident()); 207 } 208 209 /** 210 * Results in an update of the corresponding incident tab. 211 * 212 * @see org.tastybug.bugwerk.blueprint.event.IncidentChangeListener#performAttachementAddedEvent(org.tastybug.bugwerk.blueprint.event.IncidentChangeListener.AttachmentEvent) 213 */ 214 public void performAttachementAddedEvent(AttachmentEvent event) { 215 // alten display loeschen 216 removeIncidentTab(event.getIncident()); 217 // neuen display hinzufuegen 218 addIncidentTab(event.getIncident()); 219 } 220 221 /** 222 * Results in an update of the corresponding incident tab. 223 * 224 * @see org.tastybug.bugwerk.blueprint.event.IncidentChangeListener#performAttachmentRemovedEvent(org.tastybug.bugwerk.blueprint.event.IncidentChangeListener.AttachmentEvent) 225 */ 226 public void performAttachmentRemovedEvent(AttachmentEvent event) { 227 // alten display loeschen 228 removeIncidentTab(event.getIncident()); 229 // neuen display hinzufuegen 230 addIncidentTab(event.getIncident()); 231 } 232 233 }