package org.greenstone.gatherer.feedback;
import java.io.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import java.util.*;
import java.net.*;
import java.rmi.server.*;
import javax.imageio.*;
import java.util.Locale;
import java.util.ResourceBundle;
import java.text.MessageFormat;
import com.sun.image.codec.jpeg.*;
import javax.swing.Timer;
import org.greenstone.gatherer.util.Utility;
/**
* This class will show the FeedbackInterface form.
* It will allow user to described about the problem better.Here we will also take some more information available
* in the system such as the size of the memory available and the screen size.User also could take more screenshot
* so they will be able to say the sequence of events that lead up to the problem.
*
If the user don't want to send this form, then all the information taken from this form will be deleted
* and user will be quitted from the Reporting Feedback sequence.
*
* @author Veronica Liesaputra
*/
public class FeedbackInterface extends JDialog
implements ActionListener
{
/**
* This is the button user need to pressed if they want to view the files.
* This button will be disabled when the timer is running and finish = false.
*/
private JButton view_button;
/**
* This button means that the user finished give the information and
* want to send it.
*/
public JButton send_button;
/**
* This button means that the user don't want to send information and
* back to normal application.
* All the data taken start from user choose to start doing the Feedback sequence
* up to this point will be delete.
*/
private JButton notsend_button;
/**
* This is the text area where user can explain more about the problem.
*/
private JTextArea problem_details;
/**
* This is the combo box that allow user to specify the poblem type.
*/
private JComboBox problem_type;
/**
* This is the combo box that allow user to specify the urgency of the problem.
*/
private JComboBox problem_urgency;
/**
* This combo box will ask whether or not user want to send the screenshot.
*/
private JComboBox problem_screenshot;
/**
* This text field allow user to type the smtp address of their email that
* they want this application to use to send all the data.
* If they don't fill this field then it will set to the same
* smtp adress of where the data will be send to.
*/
private JTextField smtp_address;
/**
* This text field allow user to type the email adress that they want this
* application to use to send all the data.
* If they don't fill this field then it will set to the same email
* adress of where the data will be send to.
*/
private JTextField email_address;
/**
* This is the name of the window the user lastly used.
* This is the name of the window where the user called to start the Feedback
* sequence.
*/
private String frameName;
/**
* This is the unique code generated for each time user start doing the Feedback
* sequence.
* This code will be used as reference to which feedback that the user send.
*/
private static String code;
/**
* This is the date when the user start open this FeedbackInterface form.
*/
private Date curr_date;
/**
* This is the special listener class that record all the action user did in application.
*/
private static ActionRecorderDialog dialog;
/**
* This variable will hold the resource of the words that is stored in Messages.properties file.
* The calling using messages.getString(someString) will caused someString to be translated
* into some other string that is hold in that file.usually it will caused it to be translated
* to the language that the user use or choose to have as stated in Locale.
*/
private static ResourceBundle messages;
/**
* This is the screen shot instance that will allow the application to take screen shot of the whole
* screen or only the window that the user currently doing their action.
*/
private ScreenShot screen;
/**
* This is the thread that allows the encoding of the image file to String and the saving of image to
* a jpeg file happens concurrently.
*/
private Thread save;
/**
* This is the hashmap that hold the screen shot and the panel where the screenshot is held.
*/
private HashMap picAndPane;
/**
* This is the panel that hold all the panels containing the screenshots taken.
*/
private JPanel picture_scroll;
/**
* This is how many rows of screenshots panel displayed at the moment.
*/
private int row;
/**
* This is the array list that hold all the screenshots panel displayed.
*/
private ArrayList paneArray;
/**
* This button will remove the last screenshot panels.
*/
private JButton remove;
/**
* This is a reference to feedback interface displayed at the moment.
*/
private FeedbackInterface frame;
/**
* This is the thread to send all the xml files back to the developer.
*/
private Thread sendThread;
/**
* This is the flag to tell whether or not the sending files finished or not.
* It is also flag to tell whether or not the viewing files finished or not.
*/
private static boolean finish;
/**
* This is the timer to displayed the progress bar to tell user to wait while
* we sending the files or while we generate the xml files to be viewed.
* If finish = false then wait cursor,progress bar and wait label will be displayed.
* If finish = true then default cursor will be displayed.
*/
private Timer timer;
/**
* Progress bar displayed when user sending or want to view details.
*/
private JProgressBar progressBar;
/**
* Label displayed to tell user to wait for a while.
*/
private JLabel wait_lbl;
/**
* This is the background colour for the window.
*/
private Color bckcolor;
/**
* This is the panel to displayed all descriptions panel.
*/
private JPanel tempPane;
/**
* This is the thread that will be running when user pressed the preview button.
* This thread will show the 6 xml files that are going to be send. It will run concurrently
* with the timer, if value of finish = true, this thread will be null-ed.
*/
private Thread prevThread;
/**
* This is the flag to say whether or not this window should be dispose when timer is stop
* and finish = true.
* If selected = true then this window should be dispose, otherwise don't dispose it.
*/
private boolean selected = false;
/**
* This is a blocker to say that user cannot do anything while waiting.
*/
private MouseListener mouse_blocker_listener = new MouseAdapter() {};
/**
* Will make a dialog window that allows people to write more about the problem that want
* to send.
* This is the GUI for user to write on Feedback form. It is also setting the up the appropriate
* data member with the value passed on to this constructor.
* (Precondition: (sh != null) && (dlg != null) && (msg != null))
* @param sh an instance of ScreenShot that will allow application to take screenshot.
* @param frame_name name of the window where user called Feedback form from.
* @param msg holding the resource of the words that is stored in Messages.properties file.
* @param dlg holding the special listener.
*/
public FeedbackInterface(ScreenShot sh,String frame_name,
ResourceBundle msg,ActionRecorderDialog dlg)
{
super();
frame = this;
bckcolor = new Color(176,209,217);
picAndPane = new HashMap();
messages = msg;
frameName = frame_name;
dialog = dlg;
FeedbackInterface.setDefaultLookAndFeelDecorated(true);
setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
setTitle(messages.getString("SendFeedbackForm"));
screen = sh;
Container container;
container = getContentPane();
createUI(container);
curr_date = new Date();
Toolkit kit;
kit = Toolkit.getDefaultToolkit();
Dimension screenSize;
screenSize = kit.getScreenSize();
int screenHeight;
screenHeight = screenSize.height;
int screenWidth;
screenWidth = screenSize.width;
Dimension size;
size = this.getSize();
setLocation((screenWidth - size.width - 500) ,
(screenHeight - size.height - 700));
setBackground(bckcolor);
pack();
setModal(false);
setVisible(true);
}
/**
* This method is setting up the content pane for the Feedback form window.
* (Precondition: (window != null))
* @param window the content pane of Feedback form window.
*/
public void createUI(Container window)
{
JPanel container;
container = new JPanel();
container.setBackground(bckcolor);
container.setLayout(new BoxLayout(container,BoxLayout.PAGE_AXIS));
String opening_text;
opening_text = messages.getString("FeedbackOpeningText");
JTextArea textArea;
textArea = new JTextArea(opening_text);
textArea.setMinimumSize(new Dimension(100,100));
textArea.setOpaque(false);
textArea.setEditable(false);
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);
textArea.setBorder(new EmptyBorder(10,10,0,10));
textArea.setBackground(bckcolor);
container.add(textArea);
tempPane = new JPanel();
tempPane.setLayout(new BorderLayout());
tempPane.setBackground(new Color(176,208,176));
paneArray = new ArrayList();
picture_scroll = new JPanel();
row = 1;
picture_scroll.setLayout(new GridLayout(0,1));
picture_scroll.setBackground(new Color(176,208,176));
tempPane.add(picture_scroll,BorderLayout.PAGE_START);
JPanel btnPanel;
btnPanel = new JPanel();
btnPanel.setBackground(new Color(176,208,176));
remove = new JButton("Remove");
remove.setActionCommand("Remove");
remove.addActionListener(new ActionListener ()
{
public void actionPerformed(ActionEvent e)
{
Object obj;
JPanel pane;
if (paneArray.size() == 0)
System.out.println("There is no panel here!!");
else
{
pane = (JPanel) paneArray.get((row - 2));
obj = picAndPane.get(pane);
obj = null;
picAndPane.remove(pane);
paneArray.remove((row - 2));
if (paneArray.size() == 0)
remove.setVisible(false);
picture_scroll.remove(pane);
row--;
picture_scroll.setSize(picture_scroll.getPreferredSize());
picture_scroll.revalidate();
picture_scroll.repaint();
tempPane.setSize(tempPane.getPreferredSize());
tempPane.revalidate();
tempPane.repaint();
}
}
});
remove.setToolTipText("Remove last thumbnail");
remove.setBackground(new Color(176,208,176));
remove.setVisible(false);
btnPanel.add(remove);
tempPane.add(btnPanel,BorderLayout.PAGE_END);
JScrollPane pict_scroll;
pict_scroll = new JScrollPane(tempPane);
pict_scroll.setBackground(bckcolor);
pict_scroll.setPreferredSize(new Dimension(300,300));
pict_scroll.setBorder(new EmptyBorder(0,10,10,10));
container.add(pict_scroll);
JPanel pane;
pane = new JPanel();
pane.setBackground(bckcolor);
pane.setLayout(new GridLayout(0,2));
pane.setBorder(new EmptyBorder(10,10,10,10));
JLabel txt_type;
txt_type = new JLabel(messages.getString("Whatkindofproblemisit") + "? ");
txt_type.setBackground(bckcolor);
pane.add(txt_type);
String [] type = {" ",messages.getString("ContentError"),
messages.getString("ImageNotShow"),
messages.getString("StrangeBehaviour"),
messages.getString("SomethingUnexpectedHappen"),
messages.getString("HardToUse"),
messages.getString("Other")};
problem_type = new JComboBox(type);
problem_type.addActionListener(this);
problem_type.setBackground(bckcolor);
pane.add(problem_type);
JLabel txt_urgent;
txt_urgent = new JLabel(messages.getString("Howbadistheproblem")+"? ");
txt_urgent.setBackground(bckcolor);
pane.add(txt_urgent);
String[] urgent = {" ",messages.getString("Critical"),
messages.getString("Serious"),
messages.getString("Medium"),messages.getString("Minor"),
messages.getString("Trivial")};
problem_urgency = new JComboBox(urgent);
problem_urgency.addActionListener(this);
problem_urgency.setBackground(bckcolor);
pane.add(problem_urgency);
/*JLabel txt_screenshot;
txt_screenshot= new JLabel(messages.getString("Doyouwanttosendthescreenshot") + "? ");
txt_screenshot.setBackground(new Color(108,168,108));
pane.add(txt_screenshot);
String[] screenshot = {messages.getString("Yes"),
messages.getString("No")};
problem_screenshot = new JComboBox(screenshot);
problem_screenshot.addActionListener(this);
problem_screenshot.setBackground(new Color(108,168,108));
pane.add(problem_screenshot);*/
/*JLabel txt_smtp;
txt_smtp = new JLabel(messages.getString("SMTPaddress") + "? ");
txt_smtp.setBackground(new Color(176,208,176));
pane.add(txt_smtp);
smtp_address = new JTextField();
smtp_address.setBackground(new Color(224,240,224));
pane.add(smtp_address);*/
/*JLabel txt_email;
txt_email = new JLabel(messages.getString("Emailaddress") + "? ");
txt_email.setBackground(new Color(176,208,176));
pane.add(txt_email);
email_address = new JTextField();
email_address.setBackground(new Color(224,240,224));
pane.add(email_address);*/
JLabel empty;
empty = new JLabel (" ");
empty.setBackground(bckcolor);
pane.add(empty);
JLabel empty2;
empty2 = new JLabel (" ");
empty2.setBackground(bckcolor);
pane.add(empty2);
container.add(pane);
JPanel panely;
panely = new JPanel();
panely.setLayout(new GridLayout(0,3));
panely.setBackground(bckcolor);
panely.setBorder(new EmptyBorder(new Insets(10,10,10,10)));
view_button = new JButton("Details . . .");
view_button.setActionCommand(messages.getString("Preview"));
view_button.addActionListener(this);
view_button.setToolTipText(messages.getString("ConformationPreview"));
view_button.setBackground(bckcolor);
panely.add(view_button);
send_button = new JButton(messages.getString("Send"));
send_button.setActionCommand(messages.getString("Send"));
send_button.addActionListener(this);
send_button.setDefaultCapable(true);
send_button.setToolTipText(messages.getString("FeedbackSendButton"));
send_button.setBackground(bckcolor);
panely.add(send_button);
notsend_button = new JButton("Cancel");
notsend_button.setActionCommand(messages.getString("NotSend"));
notsend_button.addActionListener(this);
notsend_button.setToolTipText(messages.getString("FeedbackNotSendButton"));
notsend_button.setBackground(bckcolor);
panely.add(notsend_button);
container.add(panely);
//Align the left edges of the components.
textArea.setAlignmentX(Component.LEFT_ALIGNMENT);
pict_scroll.setAlignmentX(Component.LEFT_ALIGNMENT);
pane.setAlignmentX(Component.LEFT_ALIGNMENT);
panely.setAlignmentX(Component.LEFT_ALIGNMENT);
String about;
about = messages.getString("FeedbackAboutText");
JTextArea about_txt;
about_txt = new JTextArea(about);
about_txt.setEditable(false);
about_txt.setLineWrap(true);
about_txt.setWrapStyleWord(true);
about_txt.setBackground(bckcolor);
about_txt.setBorder(new EmptyBorder(10,10,10,10));
String privacy;
privacy = messages.getString("FeedbackPrivacyText");
JTextArea privacy_txt;
privacy_txt = new JTextArea(privacy);
privacy_txt.setEditable(false);
privacy_txt.setLineWrap(true);
privacy_txt.setWrapStyleWord(true);
privacy_txt.setBackground(bckcolor);
privacy_txt.setBorder(new EmptyBorder(10,10,10,10));
JTabbedPane tab;
tab = new JTabbedPane();
tab.setBackground(bckcolor);
tab.addTab(messages.getString("Form"),container);
tab.addTab(messages.getString("About"),about_txt);
tab.addTab(messages.getString("Privacy"),privacy_txt);
tab.setBorder(new EmptyBorder(5,5,5,5));
JPanel panelx;
panelx = new JPanel();
panelx.setLayout(new BoxLayout(panelx,BoxLayout.PAGE_AXIS));
panelx.setBackground(bckcolor);
panelx.setBorder(new EmptyBorder(new Insets(10,10,10,10)));
wait_lbl = new JLabel(messages.getString("Pleasewait"));
wait_lbl.setBackground(bckcolor);
wait_lbl.setVisible(false);
panelx.add(wait_lbl);
progressBar = new JProgressBar ();
progressBar.setBackground(bckcolor);
progressBar.setVisible(false);
panelx.add(progressBar);
JLabel emp2;
emp2 = new JLabel (" ");
emp2.setBackground(bckcolor);
panelx.add(emp2);
wait_lbl.setAlignmentX(Component.CENTER_ALIGNMENT);
progressBar.setAlignmentX(Component.CENTER_ALIGNMENT);
emp2.setAlignmentX(Component.CENTER_ALIGNMENT);
final String p1;
final String p2;
p1 = "Tab";
p2 = "ProgressBar";
final JPanel cards;
cards = new JPanel(new CardLayout());
cards.setBackground(bckcolor);
cards.add(tab,p1);
cards.add(panelx,p2);
window.add(cards);
timer = new Timer(1000, new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
if (finish == true)
{
if (sendThread != null)
{
sendThread.interrupt();
sendThread = null;
}
if (prevThread != null)
{
prevThread.interrupt();
prevThread = null;
}
Component glass_pane;
glass_pane = frame.getGlassPane();
glass_pane.setVisible(false);
glass_pane.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
glass_pane.removeMouseListener(mouse_blocker_listener);
wait_lbl.setVisible(false);
progressBar.setIndeterminate(false);
progressBar.setVisible(false);
frame.setTitle(messages.getString("SendFeedbackForm"));
CardLayout cl = (CardLayout)(cards.getLayout());
cl.show(cards,p1);
if (selected == true)
frame.dispose();
timer.stop();
}
else
{
Component glass_pane;
glass_pane = frame.getGlassPane();
glass_pane.addMouseListener(mouse_blocker_listener);
glass_pane.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
glass_pane.setVisible(true);
frame.setTitle("Please wait...");
CardLayout cl = (CardLayout)(cards.getLayout());
cl.show(cards,p2);
wait_lbl.setVisible(true);
progressBar.setIndeterminate(true);
progressBar.setVisible(true);
}
}
});
}
/**
* This method will set the finish variable values.
* When the sending files is finished, the sending application will set the finish value to true.
* @param fin whether or not the send files is finished.
*/
public static void setFinish (boolean fin)
{
finish = fin;
}
/**
* This is the class to represent the whole panel that hold the screenshot and the comments
* about the screenshot.
*/
private class ThumbnailPic implements Serializable
{
/**
* This is the panel that hold a thumbnail for a screenshot and a comments text area.
*/
private JPanel picpane;
/**
* This hold the BufferedImages for the whole screen version of screenshot.
*/
private BufferedImage[] screenimages;
/**
* This hold the BufferedImages for the window version only.
*/
private BufferedImage[] windowimages;
/**
* This is the text area where user can enter their comments.
*/
private JTextArea problem_details;
/**
* This is a flag to tell us which image user wants to send.Its defaults value is false.
* If iswindow = true then it means user wants to send the window version only.
* If iswindow = false then it means user wants to send the whole screen version.
*/
private boolean iswindow;
/**
* This is the titles for the panel.
* Usually this is the title of the window where user wants to do the screenshot.
* If the title is more than 40 characters then we will trim it and add ... at the back of it.
*/
private String titles;
/**
* This is the width of the image user wants to send.
*/
private String iw;
/**
* This is the height of the image user wants to send.
*/
private String ih;
/**
* This is the x-coordinate where the window located inside the whole screen image.
*/
private int xcoord;
/**
* This is the y-coordinate where the window located inside the whole screen image.
*/
private int ycoord;
/**
* This is the width of the window inside the whole screen image.
*/
private int width;
/**
* This is the height of the window inside the whole screen image.
*/
private int height;
/**
* This is the constructor that will setup the panel that contains
* a thumbnail screenshot and a comments text area.
* @param image the whole screen screenshot image.
* @param text the title for this pane.
* @param x the x-coordinate of the window inside the whole screen image.
* @param y the y-coordinate of the window inside the whole screen image.
* @param w the width of the window inside the whole screen image.
* @param h the height of the window inside the whole screen image.
*/
//public ThumbnailPic (BufferedImage screen,byte[] image,String text)
public ThumbnailPic (BufferedImage image,String text,int x,int y,int w,int h)
{
xcoord = x;
ycoord = y;
width = w;
height = h;
iswindow = false;
titles = text;
screenimages = new BufferedImage[3];
windowimages = new BufferedImage[3];
//screenimages[0] = screen;
screenimages[0] = image;
screenimages[1] = null;
screenimages[2] = null;
windowimages[0] = null;
windowimages[1] = null;
windowimages[2] = null;
addPanel(image);
}
/**
* This method will setup the components inside the panel properly.
* @param image the whole screen screenshot image.
*/
//public void addPanel (byte[] image)
public void addPanel (BufferedImage image)
{
picpane = new JPanel();
picpane.setLayout(new BorderLayout());
final JButton picture;
picture = new JButton();
int w;
int h;
w = (int) (150/2);
h = (int) (150/2);
iw = "" + image.getWidth();
ih = "" + image.getHeight();
ImageIcon thumbnail;
thumbnail = new ImageIcon(image.getScaledInstance(w,h,Image.SCALE_SMOOTH));
picture.setIcon(thumbnail);
picture.setText("Draw . . .");
picture.setActionCommand("Scribble");
picture.addActionListener(new ActionListener()
{
public void actionPerformed (ActionEvent e)
{
frame.addMouseListener(mouse_blocker_listener);
frame.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
SelectPicture select;
select = new SelectPicture(screenimages,windowimages,iswindow,problem_details.getText(),messages);
frame.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
frame.removeMouseListener(mouse_blocker_listener);
select.setWindowBounds(xcoord,ycoord,width,height);
iswindow = select.getIsWindow();
screenimages[0] = select.getImage3();
screenimages[1] = select.getImage();
screenimages[2] = select.getImage2();
if (iswindow == true)
{
windowimages[0] = select.getWindowImage3();
windowimages[1] = select.getWindowImage();
windowimages[2] = select.getWindowImage2();
}
else
{
windowimages[0] = null;
windowimages[1] = null;
windowimages[2] = null;
}
problem_details.setText(select.getDetails());
int w,h;
w = (int) (150/2);
h = (int) (150/2);
ImageIcon thumbnail;
if (iswindow == false)
thumbnail = new ImageIcon(screenimages[1].getScaledInstance(w,h,Image.SCALE_SMOOTH));
else
thumbnail = new ImageIcon(windowimages[1].getScaledInstance(w,h,Image.SCALE_SMOOTH));
picture.setIcon(thumbnail);
if (select.getSendNow() == true)
{
ActionEvent evt;
evt = new ActionEvent(send_button,ActionEvent.ACTION_PERFORMED,messages.getString("Send"));
frame.actionPerformed(evt);
}
}
});
picture.setToolTipText("Click if you want to draw on it");
picture.setMargin(new Insets(5,5,5,5));
picture.setVerticalTextPosition(AbstractButton.BOTTOM);
picture.setHorizontalTextPosition(AbstractButton.CENTER);
picture.setBackground(new Color(176,208,176));
picpane.add(picture,BorderLayout.LINE_START);
JPanel txtPane;
txtPane = new JPanel(new BorderLayout());
txtPane.setBackground(new Color(176,208,176));
txtPane.setBorder(new EmptyBorder(5,5,5,5));
JLabel lbldesc = new JLabel("Comments :");
lbldesc.setBackground(new Color(176,208,176));
txtPane.add(lbldesc,BorderLayout.PAGE_START);
problem_details = new JTextArea();
problem_details.setWrapStyleWord(true);
problem_details.setEditable(true);
problem_details.setBackground(new Color(224,240,224));
JScrollPane scroll;
scroll = new JScrollPane(problem_details);
scroll.setBackground(new Color(176,208,176));
scroll.setPreferredSize(new Dimension(300,150));
txtPane.add(scroll,BorderLayout.LINE_START);
picpane.setSize(new Dimension(150,150));
picpane.add(txtPane,BorderLayout.CENTER);
}
/**
* This method will get the width of the image user wants to send.
* @return the width of the image.
*/
public String getWidth()
{
if (iswindow == false)
return "" + screenimages[0].getWidth();
else
{
return "" + windowimages[0].getWidth();
}
}
/**
* This method will get the height of the image user wants to send.
* @return the height of the image.
*/
public String getHeight()
{
if (iswindow == false)
return "" + screenimages[0].getHeight();
else
{
return "" + windowimages[0].getHeight();
}
}
/**
* This method will get the titles of this panel.
* @return the panel's title.
*/
public String getTitles()
{
return titles;
}
/**
* This method will get user comments inside the text area.
* @return the user's comments.
*/
public String getProblemDetails ()
{
String txt;
txt = problem_details.getText();
if (txt == null)
return " ";
else
return txt;
}
/**
* This method will setting up the text inside the text area.
* @param comments the text set to the text area.
*/
public void setComments (String comments)
{
problem_details.setText(comments);
}
/**
* This method will get the image that user wants to send.
* @return image going to be send.
*/
public BufferedImage[] getImages ()
{
if (iswindow == false)
return screenimages;
else
return windowimages;
}
/**
* This method will get the non-scribble lines image that user wants to send.
* @return the string representation of the non-scribble lines image.
*/
public String getScreenImage ()
{
if (iswindow == false)
return convert(screenimages[0]);
else
return convert(windowimages[1]);
}
/**
* This method will get the scribble lines image that user wants to send.
* @return the string representation of the scribble lines image.
*/
public String getScreenAndLineImage ()
{
if (iswindow == false)
{
if (screenimages[1]!= null)
return convert(screenimages[1]);
else
return convert(screenimages[0]);
}
else
{
if (windowimages[1]!= null)
return convert(windowimages[1]);
else
return convert(windowimages[0]);
}
}
/**
* This method will get only scribble lines image that user wants to send.
* @return the string representation of the only scribble lines image.
*/
public String getLineForScreenImage ()
{
if (iswindow == false)
{
if (screenimages[2] != null)
return convert(screenimages[2]);
else
return "";
}
else
{
if (windowimages[2] != null)
return convert(windowimages[2]);
else
return "";
}
}
/**
* This method will get the panel that hold a thumbnail and a text area.
* @return panel that represent the thumbnail and the text area.
*/
public JPanel getPanel()
{
return picpane;
}
}
/**
* This method will setting up the comments to be displayed inside the latest added panel.
* So if the window where user wants to take the screenshot at the moment is a modal window
* then it will setting the comments to ask user to close the window before they can enter
* their comments there.
* @param modal the modality of the window where user wants to take the screenshot.
*/
public void setComment (boolean modal)
{
if (paneArray.size() == 0)
System.out.println("There is no panel here!!");
else
{
JPanel pane;
pane = (JPanel) paneArray.get((row - 2));
ThumbnailPic obj;
obj = (ThumbnailPic) picAndPane.get(pane);
String text;
if (modal == true)
text = "Please close '" + obj.getTitles() + "' window \nbefore you can enter comments here.";
else
text = " ";
obj.setComments(text);
}
}
/**
* This method will add a panel that contains the thumbnail button and the text area.
* @param title the window's title.
* @param image the whole screen image.
* @param x the window's x-coordinate in the image.
* @param y the window's y-coordinate in the image.
* @param width the window's width in the image.
* @param height the window's height in the image.
*/
//public void addScreenPanel (String title,BufferedImage screen,byte[] image)
public void addScreenPanel (String title,BufferedImage image,int x,int y,int width,int height)
{
final JPanel pane;
pane = new JPanel();
pane.setLayout(new BorderLayout());
pane.setBackground(new Color(176,208,176));
Border loweredetched;
loweredetched = BorderFactory.createEtchedBorder(EtchedBorder.LOWERED);
String ttl;
if (title.length() > 41)
ttl = title.substring(0,40) + " . . . ";
else
ttl = title;
TitledBorder border;
border = BorderFactory.createTitledBorder(loweredetched, title);
border.setTitleJustification(TitledBorder.LEFT);
pane.setBorder(BorderFactory.createCompoundBorder(new EmptyBorder(5,5,5,5),border));
ThumbnailPic pic;
//pic = new ThumbnailPic(screen,image,title);
pic = new ThumbnailPic(image,title,x,y,width,height);
picAndPane.put(pane,pic);
pane.add(pic.getPanel(),BorderLayout.LINE_START);
remove.setVisible(true);
picture_scroll.add(pane);
paneArray.add(pane);
row++;
picture_scroll.setSize(picture_scroll.getPreferredSize());
picture_scroll.revalidate();
picture_scroll.repaint();
tempPane.setSize(tempPane.getPreferredSize());
tempPane.revalidate();
tempPane.repaint();
}
/**
* This method will generate the unique code that will be used as the
* reference number of the feedback that user are about to send.
* @return the unique code.
*/
public String getPrevData ()
{
try
{
UID id = new UID();
code = "" + InetAddress.getLocalHost().hashCode() + id.hashCode();
}
catch (UnknownHostException exp) {}
return code;
}
/**
* This method allows another class to get the unique code that can be used as
* the reference number of the feedback that user are about to send.
* This method should be called only if
* getPrevData() method already been called before.Otherwise it will return null.
* @return the unique code
*/
public static String getCode()
{
return code;
}
/**
* This method will encode BufferedImage into their String representation using
* Base64 encoder.
* (Precondition: (image != null))
* @param image is the image that we want to encode to String.
*/
public String convert (BufferedImage image)
{
String txt;
txt = null;
try
{
ByteArrayOutputStream stream = new ByteArrayOutputStream();
ImageIO.write(image,"jpeg",stream);
byte[] bytes = stream.toByteArray();
txt = Base64.encodeBytes(bytes);
}
catch(IOException ex) {}
return txt;
}
/**
* This method is to make sure that there is no thread running at the moment.
*/
private void ensureEventThread()
{
if(SwingUtilities.isEventDispatchThread())
{
return;
}
throw new RuntimeException(messages.getString("file"));
}
/**
* This method will create all 6 xml files, jarred them into one file, deletes all xml files and
* sending it.
* The xml files for:
*
1.The history & information of all the actions done and windows opened by the application
* after user choose to start the sequence of sending feedback.
*
2.The history of all the commands (actions) done by the user before choosing
* after start the sequence of sending feedback.
*
3.The informations we get from the feedback interface form period.
*
will be getting from vector and the temp_feedbackhist.log file.
* (Precondition: (sx != null) && (vector != null) && (err_array != null))
* @param sx the xml parser.
* @param vector the vector that hold the history and information.
* @param err_array the arrays of information we take from the feedback interface period.
* @param imgFile the arrays of information we take from the panels inside feedback interface form.
*/
private void sendState (SaveToXML sx,Vector vector,String[] err_array,String[] imgFile)
{
String dirname;
dirname = "xmlfeedback/";
File dir = new File("xmlfeedback");
if (dir.isDirectory() == false)
dir.mkdir();
sx.saveFeedback(err_array,imgFile);
sx.open(dirname + "feedbackcontent" + FeedbackInterface.getCode() + ".xml",
"HISTORY");
SaveToXML sx2;
sx2 = new SaveToXML(messages);
sx2.open(dirname + "feedbackcommand" + FeedbackInterface.getCode() + ".xml",
"COMMANDS");
for (int i = 0 ; i < vector.size() ; i++)
{
History log;
log = (History) vector.get(i);
log.sendXML(sx);
log.sendXMLComm(sx2);
}
Vector stack;
stack = getPrev_log();
if (stack != null)
{
for (int i = 0 ; i < stack.size() ; i++)
{
History log;
log = (History) stack.get(i);
log.sendXML(sx);
log.sendXMLComm(sx2);
}
stack.removeAllElements();
System.gc();
stack = null;
}
sx2.close("COMMANDS");
sx.close("HISTORY");
getHistPrev_log(sx,sx2);
ZipFile zip;
zip = new ZipFile();
zip.sendZipXMLFile();
File f;
f = new File (dirname + "feedback" + FeedbackInterface.getCode() + ".xml");
f.delete();
f = new File (dirname + "feedbackcontent" + FeedbackInterface.getCode() + ".xml");
f.delete();
f = new File (dirname + "feedbackcommand" + FeedbackInterface.getCode() + ".xml");
f.delete();
/*f = new File (dirname + "content" + FeedbackInterface.getCode() + ".xml");
f.delete();*/
f = new File (dirname + "command" + FeedbackInterface.getCode() + ".xml");
f.delete();
String[] args = new String[5];
args[0] = "vl6@cs.waikato.ac.nz";
args[1] = dirname + "Jar" + FeedbackInterface.getCode() + "File.jar";
args[4] = "lib/parser.jar";
args[2] = err_array[19];
args[3] = err_array[20];
SendHTTP sm = new SendHTTP();
//SendMail sm = new SendMail();
sm.sendMail(args,messages,FeedbackInterface.getCode());
}
/**
* This method will create the 2 xml files.
* The xml files are:
*
1.The history & information of all the actions done and windows opened by the application
* before user choose to start the sequence of sending feedback.
*
2.The history of all the commands (actions) done by the user before choosing
* to start the sequence of sending feedback.
*
The information will be getting from history.log file and the temp_history.log file.
* (Precondition: (sx != null) && (sx2 != null))
* @param sx the xml parser for the history xml file.
* @param sx2 the xml parser for the command xml file.
*/
private void getHistPrev_log(SaveToXML sx,SaveToXML sx2)
{
Vector stack = null;
try
{
File f = new File("history.log");
if (f.exists() == true)
{
FileInputStream fis = new FileInputStream(f);
ObjectInputStream ois = new ObjectInputStream(fis);
stack = (Vector) ois.readObject();
String dirname;
dirname = "xmlfeedback/";
/*sx.open(dirname + "content" + FeedbackInterface.getCode() + ".xml",
"HISTORY");*/
sx2.open(dirname + "command" + FeedbackInterface.getCode() + ".xml",
"COMMANDS");
if (stack != null)
{
for (int i = 0 ; i < stack.size() ; i++)
{
History log;
log = (History) stack.get(i);
//log.sendXML(sx);
log.sendXMLComm(sx2);
}
stack.removeAllElements();
System.gc();
stack = null;
}
stack = (Vector) ois.readObject();
if (stack != null)
{
for (int i = 0 ; i < stack.size() ; i++)
{
History log;
log = (History) stack.get(i);
//log.sendXML(sx);
log.sendXMLComm(sx2);
}
stack.removeAllElements();
System.gc();
stack = null;
}
sx2.close("COMMANDS");
//sx.close("HISTORY");
ois.close();
}
}
catch (IOException exp) {exp.printStackTrace();}
catch (ClassNotFoundException exp2)
{
System.out.println("class exp");}
}
/**
* This method will get the Vector stored in temp_feedbackhist.log file.
* @return the vector stored in temp_feedbackhist.log file.
*/
public Vector getPrev_log()
{
Vector stack = null;
try
{
File f = new File("temp_feedbackhist.log");
if (f.exists() == true)
{
FileInputStream fis = new FileInputStream(f);
ObjectInputStream ois = new ObjectInputStream(fis);
stack = (Vector) ois.readObject();
ois.close();
return stack;
}
else
stack = null;
}
catch (IOException exp) {exp.printStackTrace();}
catch (ClassNotFoundException exp2)
{
System.out.println("class exp");}
return stack;
}
/**
* This is the thread that will start when user click send button and it will
* make 6 xml files,jarred them together into 1 jar file, deletes the 6 xml files and send it.
* @param vector the vector stored the current actions history.
* @param err_array the array that stored all the information took during feedback interface period.
* @param imgFile the array of that stored all the information from all the panels inside feedback interface form.
*/
public void sendMethod (final Vector vector,final String err_array[], final String imgFile[])
{
ensureEventThread();
Runnable sendRun;
sendRun = new Runnable()
{
public void run ()
{
finish = false;
selected = true;
SaveToXML sx;
sx = new SaveToXML(messages);
sendState(sx,vector,err_array,imgFile);
finish = true;
}
};
sendThread = new Thread(sendRun);
sendThread.start();
}
/**
* This method will called the window that will display the preview of all
* the file going to be send.
* @param vector the vector stored the current actions history.
* @param err_array the array that stored all the information took during feedback interface period.
* @param imgFile the array of that stored all the information from all the panels inside feedback interface form.
*/
public void viewMethod (final Vector vector,final String err_array[], final String imgFile[])
{
ensureEventThread();
Runnable prevRun;
prevRun = new Runnable()
{
public void run ()
{
finish = false;
selected = false;
ReportDetails rd;
rd = new ReportDetails(vector,err_array,imgFile,messages,true);
finish = true;
}
};
prevThread = new Thread(prevRun);
prevThread.start();
}
/**
* This method will save a BufferedImage to a jpeg file with the specified filename.
* This method is a thread that will caused the thread save to be started and stop
* if the saving process is finished.
* (Precondition: (I != null))
* @param I is the BufferedImage that we want to save.
* @param picScreen name of the jpeg file where we want to store the BufferedImage
*/
public void saveGraph(final BufferedImage I,final String picScreen)
{
ensureEventThread();
Runnable saveRun;
saveRun = new Runnable ()
{
public void run()
{
try
{
File file;
file = new File(picScreen);
FileOutputStream out;
out = new FileOutputStream(file);
JPEGImageEncoder encoder;
encoder = JPEGCodec.createJPEGEncoder(out);
JPEGEncodeParam param;
param = encoder.getDefaultJPEGEncodeParam(I);
param.setQuality(1.0f, false);
encoder.setJPEGEncodeParam(param);
encoder.encode(I);
out.close();
save = null;
}
catch (Exception ex) {}
}
};
save = new Thread(saveRun);
save.start();
}
/**
* This method will get all the informations from the all the panels inside the feedback interface form.
* @return the arrays of information from all the panels.
*/
public String[] getimgFile()
{
String[] imgFile;
imgFile = null;
/*String answer;
answer = (String) problem_screenshot.getSelectedItem();
if(answer == messages.getString("Yes"))
{*/
if (paneArray.size() > 0)
{
imgFile = new String[(paneArray.size() * 10)];
int step;
for (step = 0 ; step < (paneArray.size()*10) ; step=step+10)
{
JPanel pane;
ThumbnailPic obj;
pane = (JPanel) paneArray.get((step/10));
obj = (ThumbnailPic) picAndPane.get(pane);
//obj.setSize();
String title;
title = obj.getTitles();
imgFile[step+0] = title;
imgFile[step+1] = obj.getScreenImage();
title = "Window" + pane.hashCode() + "File";
imgFile[step+2] = messages.getString("screen")+title+step+".jpg";
imgFile[step+3] = obj.getScreenAndLineImage();
imgFile[step+4] = messages.getString("ErrorLineAnd")+imgFile[step+2];
imgFile[step+5] = obj.getLineForScreenImage();
imgFile[step+6] = messages.getString("ErrorLineFor")+imgFile[step+2];
imgFile[step+7] = obj.getWidth();
imgFile[step+8] = obj.getHeight();
imgFile[step+9] = obj.getProblemDetails();
}
}
return imgFile;
}
/**
* This method will get all the informations taken during feedback interface period, such as os version.
* @return then arrays of informations.
*/
public String[] geterr_array()
{
String[] err_array;
err_array = null;
String os_name;
os_name = System.getProperty("os.name") + " " + System.getProperty("os.version")
+ " " + System.getProperty("os.arch");
Date problem_date;
String err_date,java_info,screen_res;
problem_date = new Date();
err_date = problem_date.toString();
java_info = System.getProperty("java.vendor")+ " " + System.getProperty("java.class.version");
Dimension dim;
dim = Toolkit.getDefaultToolkit().getScreenSize();
screen_res = "" + dim.width + "x" + dim.height;
try
{
err_array = new String[24];
err_array[0] = code;
err_array[1] = frameName;
err_array[2] = "";
err_array[3] = (String) problem_type.getSelectedItem();
err_array[4] = (String) problem_urgency.getSelectedItem();
err_array[5] = System.getProperty("user.name");
err_array[6] = System.getProperty("user.home");
err_array[7] = System.getProperty("user.dir");
err_array[8] = curr_date.toString();
err_array[9] = err_date;
err_array[10] = os_name;
err_array[11] = java_info;
err_array[12] = "" + Locale.getDefault();
err_array[13] = Utility.PROGRAM_NAME + " " + Utility.PROGRAM_VERSION;
err_array[14] = InetAddress.getLocalHost().getHostName();
err_array[15] = InetAddress.getLocalHost().getHostAddress();
err_array[16] = screen_res;
err_array[17] = "";
/*String test_txt;
test_txt = smtp_address.getText();
if ((test_txt == null)||(test_txt.length() < 5))*/
err_array[19] = "mail.waikato.ac.nz";
/*else
err_array[19] = test_txt;
test_txt = email_address.getText();
if ((test_txt == null)||(test_txt.length() < 5))*/
err_array[20] = "vl6@cs.waikato.ac.nz";
//else
//err_array[20] = test_txt;
Runtime run;
run = Runtime.getRuntime();
err_array[21] = formatFileSize(run.totalMemory());
err_array[22] = formatFileSize(run.maxMemory());
err_array[23] = formatFileSize(run.freeMemory());
}
catch(UnknownHostException exp) {}
return err_array;
}
/**
* This method will format the file size given into more elegant form,e.g. 2KB
* @param length the file size.
* @return the more elegant string representations of the file size.
*/
public String formatFileSize(long length)
{
String BYTE_SUFFIX;
BYTE_SUFFIX = " B";
long GIGABYTE;
GIGABYTE = 1024000000l;
String GIGABYTE_SUFFIX;
GIGABYTE_SUFFIX = " GB";
long KILOBYTE;
KILOBYTE = 1024l;
String KILOBYTE_SUFFIX;
KILOBYTE_SUFFIX = " KB";
long MEGABYTE;
MEGABYTE = 1024000l;
String MEGABYTE_SUFFIX;
MEGABYTE_SUFFIX = " MB";
StringBuffer result;
result = new StringBuffer("");
float number;
number = 0f;
String suffix;
suffix = null;
if(length >= GIGABYTE)
{
number = (float) length / (float) GIGABYTE;
suffix = GIGABYTE_SUFFIX;
}
else if(length >= MEGABYTE)
{
number = (float) length / (float) MEGABYTE;
suffix = MEGABYTE_SUFFIX;
}
else if(length >= KILOBYTE)
{
number = (float) length / (float) KILOBYTE;
suffix = KILOBYTE_SUFFIX;
}
else
{
return length + BYTE_SUFFIX;
}
String number_str;
number_str = Float.toString(number);
char number_char[] = number_str.toCharArray();
int pos,i;
pos = 0;
while(number_char != null && pos < number_char.length && number_char[pos] != '.')
{
result.append(number_char[pos]);
pos++;
}
if(pos < number_char.length)
{
result.append(number_char[pos]);
pos++;
for(i = 0; i < 2 && pos < number_char.length; i++, pos++)
result.append(number_char[pos]);
while(pos < number_char.length && number_char[pos] != 'E')
pos++;
while(pos < number_char.length)
{
result.append(number_char[pos]);
pos++;
}
}
result.append(suffix);
return result.toString();
}
/**
* This method will decide what action should be done if the user entered a button in
* the Feedback form.
*
If user click cancel button then all the information taken in this form will be deleted
* and user will be quitted from the Reporting Feedback sequence.
*
If user click the send button then all the information taken will be stored in array which
* then will be saved into xml files and sent when user confirm to send all the files.
*
If user click the details button then they can view all the xml files that are going to be send.
* @param e the button that user clicked
*/
public void actionPerformed (ActionEvent e)
{
getPrevData();
if(messages.getString("Send").equals(e.getActionCommand()))
{
String[] imgFile;
String[] err_array;
imgFile = getimgFile();
err_array = geterr_array();
timer.start();
sendMethod(dialog.getVector(),err_array,imgFile);
}
if(messages.getString("Preview").equals(e.getActionCommand()))
{
String[] imgFile;
String[] err_array;
imgFile = getimgFile();
err_array = geterr_array();
timer.start();
viewMethod(dialog.getVector(),err_array,imgFile);
}
if(messages.getString("NotSend").equals(e.getActionCommand()))
{
dispose();
}
}
}