package com.salas.bb.networking.manager;
import com.jgoodies.forms.layout.CellConstraints;
import com.salas.bb.utils.Constants;
import com.salas.bb.utils.StringUtils;
import com.salas.bb.utils.i18n.Strings;
import com.salas.bb.utils.uif.BBFormBuilder;
import com.salas.bb.utils.uif.treetable.JTreeTable;
import com.salas.bb.utils.uif.treetable.TreeTableModel;
import javax.swing.*;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.table.TableColumn;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.text.MessageFormat;
/**
* Networking manager window.
*/
public final class ActivityWindow extends JDialog
{
private static final int DEFAULT_WIDTH = 300;
private static final int DEFAULT_HEIGHT = 200;
// Number of points the font should be smaller for whole content of the window
private static final int FONT_SIZE_DECREMENT = 1;
private static ActivityWindow instance;
/**
* Returns instance of window. If not created yet then it will be created using parent frame
* specified.
*
* @param parent parent frame.
*
* @return instance of window.
*/
public synchronized static ActivityWindow getInstance(JFrame parent)
{
if (instance == null) instance = new ActivityWindow(parent);
return instance;
}
/**
* Creates a window and connects it to the frame.
*
* @param parent parent frame.
*/
private ActivityWindow(JFrame parent)
{
super(parent, Strings.message("activity.title"), false);
initGUI();
}
// Initializes GUI
private void initGUI()
{
Container c = getContentPane();
c.setLayout(new BorderLayout());
c.add(createMainArea(), BorderLayout.CENTER);
// center
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
int x = (int)(screenSize.getWidth() - DEFAULT_WIDTH) / 2;
int y = (int)(screenSize.getHeight() - DEFAULT_HEIGHT) / 2;
setBounds(x, y, DEFAULT_WIDTH, DEFAULT_HEIGHT);
}
// Creates main area
private JComponent createMainArea()
{
JScrollPane sp = createTasksTreeTable();
BBFormBuilder builder = new BBFormBuilder("2dlu, pref:grow, 7dlu");
builder.appendRow("min:grow");
builder.append(sp, 3, CellConstraints.FILL, CellConstraints.FILL);
return builder.getPanel();
}
// Creates tree table in main area
private JScrollPane createTasksTreeTable()
{
NetTasksModel model = new NetTasksModel(NetManager.getRootTasksGroup());
JTreeTable treeTable = new NetTasksTreeTable(model);
JScrollPane sp = new JScrollPane(treeTable);
sp.getViewport().setBackground(treeTable.getBackground());
return sp;
}
/**
* Makes an operation over the given task. The operation will be performed depends on
* current status of the task.
*
* @param aTask task.
*/
private void doTaskOperation(NetTask aTask)
{
if (aTask == null) return;
int status = aTask.getStatus();
switch (status)
{
case NetTask.STATUS_ABORTED:
case NetTask.STATUS_COMPLETED:
case NetTask.STATUS_ERRORED:
// Do nothing
break;
case NetTask.STATUS_PAUSED:
aTask.resume();
break;
case NetTask.STATUS_CONNECTING:
case NetTask.STATUS_RUNNING:
aTask.pause();
break;
default:
break;
}
}
/**
* Custom component for net tasks displaying. It is capable of telling the correct tool-tip
* text for tasks and groups.
*/
private class NetTasksTreeTable extends JTreeTable
{
public NetTasksTreeTable(TreeTableModel model)
{
super(model);
setSelectionBackground(getBackground());
// Fonts setup
Font font = getFont();
font = font.deriveFont((float)font.getSize() - FONT_SIZE_DECREMENT);
Font fontGroup = font.deriveFont(Font.BOLD);
// Remove icons from leaves
DefaultTreeCellRenderer renderer = new CustomTreeCellRenderer(fontGroup, font);
renderer.setLeafIcon(null);
renderer.setClosedIcon(null);
renderer.setOpenIcon(null);
setTreeCellRenderer(renderer);
setRootVisible(false);
setShowsRootHandles(true);
// Setup rendering of cells
ProgressCellRenderer progressRenderer = new ProgressCellRenderer();
setDefaultRenderer(Integer.class, new CommandCellRenderer());
setDefaultRenderer(Double.class, progressRenderer);
addMouseListener(new MouseAdapter()
{
public void mousePressed(MouseEvent e)
{
Point point = e.getPoint();
int col = columnAtPoint(point);
if (col == NetTasksModel.COL_COMMANDS)
{
int row = rowAtPoint(point);
NetTask task = (NetTask)getValueAt(row, -1);
doTaskOperation(task);
}
}
});
// Table setup
setColumnWidth(NetTasksModel.COL_COMMANDS, 20, 20);
setColumnWidth(NetTasksModel.COL_TASK_NAME, 150, -1);
setColumnWidth(NetTasksModel.COL_PROGRESS, 75, -1);
setFont(font);
progressRenderer.setFont(font);
// Set horizontal division lines
JTree treeRenderer = getTreeRenderer();
treeRenderer.putClientProperty("JTree.lineStyle", "None");
}
// Sets the widths of selected column
private void setColumnWidth(int columnIndex, int minWidth, int maxWidth)
{
TableColumn column = getColumnModel().getColumn(columnIndex);
if (minWidth != -1) column.setMinWidth(minWidth);
if (maxWidth != -1) column.setMaxWidth(maxWidth);
}
/**
* Returns tip text for a given mouse event.
*
* @param event event.
*
* @return text.
*/
public String getToolTipText(MouseEvent event)
{
String text = null;
int row = rowAtPoint(event.getPoint());
if (row != -1)
{
NetTask task = (NetTask)getValueAt(row, -1);
text = getToolTip(task);
}
return text;
}
/**
* Returns tool-tip text for a task.
*
* @param aTask task.
*
* @return text.
*/
private String getToolTip(NetTask aTask)
{
String text;
if (aTask == null) return null;
if (aTask instanceof NetTaskGroup)
{
text = aTask.getTitle();
} else
{
String feed = aTask.getFeed();
if (feed == null) feed = Strings.message("activity.feed.unknown");
String size = StringUtils.sizeToString(aTask.getSize());
String sourceURL = aTask.getSourceURL().toString();
String startTime = Constants.DATE_TIME_FORMAT.format(aTask.getStartTime());
text = MessageFormat.format(Strings.message("activity.status"),
new Object[] { StringUtils.escape(feed), StringUtils.escape(sourceURL), size, startTime });
}
return text;
}
/**
* Custom renderer with separate fonts for group and task.
*/
private class CustomTreeCellRenderer extends DefaultTreeCellRenderer
{
private Font groupFont;
private Font taskFont;
/**
* Creates renderer with specific fonts for group and task.
*
* @param aGroupFont group font.
* @param aTaskFont task font.
*/
public CustomTreeCellRenderer(Font aGroupFont, Font aTaskFont)
{
groupFont = aGroupFont;
taskFont = aTaskFont;
}
/**
* Configures the renderer based on the passed in components. The value is set
* from messaging the tree with <code>convertValueToText</code>, which ultimately
* invokes <code>toString</code> on <code>value</code>. The foreground color is
* set based on the selection and the icon is set based on on leaf and expanded.
*/
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel,
boolean expanded, boolean leaf, int row, boolean hasFocus)
{
Component comp = super.getTreeCellRendererComponent(tree,
value, sel, expanded, leaf, row, hasFocus);
Font fnt = (value instanceof NetTaskGroup) ? groupFont : taskFont;
comp.setFont(fnt);
return comp;
}
}
}
}