/*
This file is part of JFLICKS.
JFLICKS 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.
JFLICKS 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 JFLICKS. If not, see <http://www.gnu.org/licenses/>.
*/
package org.jflicks.ui.view.fe;
import java.awt.Color;
import java.awt.GradientPaint;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Line2D;
import java.text.FieldPosition;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.awt.Dimension;
import java.awt.geom.RoundRectangle2D;
import javax.swing.BorderFactory;
import javax.swing.JLayeredPane;
import javax.swing.SwingConstants;
import javax.swing.Timer;
import org.jdesktop.swingx.JXLabel;
import org.jdesktop.swingx.painter.MattePainter;
import org.jdesktop.swingx.painter.Painter;
import org.jdesktop.swingx.painter.ShapePainter;
import org.jflicks.tv.Airing;
import org.jflicks.tv.Channel;
import org.jflicks.tv.Show;
import org.jflicks.tv.ShowAiring;
/**
* This class supports a grid style guide component. The idea is that
* the component is populated with a HashMap of ShowAiring instances mapped
* by Channel instances. Then the user can set a subset of Channel instances
* to filter the HashMap by. The component will fire SelectedShowAiring
* property events so listeners might want to do stuff like show full details.
* It will also fire SelectedChannel when the user moves to a new Channel
* row in the grid.
*
* @author Doug Barnum
* @version 1.0
*/
public class GridGuidePanel extends BaseCustomizePanel
implements ActionListener {
private static final long JUMP_MILLIS = 30L * 60L * 1000L;
private ArrayList<Channel> channelList;
private HashMap<Channel, ShowAiring[]> guideMap;
private JXLabel dateLabel;
private JXLabel[] timeLabels;
private RowDisplay[] rowDisplays;
private Channel selectedChannel;
private ShowAiring selectedShowAiring;
private long timeOffset;
private long lastTime;
private SimpleDateFormat daySimpleDateFormat;
private SimpleDateFormat timeSimpleDateFormat;
private int selectedRow;
private int selectedColumn;
private int channelIndex;
private int visibleRowCount;
private Timer displayTimer;
/**
* Simple empty constructor.
*/
public GridGuidePanel() {
setChannelList(new ArrayList<Channel>());
setVisibleRowCount(4);
setDaySimpleDateFormat(new SimpleDateFormat("MMM d"));
setTimeSimpleDateFormat(new SimpleDateFormat("h:mm a"));
MattePainter mpainter = new MattePainter(getPanelColor());
setBackgroundPainter(mpainter);
setAlpha((float) getPanelAlpha());
Timer t = new Timer(60000, this);
setDisplayTimer(t);
t.start();
}
public int getVisibleRowCount() {
return (visibleRowCount);
}
public void setVisibleRowCount(int i) {
visibleRowCount = i;
}
private Timer getDisplayTimer() {
return (displayTimer);
}
private void setDisplayTimer(Timer t) {
displayTimer = t;
}
private ArrayList<Channel> getChannelList() {
return (channelList);
}
private void setChannelList(ArrayList<Channel> l) {
channelList = l;
}
private int getChannelCount() {
int result = 0;
ArrayList<Channel> l = getChannelList();
if (l != null) {
result = l.size();
}
return (result);
}
private SimpleDateFormat getDaySimpleDateFormat() {
return (daySimpleDateFormat);
}
private void setDaySimpleDateFormat(SimpleDateFormat sdf) {
daySimpleDateFormat = sdf;
}
private SimpleDateFormat getTimeSimpleDateFormat() {
return (timeSimpleDateFormat);
}
private void setTimeSimpleDateFormat(SimpleDateFormat sdf) {
timeSimpleDateFormat = sdf;
}
public HashMap<Channel, ShowAiring[]> getGuideMap() {
return (guideMap);
}
public void setGuideMap(HashMap<Channel, ShowAiring[]> m) {
guideMap = m;
}
private JXLabel getDateLabel() {
return (dateLabel);
}
private void setDateLabel(JXLabel l) {
dateLabel = l;
}
private JXLabel[] getTimeLabels() {
return (timeLabels);
}
private void setTimeLabels(JXLabel[] array) {
timeLabels = array;
}
private RowDisplay[] getRowDisplays() {
return (rowDisplays);
}
private void setRowDisplays(RowDisplay[] array) {
rowDisplays = array;
}
private long getTimeOffset() {
return (timeOffset);
}
private void setTimeOffset(long l) {
timeOffset = l;
}
private long getLastTime() {
return (lastTime);
}
private void setLastTime(long l) {
lastTime = l;
}
private int getSelectedRow() {
return (selectedRow);
}
private void setSelectedRow(int i) {
selectedRow = i;
}
private int getSelectedColumn() {
return (selectedColumn);
}
private void setSelectedColumn(int i) {
selectedColumn = i;
}
private int getChannelIndex() {
return (channelIndex);
}
private void setChannelIndex(int i) {
if (i < 0) {
channelIndex = 0;
} else {
channelIndex = i;
}
}
public boolean pageUp() {
boolean result = false;
for (int i = 0; i < getVisibleRowCount() - 1; i++) {
boolean action = up();
if (!action) {
break;
} else {
result = true;
}
}
return (result);
}
public boolean pageDown() {
boolean result = false;
for (int i = 0; i < getVisibleRowCount() - 1; i++) {
boolean action = down();
if (!action) {
break;
} else {
result = true;
}
}
return (result);
}
public boolean up() {
boolean result = false;
int newrow = getSelectedRow() - 1;
if (isRowVisible(newrow)) {
applyHighlight(false);
int index = computeGridIndex(getSelectedRow(), newrow,
getSelectedColumn());
setSelectedRow(newrow);
setSelectedColumn(index);
applyHighlight(true);
result = true;
} else {
// We can shift the rows if we can update the ChannelIndex.
int newcindex = getChannelIndex() - 1;
if (newcindex >= 0) {
setChannelIndex(newcindex);
applyHighlight(false);
applyChannels();
int index = computeGridIndex(getSelectedRow() + 1,
getSelectedRow(),
getSelectedColumn());
setSelectedColumn(index);
applyHighlight(true);
result = true;
}
}
return (result);
}
public boolean down() {
boolean result = false;
int newrow = getSelectedRow() + 1;
if (isRowVisible(newrow)) {
applyHighlight(false);
int index = computeGridIndex(getSelectedRow(), newrow,
getSelectedColumn());
setSelectedRow(newrow);
setSelectedColumn(index);
applyHighlight(true);
result = true;
} else {
// We can shift the rows if we can update the ChannelIndex.
int newcindex = getChannelIndex() + 1;
int total = getChannelCount();
int rows = getVisibleRowCount();
if ((newcindex + rows) <= total) {
setChannelIndex(newcindex);
applyHighlight(false);
applyChannels();
int index = computeGridIndex(getSelectedRow() - 1,
getSelectedRow(), getSelectedColumn());
setSelectedColumn(index);
applyHighlight(true);
result = true;
}
}
return (result);
}
public boolean left() {
boolean result = false;
int newcol = getSelectedColumn() - 1;
if (isColumnVisible(newcol)) {
applyHighlight(false);
setSelectedColumn(newcol);
applyHighlight(true);
result = true;
} else {
// We can shift to the left if our timeoff is non-zero.
if (getTimeOffset() > 0L) {
applyHighlight(false);
setTimeOffset(getTimeOffset() - JUMP_MILLIS);
applyTimeLabels();
if (!isColumnVisible(getSelectedColumn())) {
setSelectedColumn(getSelectedColumn() - 1);
}
applyChannels();
applyHighlight(true);
}
}
return (result);
}
public boolean right() {
boolean result = false;
int newcol = getSelectedColumn() + 1;
if (isColumnVisible(newcol)) {
applyHighlight(false);
setSelectedColumn(newcol);
applyHighlight(true);
result = true;
} else {
// We have to shift the time offset.
applyHighlight(false);
setTimeOffset(getTimeOffset() + JUMP_MILLIS);
applyTimeLabels();
applyChannels();
setSelectedColumn(getGreatestVisible());
applyHighlight(true);
}
return (result);
}
/**
* We list channel in our panel.
*
* @return An array of Channel instances.
*/
public Channel[] getChannels() {
Channel[] result = null;
ArrayList<Channel> l = getChannelList();
if ((l != null) && (l.size() > 0)) {
result = l.toArray(new Channel[l.size()]);
}
return (result);
}
/**
* We list channel in our panel.
*
* @param array An array of Channel instances.
*/
public void setChannels(Channel[] array) {
ArrayList<Channel> l = getChannelList();
if (l != null) {
l.clear();
if (array != null) {
for (int i = 0; i < array.length; i++) {
l.add(array[i]);
}
}
if (getChannelIndex() + getVisibleRowCount() >= l.size()) {
setChannelIndex(l.size() - (getVisibleRowCount() + 1));
}
applyChannels();
applyTimeLabels();
applyHighlight(true);
}
}
public Channel getSelectedChannel() {
return (selectedChannel);
}
public void setSelectedChannel(Channel c) {
Channel old = selectedChannel;
selectedChannel = c;
firePropertyChange("SelectedChannel", old, selectedChannel);
}
public ShowAiring getSelectedShowAiring() {
return (selectedShowAiring);
}
public void setSelectedShowAiring(ShowAiring sa) {
ShowAiring old = selectedShowAiring;
selectedShowAiring = sa;
firePropertyChange("SelectedShowAiring", old, selectedShowAiring);
}
/**
* {@inheritDoc}
*/
public void performControl() {
}
/**
* {@inheritDoc}
*/
public void performLayout(Dimension d) {
JLayeredPane pane = getLayeredPane();
if ((d != null) && (pane != null)) {
int width = (int) d.getWidth();
int height = (int) d.getHeight();
int top = (int) (getSmallFontSize() * 1.5);
int rowCount = getVisibleRowCount();
int halfhourwidth = (width / 11) * 2;
int channelwidth = width - (halfhourwidth * 5);
int colheight = height - top;
int cellheight = colheight / rowCount;
if (colheight % rowCount != 0) {
int left = colheight % rowCount;
top += left;
colheight = height - top;
}
JXLabel channelLabel = new JXLabel();
channelLabel.setBorder(BorderFactory.createLineBorder(
getSelectedColor(), 1));
channelLabel.setBounds(0, top, channelwidth, colheight);
pane.add(channelLabel, Integer.valueOf(100));
JXLabel dlabel = new JXLabel("DATE");
dlabel.setFont(getSmallFont());
dlabel.setForeground(getSelectedColor());
dlabel.setBounds(0, 0, channelwidth, top);
pane.add(dlabel, Integer.valueOf(100));
setDateLabel(dlabel);
JXLabel[] larray = new JXLabel[5];
int x = channelwidth;
for (int i = 0; i < larray.length; i++) {
JXLabel halfHourLabel = new JXLabel();
halfHourLabel.setBorder(BorderFactory.createLineBorder(
getUnselectedColor(), 1));
halfHourLabel.setBounds(x, top, halfhourwidth, colheight);
pane.add(halfHourLabel, Integer.valueOf(100));
larray[i] = new JXLabel("TIME");
larray[i].setFont(getSmallFont());
larray[i].setForeground(getSelectedColor());
larray[i].setBounds(x, 0, halfhourwidth, top);
pane.add(larray[i], Integer.valueOf(100));
x += halfhourwidth;
}
setTimeLabels(larray);
RowDisplay[] rdarray = new RowDisplay[rowCount];
int y = top;
for (int i = 0; i < rowCount; i++) {
JXLabel rowLabel = new JXLabel();
rowLabel.setBorder(BorderFactory.createLineBorder(
getUnselectedColor(), 1));
rowLabel.setBounds(0, y, width, cellheight);
pane.add(rowLabel, Integer.valueOf(100));
y += cellheight;
rdarray[i] = new RowDisplay(pane, rowLabel.getBounds(),
channelwidth, halfhourwidth);
}
setRowDisplays(rdarray);
}
}
private long getCurrentRounded() {
Calendar c = Calendar.getInstance();
int min = c.get(Calendar.MINUTE);
if (min < 30) {
min = 0;
} else {
min = 30;
}
c.set(Calendar.MINUTE, min);
c.set(Calendar.SECOND, 0);
return (c.getTimeInMillis() + getTimeOffset());
}
private ShowAiring[] stripDone(ShowAiring[] array) {
ShowAiring[] result = array;
if (array != null) {
if (array.length > 0) {
int skip = 0;
for (int i = 0; i < array.length; i++) {
if (!array[i].isOver()) {
skip = i;
break;
}
}
if (skip > 0) {
result = Arrays.copyOfRange(array, skip, array.length);
}
}
}
return (result);
}
private boolean isOver(ShowAiring sa, long when) {
boolean result = false;
if (sa != null) {
Airing a = sa.getAiring();
if (a != null) {
Date d = a.getAirDate();
if (d != null) {
long end = d.getTime() + (a.getDuration() * 1000);
result = (end < when);
}
}
}
return (result);
}
public boolean isOn(ShowAiring sa) {
boolean result = false;
if (sa != null) {
Airing a = sa.getAiring();
if (a != null) {
Date d = a.getAirDate();
if (d != null) {
long airstart = d.getTime();
long airend = airstart + (a.getDuration() * 1000);
long now = System.currentTimeMillis();
result = ((airstart < now) && (now < airend));
}
}
}
return (result);
}
private boolean isOn(ShowAiring sa, long start, long end) {
boolean result = false;
if (sa != null) {
Airing a = sa.getAiring();
if (a != null) {
Date d = a.getAirDate();
if (d != null) {
long airstart = d.getTime();
long airend = airstart + (a.getDuration() * 1000);
result = (((airstart > start) && (airstart < end))
|| ((airend > start) && (airend < end))
|| ((airstart <= start) && (airend >= end)));
}
}
}
return (result);
}
private ShowAiring[] stripViaTime(ShowAiring[] array, long when) {
ShowAiring[] result = array;
if (array != null) {
if (array.length > 0) {
int skip = 0;
for (int i = 0; i < array.length; i++) {
if (!isOver(array[i], when)) {
skip = i;
break;
}
}
if (skip > 0) {
result = Arrays.copyOfRange(array, skip, array.length);
}
}
}
return (result);
}
private String formatDay(long when) {
String result = null;
SimpleDateFormat sdf = getDaySimpleDateFormat();
if (sdf != null) {
StringBuffer sb = new StringBuffer();
sdf.format(new Date(when), sb, new FieldPosition(0));
result = sb.toString();
}
return (result);
}
private String formatTime(long when) {
String result = null;
SimpleDateFormat sdf = getTimeSimpleDateFormat();
if (sdf != null) {
StringBuffer sb = new StringBuffer();
sdf.format(new Date(when), sb, new FieldPosition(0));
result = sb.toString();
}
return (result);
}
private synchronized void applyChannels() {
Channel[] array = getChannels();
RowDisplay[] rdarray = getRowDisplays();
HashMap<Channel, ShowAiring[]> m = getGuideMap();
if ((array != null) && (rdarray != null) && (m != null)) {
int index = getChannelIndex();
long rounded = getCurrentRounded();
for (int i = 0; i < rdarray.length; i++) {
if (index < array.length) {
Channel chan = array[index];
ShowAiring[] sarray = m.get(chan);
sarray = stripViaTime(sarray, rounded);
rdarray[i].apply(chan, sarray, rounded);
} else {
rdarray[i].apply(null, null, rounded);
}
index++;
}
repaint();
}
}
private void applyTimeLabels() {
long l = getCurrentRounded();
JXLabel label = getDateLabel();
if (label != null) {
label.setText(formatDay(l));
}
JXLabel[] array = getTimeLabels();
if ((array != null) && (array.length > 0)) {
for (int i = 0; i < array.length; i++) {
array[i].setText(formatTime(l));
l += 30 * 60 * 1000;
}
}
}
private void applyHighlight(boolean b) {
RowDisplay[] array = getRowDisplays();
if ((array != null) && (array.length > 0)) {
int row = getSelectedRow();
if ((row >= array.length) || (row < 0)) {
row = 0;
}
int column = getSelectedColumn();
array[row].select(b, column);
if (b) {
// Set our selected channel when we highlight.
setSelectedChannel(array[row].getChannel());
}
}
}
private int getIndex(Channel[] array, Channel c) {
int result = 0;
if ((array != null) && (c != null)) {
for (int i = 0; i < array.length; i++) {
if (c.equals(array[i])) {
result = i;
break;
}
}
}
return (result);
}
public void setCurrentChannel(Channel c) {
if (c != null) {
setChannelIndex(getIndex(getChannels(), c));
applyChannels();
setSelectedColumn(0);
setSelectedRow(0);
applyHighlight(true);
}
}
private int computeGridIndex(int oldrow, int newrow, int defaultColumn) {
int result = defaultColumn;
RowDisplay[] array = getRowDisplays();
if ((array != null) && (oldrow >= 0) && (newrow >= 0)
&& (oldrow != newrow) && (oldrow < array.length)
&& (newrow < array.length)) {
RowDisplay oldrd = array[oldrow];
RowDisplay newrd = array[newrow];
ShowAiring sa = oldrd.getShowAiringByIndex(defaultColumn);
if (sa != null) {
result = newrd.match(sa, defaultColumn);
}
}
return (result);
}
private int getGreatestVisible() {
int result = 0;
int row = getSelectedRow();
RowDisplay[] array = getRowDisplays();
if ((array != null) && (array.length > 0) && (row < array.length)) {
result = array[row].getGreatestVisible();
}
return (result);
}
private boolean isColumnVisible(int column) {
boolean result = false;
RowDisplay[] array = getRowDisplays();
if ((array != null) && (array.length > 0) && (column >= 0)) {
int row = getSelectedRow();
if (row >= array.length) {
row = 0;
}
result = array[row].isColumnVisible(column);
}
return (result);
}
private boolean isRowVisible(int row) {
boolean result = false;
RowDisplay[] array = getRowDisplays();
if ((array != null) && (array.length > 0) && (row >= 0)
&& (row < array.length)) {
result = true;
}
return (result);
}
public void actionPerformed(ActionEvent event) {
if (getGuideMap() != null) {
long last = getLastTime();
if (last != 0L) {
long current = getCurrentRounded() - getTimeOffset();
if ((Math.abs(current - last)) > 1000) {
// The start of our time line has changed. We should
// update. This can be unsettling to the user if they
// are interacting right now. But this should happen
// only every 30 minutes.
int row = getSelectedRow();
int col = getSelectedColumn();
setLastTime(current);
applyTimeLabels();
applyChannels();
setSelectedColumn(col);
setSelectedRow(row);
repaint();
}
} else {
setLastTime(getCurrentRounded() - getTimeOffset());
}
}
}
class RowDisplay {
private JLayeredPane layeredPane;
private Rectangle rectangle;
private int channelWidth;
private int halfHourWidth;
private JXLabel channelLabel;
private JXLabel[] labels;
private ShowAiring[] showAirings;
private Channel channel;
public RowDisplay(JLayeredPane p, Rectangle r, int cwidth, int swidth) {
setLayeredPane(p);
setRectangle(r);
setChannelWidth(cwidth);
setHalfHourWidth(swidth);
// Make 10 labels and put them all at (-1, -1, 0, 0)
JXLabel[] array = new JXLabel[10];
for (int i = 0; i < array.length; i++) {
array[i] = new JXLabel();
array[i].setTextAlignment(JXLabel.TextAlignment.CENTER);
array[i].setLineWrap(true);
array[i].setForeground(getSelectedColor());
array[i].setFont(getSmallFont());
array[i].setBorder(BorderFactory.createLineBorder(
getSelectedColor(), 1));
array[i].setBounds(-1, -1, 0, 0);
p.add(array[i], Integer.valueOf(110));
}
setLabels(array);
// We keep an associated array of ShowAiring so we can easily
// update the SelectedShowAiring. We set this array values on
// an apply().
ShowAiring[] showArray = new ShowAiring[10];
setShowAirings(showArray);
JXLabel clabel = new JXLabel();
clabel.setTextAlignment(JXLabel.TextAlignment.CENTER);
clabel.setFont(getSmallFont());
clabel.setLineWrap(true);
clabel.setForeground(getSelectedColor());
clabel.setBounds(r.x, r.y, cwidth, r.height);
setChannelLabel(clabel);
p.add(clabel, Integer.valueOf(110));
}
private JLayeredPane getLayeredPane() {
return (layeredPane);
}
private void setLayeredPane(JLayeredPane p) {
layeredPane = p;
}
private Rectangle getRectangle() {
return (rectangle);
}
private void setRectangle(Rectangle r) {
rectangle = r;
}
private int getChannelWidth() {
return (channelWidth);
}
private void setChannelWidth(int i) {
channelWidth = i;
}
private int getHalfHourWidth() {
return (halfHourWidth);
}
private void setHalfHourWidth(int i) {
halfHourWidth = i;
}
private JXLabel getChannelLabel() {
return (channelLabel);
}
private void setChannelLabel(JXLabel l) {
channelLabel = l;
}
private JXLabel[] getLabels() {
return (labels);
}
private void setLabels(JXLabel[] array) {
labels = array;
}
private ShowAiring[] getShowAirings() {
return (showAirings);
}
private void setShowAirings(ShowAiring[] array) {
showAirings = array;
}
public Channel getChannel() {
return (channel);
}
private void setChannel(Channel c) {
channel = c;
}
public ShowAiring getShowAiringByIndex(int index) {
ShowAiring result = null;
ShowAiring[] array = getShowAirings();
if ((array != null) && (index < array.length) && (index >= 0)) {
result = array[index];
}
return (result);
}
private long getShowAiringStart(ShowAiring sa) {
long result = 0L;
if (sa != null) {
Airing a = sa.getAiring();
if (a != null) {
Date d = a.getAirDate();
if (d != null) {
result = d.getTime();
}
}
}
return (result);
}
private long getShowAiringEnd(ShowAiring sa) {
long result = 0L;
if (sa != null) {
Airing a = sa.getAiring();
if (a != null) {
result = getShowAiringStart(sa) + (a.getDuration() * 1000);
}
}
return (result);
}
public int match(ShowAiring sa, int defaultIndex) {
int result = defaultIndex;
ShowAiring[] array = getShowAirings();
if ((sa != null) && (array != null) && (array.length > 0)) {
long most = 0L;
double start = (double) getShowAiringStart(sa);
double end = (double) getShowAiringEnd(sa);
Line2D.Double line =
new Line2D.Double(start + 10, 0, end - 10, 0);
for (int i = 0; i < array.length; i++) {
start = (double) getShowAiringStart(array[i]);
end = (double) getShowAiringEnd(array[i]);
if (line.intersectsLine(start, 0, end, 0)) {
result = i;
break;
}
}
}
return (result);
}
private int computeX(long startTime, long current) {
int result = 0;
long offset = current - startTime;
if (offset > 0) {
// Figure the minutes first.
double doffset = (double) offset;
double sec = doffset / 1000;
double min = sec / 60;
double halfHour = (double) getHalfHourWidth();
double permin = halfHour / 30;
result = (int) (min * permin);
}
return (result);
}
private Painter createPainter(Rectangle r, Color main, Color c) {
Painter result = null;
Color mcopy = new Color(main.getRed(), main.getGreen(),
main.getBlue(), (int) (getAlpha() * 255));
Color copy = new Color(c.getRed(), c.getGreen(),
c.getBlue(), (int) (getAlpha() * 255));
GradientPaint gp = new GradientPaint(r.width / 2, 0, copy,
r.width / 2, (int) (r.getHeight() * 0.1), mcopy, false);
int inset = 8;
double arc = 10.0;
RoundRectangle2D.Double rr = new RoundRectangle2D.Double(inset,
inset, r.width - (inset * 2), r.height - (inset * 2), arc, arc);
ShapePainter sp = new ShapePainter(rr, gp);
MattePainter mp = new MattePainter(gp);
result = mp;
return (result);
}
public void apply(Channel c, ShowAiring[] array, long startTime) {
long endTime = startTime + 149 * 60 * 1000;
setChannel(c);
// First set the Channel text.
JXLabel clabel = getChannelLabel();
JXLabel[] larray = getLabels();
if ((clabel != null) && (larray != null)) {
if (c != null) {
clabel.setText(c.toString());
} else {
clabel.setText("");
}
JXLabel[] labs = getLabels();
ShowAiring[] showArray = getShowAirings();
if ((labs != null) && (showArray != null)) {
for (int i = 0; i < labs.length; i++) {
labs[i].setBounds(-1, -1, 0, 0);
}
int count = 0;
for (int i = 0; i < labs.length; i++) {
if (array != null) {
if (isOn(array[i], startTime, endTime)) {
count++;
}
}
}
int x = 0;
int lastx = 0;
int w = 0;
for (int i = 0; i < labs.length; i++) {
if (array != null) {
showArray[i] = array[i];
} else {
showArray[i] = null;
}
if (i < count) {
Airing air = array[i].getAiring();
Show show = array[i].getShow();
if ((air != null) && (show != null)) {
Date d = air.getAirDate();
if (d != null) {
long start = d.getTime();
long end = start
+ (air.getDuration() * 1000);
if (i == 0) {
x = computeX(startTime, start)
+ getChannelWidth();
} else {
x = lastx;
}
lastx = computeX(startTime, end)
+ getChannelWidth();
w = lastx - x;
labs[i].setBounds(x, rectangle.y, w,
rectangle.height);
labs[i].setText(show.getTitle());
Painter p = createPainter(
labs[i].getBounds(),
getPanelColor(),
getSelectedColor());
labs[i].setBackgroundPainter(p);
}
}
}
}
}
}
}
public boolean isColumnVisible(int column) {
boolean result = false;
JXLabel[] labs = getLabels();
if ((labs != null) && (column < labs.length)) {
Rectangle r = labs[column].getBounds();
result = (r.x != -1);
}
return (result);
}
public int getGreatestVisible() {
int result = 0;
JXLabel[] labs = getLabels();
if (labs != null) {
for (int i = labs.length - 1; i >= 0; i--) {
Rectangle r = labs[i].getBounds();
if (r.x != -1) {
result = i;
break;
}
}
}
return (result);
}
public void select(boolean b, int column) {
JXLabel[] labs = getLabels();
ShowAiring[] showArray = getShowAirings();
if ((labs != null) && (column < labs.length)
&& (showArray != null)) {
Color c = null;
Painter p = null;
if (b) {
c = getHighlightColor();
p = createPainter(labs[column].getBounds(),
getHighlightColor(), getSelectedColor());
} else {
c = getSelectedColor();
p = createPainter(labs[column].getBounds(),
getPanelColor(), getSelectedColor());
}
labs[column].setBorder(BorderFactory.createLineBorder(c, 1));
labs[column].setBackgroundPainter(p);
if (b) {
setSelectedShowAiring(showArray[column]);
}
}
}
}
}