package net.sourceforge.cruisecontrol.distributed.util;
import net.sourceforge.cruisecontrol.distributed.BuildAgentService;
import org.apache.log4j.Logger;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.rmi.RemoteException;
/**
* Shows Live Output from the selected agent.
*
* @author Dan Rollo
* Date: May 21, 2010
* Time: 1:11:16 PM
*/
class LiveOutputUI extends JDialog {
private static final Logger LOG = Logger.getLogger(LiveOutputUI.class);
private static final class LiveOutputInfo {
private final String id;
private final int start;
private final String[] lines;
private LiveOutputInfo(final String outputID, final int startLine, final String[] outputLines) {
id = outputID;
start = startLine;
lines = outputLines;
}
public String toString() {
return "LiveOutput: outputID: " + id + ", start: " + start
+ ", lines - count: " + (lines == null ? 0 : lines.length);
}
}
private static final class LUSInfoUI extends JPanel {
private static final Font DISPLAY_FONT = new Font("Courier New", 0, 12);
private LUSInfoUI(final LiveOutputUI parent, final LiveOutputInfo liveOutputInfo) {
super();
setLayout(new BorderLayout());
final JLabel lblInfo = new JLabel("Start: " + liveOutputInfo.start
+ "; Output ID: " + liveOutputInfo.id
+ "; Line Count: " + (liveOutputInfo.lines == null ? 0 : liveOutputInfo.lines.length)
);
lblInfo.setFont(DISPLAY_FONT);
if (liveOutputInfo.lines != null) {
for (final String line : liveOutputInfo.lines) {
parent.txaLines.append(line + "\n");
}
}
final JPanel pnlNorth = new JPanel(new BorderLayout(20, 2));
pnlNorth.add(lblInfo, BorderLayout.NORTH);
add(pnlNorth, BorderLayout.NORTH);
add(parent.txaLines, BorderLayout.CENTER);
}
}
private void rebuild() {
if (pnlAllLUS != null) {
pnlMain.remove(pnlAllLUS);
}
final JPanel pnlView = new JPanel(new GridLayout(0, 1));
final String outputID;
try {
outputID = agent.getIDRemote();
} catch (RemoteException e) {
final String msg = "An error occurred while reading remoteOutputID: ";
LOG.error(msg, e);
throw new RuntimeException(e);
}
final int start = Integer.parseInt(txtStart.getText());
final String[] outputLines;
try {
outputLines = agent.retrieveLinesRemote(start);
} catch (RemoteException e) {
final String msg = "An error occurred while reading retrieveLinesRemote: ";
LOG.error(msg, e);
throw new RuntimeException(e);
}
if (chkUpdateStart.isSelected()) {
if (!outputID.equals(priorOutputID)) {
txtStart.setText("0");
} else {
txtStart.setText(start + outputLines.length + "");
}
}
if (chkClearPriorText.isSelected()) {
txaLines.setText("");
}
priorOutputID = outputID;
final LiveOutputInfo liveOutputInfo = new LiveOutputInfo(outputID, start, outputLines);
pnlView.add(new LUSInfoUI(this, liveOutputInfo));
final JScrollPane scrPane = new JScrollPane(pnlView);
scrPane.setPreferredSize(new Dimension(525, 54));
pnlAllLUS = new JPanel(new BorderLayout());
pnlAllLUS.add(scrPane, BorderLayout.CENTER);
pnlMain.add(pnlAllLUS);
pnlMain.validate();
}
private final BuildAgentService agent;
private final Action atnLiveOutput;
private final JPanel pnlMain;
private JPanel pnlAllLUS;
private final JTextField txtStart;
private final JCheckBox chkUpdateStart;
private final JCheckBox chkClearPriorText;
private final JTextArea txaLines;
private String priorOutputID;
LiveOutputUI(final BuildAgentUtility.UI owner,
final BuildAgentService agentService, final String agentInfo,
final Action atnLiveOutput) {
super(owner, "Live Output - " + agentInfo);
setLocationRelativeTo(owner);
this.agent = agentService;
this.atnLiveOutput = atnLiveOutput;
pnlMain = new JPanel(new BorderLayout(5, 5));
getContentPane().add(pnlMain);
final JLabel lblStart = new JLabel("Start: ");
txtStart = new JTextField(0 + "", 5);
lblStart.setLabelFor(txtStart);
final JPanel pnlTop = new JPanel(new FlowLayout());
pnlTop.add(lblStart);
pnlTop.add(txtStart);
chkUpdateStart = new JCheckBox("Update Start to Output Line Count + 1, or 0 if Output ID changed.", true);
pnlTop.add(chkUpdateStart);
chkClearPriorText = new JCheckBox("Clear Prior Output.", false);
pnlTop.add(chkClearPriorText);
pnlMain.add(pnlTop, BorderLayout.NORTH);
txaLines = new JTextArea();
txaLines.setEditable(false);
final Action atnRefresh = new AbstractAction("Refresh") {
public void actionPerformed(final ActionEvent e) {
LOG.debug("Rebuilding Live Output...");
rebuild();
}
};
final JPanel pnlSouth = new JPanel(new GridLayout());
pnlSouth.add(new JButton(atnRefresh));
final Action atnClose = new AbstractAction("Close") {
public void actionPerformed(final ActionEvent e) {
doExit();
}
};
pnlSouth.add(new JButton(atnClose));
pnlMain.add(pnlSouth, BorderLayout.SOUTH);
addWindowListener(new WindowAdapter() {
public void windowClosing(final WindowEvent evt) {
doExit();
}
});
rebuild();
pack();
setLocationRelativeTo(owner);
setVisible(true);
}
private void doExit() {
LiveOutputUI.this.dispose();
atnLiveOutput.setEnabled(true);
}
}