blob: fc1a8e627d00f33820b27c5a0af6da2c84216860 [file] [log] [blame]
/*******************************************************************************
* Copyright (C) 2009 The University of Manchester
*
* Modifications to the initial code base are copyright of their respective
* authors, or their employers as appropriate.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This program 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 Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307
******************************************************************************/
package net.sf.taverna.t2.ui.perspectives.myexperiment;
import java.awt.Component;
import java.awt.Container;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.net.HttpURLConnection;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JRootPane;
import javax.swing.JScrollPane;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import net.sf.taverna.t2.lang.ui.DialogTextArea;
import net.sf.taverna.t2.ui.perspectives.myexperiment.model.MyExperimentClient;
import net.sf.taverna.t2.ui.perspectives.myexperiment.model.Resource;
import net.sf.taverna.t2.ui.perspectives.myexperiment.model.ServerResponse;
import net.sf.taverna.t2.ui.perspectives.myexperiment.model.Util;
import net.sf.taverna.t2.workbench.helper.HelpEnabledDialog;
import org.apache.log4j.Logger;
/**
* @author Sergejs Aleksejevs, Jiten Bhagat
*/
public class AddCommentDialog extends HelpEnabledDialog implements ActionListener, CaretListener, ComponentListener, KeyListener {
// components for accessing application's main elements
private MainComponent pluginMainComponent;
private MyExperimentClient myExperimentClient;
private Logger logger;
// COMPONENTS
private DialogTextArea taComment;
private JButton bPost;
private JButton bCancel;
private JLabel lStatusMessage;
// STORAGE
private Resource resource; // a resource for which the comment is being posted
private String strComment = null;
private boolean bPostingSuccessful = false;
public AddCommentDialog(JFrame owner, Resource resource, MainComponent component, MyExperimentClient client, Logger logger) {
super(owner, "Add comment for \"" + resource.getTitle() + "\" "
+ resource.getItemTypeName(), true);
// set main variables to ensure access to myExperiment, logger and the parent component
this.pluginMainComponent = component;
this.myExperimentClient = client;
this.logger = logger;
// set the resource for which the comment is being added
this.resource = resource;
// set options of the 'add comment' dialog box
this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
//this.setIconImage(new ImageIcon(MyExperimentPerspective.getLocalResourceURL("myexp_icon")).getImage());
this.initialiseUI();
}
private void initialiseUI() {
// get content pane
Container contentPane = this.getContentPane();
// set up layout
contentPane.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
// add all components
JLabel lInfo = new JLabel("Please type in you comment:");
c.gridx = 0;
c.gridy = 0;
c.anchor = GridBagConstraints.WEST;
c.gridwidth = 2;
c.fill = GridBagConstraints.NONE;
c.insets = new Insets(10, 10, 5, 10);
contentPane.add(lInfo, c);
this.taComment = new DialogTextArea(5, 35);
this.taComment.setLineWrap(true);
this.taComment.setWrapStyleWord(true);
this.taComment.addKeyListener(this);
this.taComment.addCaretListener(this);
JScrollPane spComment = new JScrollPane(this.taComment);
c.gridy = 1;
c.fill = GridBagConstraints.HORIZONTAL;
c.insets = new Insets(0, 10, 0, 10);
contentPane.add(spComment, c);
this.bPost = new JButton("Post Comment");
this.bPost.setEnabled(false);
this.bPost.setDefaultCapable(true);
this.getRootPane().setDefaultButton(this.bPost);
this.bPost.addActionListener(this);
this.bPost.addKeyListener(this);
c.gridy = 2;
c.anchor = GridBagConstraints.EAST;
c.gridwidth = 1;
c.fill = GridBagConstraints.NONE;
c.weightx = 0.5;
c.insets = new Insets(10, 5, 10, 5);
contentPane.add(bPost, c);
this.bCancel = new JButton("Cancel");
this.bCancel.setPreferredSize(this.bPost.getPreferredSize());
this.bCancel.addActionListener(this);
c.gridx = 1;
c.anchor = GridBagConstraints.WEST;
c.weightx = 0.5;
contentPane.add(bCancel, c);
this.pack();
this.setMinimumSize(this.getPreferredSize());
this.setMaximumSize(this.getPreferredSize());
this.addComponentListener(this);
}
/**
* Opens up a modal dialog where the user can enter the comment text.
*
* Window is simply closed if 'Cancel' button is pressed; on pressing 'Post
* Comment' button the window will turn into 'waiting' state, post the comment
* and return the resulting XML document (which would contain the newly added
* comment) back to the caller.
*
* @return String value of the non-empty comment text to be sent to
* myExperiment or null if action was cancelled.
*/
public String launchAddCommentDialogAndPostCommentIfRequired() {
// makes the 'add comment' dialog visible, then waits until it is closed;
// control returns to this method when the dialog window is disposed
this.setVisible(true);
return (strComment);
}
// *** Callback for ActionListener interface ***
public void actionPerformed(ActionEvent e) {
if (e.getSource().equals(this.bPost)) {
// 'Post' button is not active when text in the comment field is blank,
// so if it was pressed, there should be some text typed in
this.strComment = this.taComment.getText();
// the window will stay visible, but should turn into 'waiting' state
final JRootPane rootPane = this.getRootPane();
final Container contentPane = this.getContentPane();
contentPane.remove(this.bPost);
contentPane.remove(this.bCancel);
if (this.lStatusMessage != null)
contentPane.remove(this.lStatusMessage);
this.taComment.setEditable(false);
final GridBagConstraints c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 2;
c.gridwidth = 2;
c.anchor = GridBagConstraints.CENTER;
c.fill = GridBagConstraints.NONE;
c.insets = new Insets(10, 5, 10, 5);
lStatusMessage = new JLabel("Posting your comment...", new ImageIcon(MyExperimentPerspective.getLocalResourceURL("spinner")), SwingConstants.CENTER);
contentPane.add(lStatusMessage, c);
// disable the (X) button (ideally, would need to remove it, but there's no way to do this)
this.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
// revalidate the window
this.pack();
this.validate();
this.repaint();
new Thread("Posting comment") {
public void run() {
// *** POST THE COMMENT ***
final ServerResponse response = myExperimentClient.postComment(resource, Util.stripAllHTML(strComment));
bPostingSuccessful = (response.getResponseCode() == HttpURLConnection.HTTP_OK);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// *** REACT TO POSTING RESULT ***
if (bPostingSuccessful) {
// comment posted successfully
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
taComment.setEnabled(false);
contentPane.remove(lStatusMessage);
c.insets = new Insets(10, 5, 5, 5);
lStatusMessage = new JLabel("Your comment was posted successfully", new ImageIcon(MyExperimentPerspective.getLocalResourceURL("success_icon")), SwingConstants.LEFT);
contentPane.add(lStatusMessage, c);
bCancel.setText("OK");
bCancel.setDefaultCapable(true);
rootPane.setDefaultButton(bCancel);
c.insets = new Insets(5, 5, 10, 5);
c.gridy += 1;
contentPane.add(bCancel, c);
pack();
bCancel.requestFocusInWindow();
} else {
// posting wasn't successful, notify the user
// and provide an option to close window or start again
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
taComment.setEditable(true);
contentPane.remove(lStatusMessage);
c.insets = new Insets(10, 5, 5, 5);
lStatusMessage = new JLabel("Error occurred while posting comment: "
+ Util.retrieveReasonFromErrorXMLDocument(response.getResponseBody()), new ImageIcon(MyExperimentPerspective.getLocalResourceURL("failure_icon")), SwingConstants.LEFT);
contentPane.add(lStatusMessage, c);
bPost.setText("Try again");
bPost.setToolTipText("Please review your comment before trying to post it again");
c.anchor = GridBagConstraints.EAST;
c.insets = new Insets(5, 5, 10, 5);
c.gridwidth = 1;
c.weightx = 0.5;
c.gridx = 0;
c.gridy += 1;
contentPane.add(bPost, c);
rootPane.setDefaultButton(bPost);
c.anchor = GridBagConstraints.WEST;
c.gridx = 1;
bCancel.setPreferredSize(bPost.getPreferredSize());
contentPane.add(bCancel, c);
pack();
validate();
repaint();
}
}
});
}
}.start();
} else if (e.getSource().equals(this.bCancel)) {
// cleanup the comment if it wasn't posted successfully + simply close and destroy the window
if (!this.bPostingSuccessful)
this.strComment = null;
this.dispose();
}
}
// *** Callbacks for KeyListener interface ***
public void keyPressed(KeyEvent e) {
// if TAB was pressed in the text area, need to move keyboard focus
if (e.getSource().equals(this.taComment)
&& e.getKeyCode() == KeyEvent.VK_TAB) {
if ((e.getModifiersEx() & KeyEvent.SHIFT_DOWN_MASK) == KeyEvent.SHIFT_DOWN_MASK) {
// SHIFT + TAB move focus backwards
((Component) e.getSource()).transferFocusBackward();
} else {
// TAB moves focus forward
((Component) e.getSource()).transferFocus();
}
e.consume();
}
}
public void keyReleased(KeyEvent e) {
// not in use
}
public void keyTyped(KeyEvent e) {
// not in use
}
// *** Callback for CaretListener interface ***
public void caretUpdate(CaretEvent e) {
// check whether the 'Post' button should be available or not
this.bPost.setEnabled(this.taComment.getText().length() > 0);
}
// *** Callbacks for ComponentListener interface ***
public void componentShown(ComponentEvent e) {
// center this dialog box within the preview browser window
Util.centerComponentWithinAnother(this.pluginMainComponent.getPreviewBrowser(), this);
}
public void componentHidden(ComponentEvent e) {
// not in use
}
public void componentMoved(ComponentEvent e) {
// not in use
}
public void componentResized(ComponentEvent e) {
// not in use
}
}