I need to develop a Lotus Notes plug-in that adds some UI to Lotus Notes main UI and does the following when user creates & sends an email:
Intercept the outgoing email to see if there are any attachments in email.
If there is any attachment found in email, cancel sending the email.
Manipulate the attachments of email and then send the email again (by calling some Notes API)
Is this doable in Lotus Notes plug-ins?
Thanks & regards,
Nadeem Ullah
package com.ibm.NotesJava.agents;
import lotus.domino.*;
import java.io.File;
import java.io.FileInputStream;
import java.lang.*;
import java.util.*;
import java.awt.*;
import java.awt.List;
import java.awt.event.*;
import java.text.SimpleDateFormat;
public class MyJavaAgent extends AgentBase {
//Main metho which is called by lotus notes
public void NotesMain() {
try {
Session session = getSession();
AgentContext agentContext = session.getAgentContext();
// (Your code goes here)
Name n = session.createName(agentContext.getEffectiveUserName());
String st = n.getCommon();
Log log=session.createLog("JAVA_AGENT");
log.openFileLog("JAVA_AGENT.log");
MessageBox mb = new MessageBox();
try{
log.logAction("");
log.logAction("******************************Starting JAVA AGENT ************************");
log.logAction("Hello " + st + "!");
log.logAction("Executing JavaAgentTest with Agent: "+agentContext.getCurrentAgent().getName());
Database db = agentContext.getCurrentDatabase();
//System.out.println("Loading emaildetails.properties file from following location:C:\\Program Files\\Lotus\\Notes\\framework\\emaildetails.properties");
log.logAction("Loading emaildetails.properties file from following location:C:\\Program Files\\Lotus\\Notes\\framework\\emaildetails.properties");
Properties pro = new Properties();
File fil = new File("C:\\Program Files\\Lotus\\Notes\\framework\\emaildetails.properties");
//***********LOGIC*********
DocumentCollection coll=agentContext.getUnprocessedDocuments();
Document doc=coll.getFirstDocument();
//get input from user about the process area
}
}
/************************Library Code ***********************************/
/*
* The MessageBox class allows you to create simple message boxes
* using only the java.awt classes. All you have to do is create an instance
* of a MessageBox and use it to call the doOkCancelDialog or the
* doInputBox methods. You can use a single MessageBox instance to
* create multiple dialogs.
*
* This class has been implemented here as an inner class, but there's
* no reason why it couldn't be a class all by itself. The functionality to
* create buttons and messageboxes has been modularized, so it should
* be easy for you to add your own methods to this class, or make global
* modifications as you desire.
*
* The only really complicated/weird thing I had to do was to write and
* include the MultiLineLabel class, which is included towards the end
* of this class as an inner class. Read the comments associated with
* that class to see what's going on there.
*
* Make sure you import java.awt.* and java.awt.event.*
*
* Julian Robichaux -- http://www.nsftools.com
*/
class MessageBox {
public final int NO_ACTION = -1;
public final int CANCEL_ACTION = 0;
public final int OK_ACTION = 1;
int actionCode = NO_ACTION;
Frame parent;
Dialog msgbox;
MultiLineLabel msglabel; // our custom class, defined later
Panel buttons;
Button ok, cancel;
TextField textbox;
Choice dropdown;
List multilist;
public MessageBox () {
// this is the invisible Frame we'll be using to call all of our Dialogs
parent = new Frame();
}
public void dispose () {
// use this when you're ready to clean up
try { msgbox.dispose(); } catch (Exception e) {}
try { parent.dispose(); } catch (Exception e) {}
}
/*
* This method will create a simple dialog box with a title, a message,
* and Ok/Cancel buttons. It will halt execution of your program until
* one of the buttons is clicked, and it will return either OK_ACTION
* if the Ok button is clicked, or CANCEL_BUTTON if the Cancel
* button is clicked.
*/
public int doOkCancelDialog (String title, String message) {
actionCode = NO_ACTION;
try {
// create the messagebox
msgbox = new Dialog(parent, title, true);
msgbox.setLayout(new BorderLayout());
// create the label
initMsglabel(message);
msgbox.add("North", msglabel);
// create the OK and Cancel buttons
buttons = new Panel();
buttons.setLayout(new FlowLayout());
initOkButton();
buttons.add(ok);
initCancelButton();
buttons.add(cancel);
msgbox.add("South", buttons);
// display everything (the system will wait until a button is pressed
// before returning)
displayMsgbox();
msgbox.dispose(); // just in case the ActionListeners didn't fire...
} catch (Exception e) {
}
return actionCode;
}
/*
* This method will create a dialog box that allows the user to enter
* text into a field. It also has a title, a message, and Ok/Cancel buttons,
* and will halt execution of your program until one of the buttons is
* clicked or the user enters text into the field and presses "Enter".
* If the user clicks the Ok button or enters text and presses "Enter",
* then the text in the field will be returned; otherwise, this method will
* return null (which usually indicates that the user clicked Cancel).
*/
public String doInputBox (String title, String message, String defaultText) {
actionCode = NO_ACTION;
try {
// create the messagebox
msgbox = new Dialog(parent, title, true);
msgbox.setLayout(new BorderLayout());
// create the label
initMsglabel(message);
msgbox.add("North", msglabel);
// create the text field
initTextbox(defaultText);
msgbox.add("Center", textbox);
// create the OK and Cancel buttons
buttons = new Panel();
buttons.setLayout(new FlowLayout());
initOkButton();
buttons.add(ok);
initCancelButton();
buttons.add(cancel);
msgbox.add("South", buttons);
// display everything (the system will wait until a button is pressed
// before returning)
displayMsgbox();
msgbox.dispose(); // just in case the ActionListeners didn't fire...
} catch (Exception e) {
}
if (actionCode == OK_ACTION)
return textbox.getText();
else
return null;
}
/*
* This method will create a dialog box that allows the user to select from
* a dropdown list. It also has a title, a message, and Ok/Cancel buttons,
* and will halt execution of your program until one of the buttons is
* clicked. If the user clicks the Ok button then the text in the field will be
* returned; otherwise, this method will return null (which usually indicates
* that the user clicked Cancel).
*/
public String doDropdownBox (String title, String message, String[] selections) {
actionCode = NO_ACTION;
try {
// create the messagebox
msgbox = new Dialog(parent, title, true);
msgbox.setLayout(new BorderLayout());
// create the label
initMsglabel(message);
msgbox.add("North", msglabel);
// create the dropdown box
initDropdown(selections);
msgbox.add("Center", dropdown);
// create the OK and Cancel buttons
buttons = new Panel();
buttons.setLayout(new FlowLayout());
initOkButton();
buttons.add(ok);
initCancelButton();
buttons.add(cancel);
msgbox.add("South", buttons);
// display everything (the system will wait until a button is pressed
// before returning)
displayMsgbox();
msgbox.dispose(); // just in case the ActionListeners didn't fire...
} catch (Exception e) {
}
if (actionCode == OK_ACTION)
return dropdown.getSelectedItem();
else
return null;
}
/*
* This method will create a dialog box that allows the user to select from
* a list of options (use the allowMultiSelect parameter to indicate whether
* the user can select multiple items from the list [true] or just one [false]).
* It also has a title, a message, and Ok/Cancel buttons, and will halt
* execution of your program until one of the buttons is clicked. If the user
* clicks the Ok button then the text in the field will be returned; otherwise,
* this method will return null (which usually indicates that the user clicked
* Cancel or didn't select anything).
*/
public String[] doMultilistBox (String title, String message, String[] selections, boolean allowMultiSelect) {
actionCode = NO_ACTION;
try {
// create the messagebox
msgbox = new Dialog(parent, title, true);
msgbox.setLayout(new BorderLayout());
// create the label
initMsglabel(message);
msgbox.add("North", msglabel);
// create the multilist field
initMultilist(4, allowMultiSelect, selections);
msgbox.add("Center", multilist);
// create the OK and Cancel buttons
buttons = new Panel();
buttons.setLayout(new FlowLayout());
initOkButton();
buttons.add(ok);
initCancelButton();
buttons.add(cancel);
msgbox.add("South", buttons);
// display everything (the system will wait until a button is pressed
// before returning)
displayMsgbox();
msgbox.dispose(); // just in case the ActionListeners didn't fire...
} catch (Exception e) {
}
if ((actionCode == OK_ACTION) &&
(java.lang.reflect.Array.getLength(multilist.getSelectedItems()) > 0))
return multilist.getSelectedItems();
else
return null;
}
/*
* The private methods below are simply reusable modular functions for
* creating various elements that may appear in a MessageBox dialog.
* They make it easier to write new public methods that create different
* kinds of dialogs, and also allow you to make global changes to all your
* dialog components pretty easily.
*/
private void initMsglabel (String message) {
// the actual message in the MessageBox (using the custom
// MultiLineLabel class, included below)
msglabel = new MultiLineLabel(message);
}
private void initOkButton () {
// the OK button
ok = new Button("OK");
ok.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
actionCode = OK_ACTION;
msgbox.dispose();
}
} );
}
private void initCancelButton () {
// the Cancel button
cancel = new Button("Cancel");
cancel.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
actionCode = CANCEL_ACTION;
msgbox.dispose();
}
} );
}
private void initTextbox (String defaultText) {
// the field that allows a user to enter text in an InputBox
textbox = new TextField(defaultText, 40);
// the ActionListener here will get called if the user presses "Enter"
textbox.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
actionCode = OK_ACTION;
msgbox.dispose();
}
} );
}
private void initDropdown (String[] selections) {
// a dropdown box that allows a user to select from a list of
// multiple items
dropdown = new Choice();
for (int i = 0; i < java.lang.reflect.Array.getLength(selections); i++)
dropdown.add(selections[i]);
}
private void initMultilist (int numOfLines, boolean allowMultiSelect, String[] selections) {
// a multiple selection box that allows a user to select one or
// more items. numOfLines indicates how many lines should be
// visible at a time, allowMultiSelect is a boolean value indicating
// whether or not the user should be allowed to select more than
// one item from the list, and selections is an array of Strings that
// is used to populate the selection box
multilist = new List(numOfLines, allowMultiSelect);
for (int i = 0; i < java.lang.reflect.Array.getLength(selections); i++)
multilist.add(selections[i]);
}
private void displayMsgbox () {
// once all of the components have been added to a dialog,
// use this method to display it
Dimension d = msgbox.getToolkit().getScreenSize();
msgbox.setLocation(d.width/3, d.height/3); // center the dialog (sort of)
msgbox.pack(); // organize all its components
msgbox.setResizable(false); // make sure the user can't resize it
msgbox.toFront(); // give it focus
msgbox.setVisible(true); // and display it
}
/*
* Okay, this is a pain, but java.awt doesn't natively have a Label-type class
* that allows you to display text that's more than one line. So I had to write one
* myself. The class below is a modification of some code from the fantastic
* book, "Java in a Nutshell".
*
* The big change I made was to allow this multi-line label to have a fixed width,
* so the Label wouldn't fly off the screen if you had a big paragraph of text to
* display. The width is specified in "columns", which I defined as the width of
* the letter "X" in whatever font is being used. The text that you add to the label
* is automatically split into chunks that are no longer than the number of columns
* specified (you'll see the code to do this in the parseLabel method).
*
* This sample implementation is an inner class of the MessageBox class, although
* it could also be a separate class all by itself. I made it an inner class to make it
* easier to copy and paste everything from one agent to another.
*
* Julian Robichaux -- http://www.nsftools.com
*/
class MultiLineLabel extends Canvas {
// a custom class that will display a text label at a fixed width across
// multiple lines
// (modification of MultiLineLabel class from "Java in a Nutshell")
String label;
String[] lines;
int rows = 1;
int cols = 40;
int margin = 6;
int rowHeight;
int lineAscent;
int maxWidth;
public MultiLineLabel (String text) {
// create a label with the default width
label = text;
}
public MultiLineLabel (String text, int columns) {
// create a label with the specified number of "columns" (where a column
// is the width of "X" in the font that we're using)
if (columns > 0)
cols = columns;
label = text;
}
protected void measure () {
// get the global values we use in relation to our current font
FontMetrics fm = this.getFontMetrics(this.getFont());
if (fm == null)
return;
rowHeight = fm.getHeight();
lineAscent = fm.getAscent();
maxWidth = fm.stringWidth("X") * cols;
}
private int stringWidth (String text) {
// calculate the width of a String using our current font
FontMetrics fm = this.getFontMetrics(this.getFont());
if (fm == null)
return 0;
return fm.stringWidth(text);
}
public Font getFont () {
// return the font that we're currently using
return super.getFont();
}
public void setFont (Font f) {
// change the font that we're currently using, and redraw the
// label with the new font
super.setFont(f);
repaint();
}
public void addNotify () {
// automatically invoked after our label/Canvas is created but
// before it's displayed (FontMetrics aren't available until
// super.addNotify() has been called)
super.addNotify();
measure();
}
public Dimension getPreferredSize () {
// called by the LayoutManager to find out how big we want to be
if (lines == null)
setText(label);
return new Dimension(maxWidth + (2 * margin), (rows * rowHeight) + (2 * margin));
}
public Dimension getMinimumSize () {
// called by the LayoutManager to find out what our bare minimum
// size requirements are
if (lines == null)
setText(label);
return new Dimension(maxWidth, (rows * rowHeight));
}
public void setText (String text) {
// change the text we're using for this label
label = text;
parseLabel();
}
private void parseLabel () {
// parses the text we want to display in the label, so that the lines[]
// variable contains lines of text that are no wider than maxWidth
String token, word;
StringBuffer msg = new StringBuffer("");
StringBuffer line = new StringBuffer("");
// do an initial measurement, to make sure we have maxWidth
measure();
rows = 0;
// we'll be tokenizing the label String twice, first at every end-of-line
// character ('\n') and then at every space (if the lines are too long),
// in order to generate an StringBuffer of proper length lines, all
// separated by \n
java.util.StringTokenizer st1 = new java.util.StringTokenizer(label, "\n", false);
while (st1.hasMoreTokens()) {
token = st1.nextToken();
if (stringWidth(token) <= maxWidth) {
// if the whole line is shorter than the maxWidth allowed, we can
// just add this line to the buffer and get the next one
rows++;
msg.append(token + "\n");
} else {
// if the line was too long, we'll have to break it up manually by
// tokenizing the line at every space and adding words together
// one by one until we have a line that's greater than maxWidth;
// then we can add that shorter line to the buffer and keep doing
// that until we're out of words
java.util.StringTokenizer st2 = new java.util.StringTokenizer(token, " ", false);
while (st2.hasMoreTokens()) {
word = st2.nextToken();
if ((stringWidth(line.toString()) + stringWidth(word)) > maxWidth) {
rows++;
msg.append(line.toString() + "\n");
line.setLength(0);
line.append(word + " ");
} else {
line.append(word + " ");
}
}
// after we've run out of words, add any remaining text to the buffer, too
if (line.length() > 0) {
rows++;
msg.append(line.toString() + "\n");
}
}
}
// once we're done, split the buffer into the lines[] array
java.util.StringTokenizer st = new java.util.StringTokenizer(msg.toString(), "\n");
lines = new String[rows];
for (int i = 0; i < rows; i++)
lines[i] = st.nextToken();
}
public void paint (Graphics g) {
// draw the actual label to the screen, with space around the edges
// based on the margins we've specified (for some reason, we have to
// call setLabel instead of just parseText here in order to get the size
// right, which is a little redundant, but whatever works...)
int y;
setText(label);
Dimension d = this.getSize();
y = lineAscent + (d.height - (rows * rowHeight)) / 2;
for (int i = 0; i < rows; i++, y += rowHeight)
g.drawString(lines[i], margin, y);
}
}
}// end of the MultiLineLabel class
I think you can do it using java lotus notes API.
Download the examples from here..
http://www.nsftools.com/tips/NotesTips.htm#javascraps
Download javascraps.zip file..it has example for maximum API..
To complete ur work u need to create a java agent in lotus notes and then you need to write java code as per your requirement using the java API to get the task done..
Related
I am new to Java
I created a conversion software for metric units and now I want to create new window for logging the output of converted units from one Window text areas into one text area in another window Picture of the application
Both Windows are one application
What code would I need to put in there to display this in another window text area
JButton btnConvert = new JButton("Convert");
btnConvert.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
double numCM,sumCM;
double numKM,sumKM;
double numMIL,sumMIL;
try {
//startCM//
numCM = Double.parseDouble(textFieldenter.getText());
sumCM = numCM*100;
textFieldcm.setText(Double.toString(sumCM));
//endCM//
//startKILOMETERS//
numKM = Double.parseDouble(textFieldenter.getText());
sumKM = numKM*0.001;
textFieldkm.setText(Double.toString(sumKM));
//endKILOMETERS//
//startMILES//
numMIL = Double.parseDouble(textFieldenter.getText());
sumMIL = numMIL*0.000621;
textFieldmil.setText(Double.toString(sumMIL));
//endMILES//
}
catch (Exception e1) {
JOptionPane.showInternalMessageDialog(btnConvert, "Value etered is incorrect");
}
}
});
You can use the method JTextField.getText() over your JTextFields and store its value into a String variable, then pass it to the JTextArea using the method append(String str) and put a line break at the end with /n
Read the API for these classes to learn more about its methods and how to use them Java API
It would be something like this
String record = "";
record = textFieldcm.getText()+" "+textFieldkm.getText()+" "+textFieldmil.getText();
JTextArea.append(record+"\n");
I have a code that saves a textfile, but the path of that textfile and the name are hardcoded.
How can i make that the user select his/her own path and the name of the file?
int[][] sudokuNumbers = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
try (
PrintStream output = new PrintStream(new File("C:\\Users\\David\\Desktop\\Proyecto4.3\\output.txt"));) {
for (int i = 0; i < sudokuNumbers.length; i++) {
String s= "";
for (int j = 0; j < sudokuNumbers[i].length; j++) {
s+= "|" + sudokuNumbers[i][j] + "|";
}
output.println(s);
}
output.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
The task is relatively easy to carry out however you will need a couple methods to assist you. If a User is to supply a custom path (specific for them-self) then you will need to ensure that the path will be created so that it exists before the file is created and written to. Another thing to consider is that there may also be a requirement of Permissions to be granted to the application so as to carry out the task within the local file system (if this is where the file is to be created) or wherever else.
Obviously you will need to provide a means for the User to supply a path and file name. The best way to do this in my opinion is with a Folder Chooser dialog. The reason I say this is because it's not nearly as prone to mistakes (spelling, system format, etc.) as it would be if the User completely typed in the desired path and file name. Basically, the less control you give the User to the local file system the better off your application will be. Creating a folder (directory) based on the User Name within a preset file system location and utilizing a User name and date/time for file names is relatively common and can be all auto-generated, this eliminates the possibility of any file system errors. If possible, your application should maintain full control of such a task but understandably this can not always be the case for specific applications where User interaction with the file system is a requirement due to the fact that it's sole functionality is based on such interaction. For example, a File System Explorer where creating, cutting, copying, pasting, deleting, and editing of files and folders is its allowable purpose.
To demonstrate what I'm talking about I have quickly created a small Java runnable you can play with to see how the provided custom methods work. The code is well commented so that you can understand what is going on. Unfortunately all the commenting makes the code file look large when in fact it isn't if you were to remove them.
For simplicity, when we run the provided little console application it first asks for a User's Name. This Users Name will serve two specific purposes.
1) It will be used to create a specific Folder for that particular User only.
2) When a file is saved the file name will start with the User's name and then be followed with date/time data and finally contain the
".txt" file name extension.
Again, just for example purposes, as soon as a User enters his/her name into the console a Folders Selection dialog window will be displayed so that a main folder location can be selected where Users sub-folders will be created in and ultimately the Users data files will be saved under his/her folder name.
The file data is automatically saved once the home folder is selected and the console indicates of success once completed. Our little console application then simply ends.
Here is the Java runnable:
package choosefolder;
import java.awt.Component;
import java.awt.Container;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintStream;
import java.time.LocalDateTime;
import java.util.Scanner;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
public class ChooseFolder {
// Declare & initialize required String variables.
// These are global to the entire Class.
private static String userName = "";
private static String savePath = "";
public static void main(String[] args) {
//Setup a Scanner to get User input from console.
Scanner input = new Scanner(System.in);
// Ask for and get the Users Name and convert it to lowercase
// so as to maintain nameing consistency. No sense having "John Doe"
// one day and "john Doe" the next. This would consider 2 different
// Users since the second name has a lowercase "j" in "John" and
// therefore create two separate folder. Converting all supplied names
// to lowercase eliminates this problem.
while (userName.equals("")) {
System.out.println("\nPlease Enter User Name:");
userName = input.nextLine().toLowerCase();
}
// Open a Folders selection dialog window and allow for
// selection of a home folder where all Users saved files
// will be saved. Once we get the selected folder we then
// add the Users name to the path and create it.
savePath = openFoldersDialog("", "Select Home Folder To Save User Folders & File In...") + "\\" + userName;
// Create a special path just for the Users Name (ie: C:\My Files\John Doe\).
if (!createPath(savePath)) {
// If false was returnd from the createPath() method
// then there was an error while creating the path.
// Read console output to get the Error.
System.out.println("\n\u001B[31mError creating Users Save Path! Exiting...\u001B[39;49m");
System.exit(0);
}
// Get the local date & time so we can add it to
// our file namewhen its created.
LocalDateTime dateTime = LocalDateTime.now();
// Create the new file path & file name. This will be the path
// and file name where our Users data will be saved. We take the
// Users path e created and then add the file name to the end. The
// file name consists of the supplied User's name, the date/time and
// the .txt file name extension. Unwanted characters are also removed
// from the Date/Time. So, our path may look something like:
// C:\My Files\John Doe-20160419T155758107.txt
String filePathAndName = savePath + "\\" + userName + "-" +
dateTime.toString().replace("-", "").
replace(":", "").replace(".", "") + ".txt";
// Here is your code. This is the data saved to file....
int[][] sudokuNumbers = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
try (
// Notice the filePathAndName variable which we declared and initialized above.
PrintStream output = new PrintStream(new File(filePathAndName));) {
for (int i = 0; i < sudokuNumbers.length; i++) {
String s= "";
for (int j = 0; j < sudokuNumbers[i].length; j++) {
s+= "|" + sudokuNumbers[i][j] + "|";
}
output.println(s);
}
output.close();
}
catch (FileNotFoundException e) {
System.out.println(e.getMessage());
}
finally {
// Notify in console of success.
System.out.println("\n\u001B[34mFile Saved SUCCESSFULLY in:\n\u001B[39;49m" + filePathAndName);
}
}
/**
* Opens a Folder (directory) selection dialog window. All parameters for this method are optional but if you supply
* something to the last parameter then you must supply something to the parameters preceding it even if it's a null
* string ("") (see usage examples below)
*
* Example Usage:
*
* openFolderDialog(); //Allowed
* openFolderDialog("C:\\"); //Allowed
* openFolderDialog("", "Select The Folder You Need"); //Allowed
* openFolderDialog("", "", "Select Folder"); //Allowed
* openFolderDialog("", "", ""); //Allowed
* openFolderDialog( , "Your Folders, "Select Folder"); //Not Allowed
* openFolderDialog( , , "Select Folder"); //Not Allowed
* openFolderDialog("C:\\", "Your Folders, ); //Not Allowed
*
* I think you get the idea here.
*
* #param dialogOptions OPTIONAL - 3 String Type Parameters
* startPath - String - Default is the running applications' home folder. The path
* supplied here tells the dialog where to start displaying folders from.
* If you just want to use default but would like to supply something to
* the other optional parameters then just supply a null string ("") here.
*
* dialogTitle - String - Dialog Window Title - Default is "Select Folder...". You can
* supply whatever title you like for the dialog window.
*
* openButtonCaption - String - The Select Button Caption - Default is "Select". You can supply
* whatever you like for a button caption and it can be more than one word
* but do keep in mind that the button increases in length to accommodate the
* the supplied string.
*
* #return The selected Folder (directory) full path as string. Returns Null is nothing was selected.
*/
public static String openFoldersDialog(String... dialogOptions) {
String startPath = "";
try {
startPath = new File(".").getCanonicalPath();
} catch (IOException ex) {}
String dialogTitle = "Select Folder...";
String openButtonCaption = "Select";
if (dialogOptions.length != 0) {
if (dialogOptions.length >= 1) {
if (!dialogOptions[0].isEmpty()) { startPath = dialogOptions[0]; }
}
if (dialogOptions.length >= 2) {
if (!dialogOptions[1].isEmpty()) { dialogTitle = dialogOptions[1]; }
}
if (dialogOptions.length == 3) {
if (!dialogOptions[2].isEmpty()) { openButtonCaption = dialogOptions[2]; }
}
}
File sp = new File(startPath);
JFileChooser fc = new JFileChooser(sp);
//Remove the "Files Type:" combo box and label from dialog.
removeJFCFilesTypeComponent(fc);
fc.setDialogTitle(dialogTitle);
fc.setAcceptAllFileFilterUsed(false);
fc.setRequestFocusEnabled(true);
fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
int userSelection = fc.showDialog(null, openButtonCaption); //.showSaveDialog(null);
if (userSelection == JFileChooser.APPROVE_OPTION) {
String f = fc.getSelectedFile().getPath();
return f;
}
return null;
}
/**
* Removes the Filter ComboBox from the supplied JFileChooser object.
* This helps make the JFileChooser dialog window look more like a
* folder selection dialog.
* #param filechooser The object name of the JFileChooser object.
*/
public static void removeJFCFilesTypeComponent(Container filechooser) {
Component[] components = filechooser.getComponents();
for (Component component : components) {
if (component instanceof JComboBox) {
Object sel = ((JComboBox) component).getSelectedItem();
if (sel.toString().contains("AcceptAllFileFilter")) {
component.setVisible(false);
// OR
//con.remove(component);
}
}
if (component instanceof JLabel) {
String text = ((JLabel) component).getText();
if (text.equals("Files of Type:")) {
component.setVisible(false);
// OR
//con.remove(component);
}
}
if (component instanceof Container) {
removeJFCFilesTypeComponent((Container) component);
}
}
}
/**
* Creates the supplied path into the local file system if it doesn't already exist. You must
* make sure permissions are properly in place before using this method otherwise the path may
* not be created within the file system.
* #param pathString The path to create (must not include a file name). Will not create path if it already exists.
* #return Boolean True if successful and Boolean False if not.
*/
public static boolean createPath(String pathString) {
if (pathString.isEmpty()) { return false; }
if (doesFolderExist(pathString)) { return true; }
try {
File foldersToMake = new File(pathString);
foldersToMake.mkdirs();
return true;
}
catch (Exception ex) {
System.out.println("*** CreatePath() - Exception Encountered:\n*** " + ex.getMessage());
return false;
}
}
/**
* This method simply return boolean true or false if the supplied path exists.
* #param folderPathString (String) The full path to check. No File Name is allowed
* to be in this path.
* #return
*/
public static boolean doesFolderExist(String folderPathString) {
boolean tf = false;
try {
if (folderPathString.isEmpty() || "".equals(folderPathString)) { return tf; }
File f = new File(folderPathString);
if(f.exists() && f.isDirectory()) { tf = true; }
}
catch (Exception e) {
System.out.println("*** DoesFolderExist() - Exception Encountered:\n*** " + e.getMessage());
tf = false;
}
return tf;
}
}
I hope this helps you (and others).
I'm having difficulty getting the file back from a JFileChooser when setControlButtonsAreShown() is set to false.
If the user makes a selection of an exisiting file I can get this file with getSelectedFile(), but when they type in a new file name getSelectedFile() returns null.
When I use a JFileChooser with setControlButtonsAreShown(true) and I click on the Save button any filename the user has typed can be obtained with getSelectedFile() as expected, but when setControlButtonsAreShown(false) is used I just can't seem to get this file returned.
This happens even if I call approveSelection(), which supposedly does the same as clicking on the Save button if it had been show.
What am I doing wrong? Or any another way to assign JfileChooser open button action event to customized personal Jbutton?
This the workaround I came up with.
This will iterate through all the components inside FileChooser Container and get the text from the JTextField and set as selection in the FileChooser
Call this after some button click or any event.
private void failProofSetPath(JFileChooser chooser) {
File selectedFileFromTextBox = null;
String text = getTextOfFileViewer(chooser);
if (text != null && new File(text).exists()) {
selectedFileFromTextBox = new File(text);
}
if (selectedFileFromTextBox != null
&& (chooser.getSelectedFile() == null
|| !selectedFileFromTextBox.equals(chooser.getSelectedFile()))) {
chooser.setSelectedFile(selectedFileFromTextBox);
}
}
private String getTextOfFileViewer(Container c) {
int len = c.getComponentCount();
for (int i = 0; i < len; i++) {
Component comp = c.getComponent(i);
if (comp instanceof JTextField) {
JTextField b = (JTextField) comp;
return b.getText();
} else if (comp instanceof Container) {
String val = getTextOfFileViewer((Container) comp);
if (val != null) {
return val;
}
}
}
return null;
}
I am attempting to create a simple gui weather app, that consumes the BBC rss weather feed, and displays certain information on the weather stored in the xml file passed to the app via a url.
I have succeeded in consuming and parsing the rss feed, and then displaying the weather information within the GUI, however am now trying to implement weather icons that summarise the weather description.
In my weatherParser class I have written an iconChecker method that uses a switch case statement, to change the icon depending on the weatherCode variable.
The weatherCode is determined through a series of if-else statements from within my weatherGUI class, where I then call the iconChecker method passing the weather code and label as parameters.
However when i run the gui, the weather data is outputted to the gui after supplying a url and clicking the forecast button, but I do not see any icons. I'm not sure if it is a simple fix or whether I am on completely the wrong lines, therefore any help would be much appreciated.
iconChecker method code:
/**
* Case switch checks for weather description and selects relevant
* icon to display
* #param weatherCode - each code refers to a different weather state
* #param label - the JLabel to update with relevant icon.
*/
public void iconChecker(int weatherCode, JLabel label) {
switch (weatherCode) {
case 1: ImageIcon veryHot = new ImageIcon("src/main/resources/veryHot.png");
label.setIcon(veryHot);
break;
case 2: ImageIcon cloudyDay = new ImageIcon("src/main/resources/rain.png");
label.setIcon(cloudyDay);
break;
case 3: ImageIcon night = new ImageIcon("src/main/resources/snow.png");
label.setIcon(night);
break;
case 4: ImageIcon snowy = new ImageIcon("src/main/resources/cloudyDay.png");
label.setIcon(snowy);
break;
case 5: ImageIcon storm = new ImageIcon("src/main/resources/night.png");
label.setIcon(storm);
break;
case 6: ImageIcon rain = new ImageIcon("src/main/resources/storm.png");
label.setIcon(rain);
break;
}
}
forecastButton actionPerformed method code:
private void forecastButtonActionPerformed(java.awt.event.ActionEvent evt) {
String url = urlField.getText();
int weathercode = 0;
CharSequence sun = "sunny";
CharSequence rain = "rain";
CharSequence snow = "snow";
CharSequence cloud = "cloud";
CharSequence night = "night";
CharSequence storm = "storm";
try {
WeatherParser parser = new WeatherParser();
URL u = new URL(url);
weather = parser.parse(u);
reportBox.setText(weather);
// Each weather description is associated with a weather code
if (weather.contains(sun)) {
weathercode = 1;
}
else if (weather.contains(rain)) {
weathercode = 2;
}
else if (weather.contains(snow)) {
weathercode = 3;
}
else if (weather.contains(cloud)) {
weathercode = 4;
}
else if (weather.contains(night)) {
weathercode = 5;
}
else if (weather.contains(storm)) {
weathercode = 6;
}
else {
weathercode = 0;
}
// Call iconChecker method to update label with relevant icon.
parser.iconChecker(weathercode, iconLabel);
}
catch (ParserConfigurationException | MalformedURLException |
SAXException | XPathException | NullPointerException ex) {}
catch (IOException ex) {}
}
What I want is that the user can only input decimal numbers on a Text, I don't want it to allow text input as:
HELLO
ABC.34
34.HEY
32.3333.123
I have been trying using VerifyListener, but it only gives me the portion of the text that got inserted, so I end up having the text that I want to insert and the text before the insertion, tried also combining the text, but I got problems when you delete a key (backspace) and I end up having a String like 234[BACKSPACE]455.
Is there a way to set a Mask on a Text or successfully combine VerifyEvent with the current text to obtain the "new text" before setting it to the Text?
You will have to add a Listener on the Text using SWT.Verify. Within this Listener you can verify that the input contains only a decimal number.
The following will only allow the insertion of decimals into the text field. It will check the value each time you change something in the text and reject it, if it's not a decimal.
This will solve your problem, since the VerifyListener is executed BEFORE the new text is inserted. The new text has to pass the listener to be accepted.
public static void main(String[] args) {
Display display = Display.getDefault();
final Shell shell = new Shell(display);
shell.setLayout(new FillLayout());
final Text textField = new Text(shell, SWT.BORDER);
textField.addVerifyListener(new VerifyListener() {
#Override
public void verifyText(VerifyEvent e) {
Text text = (Text)e.getSource();
// Get old text and create new text by using the VerifyEvent.text
final String oldS = text.getText();
String newS = oldS.substring(0, e.start) + e.text + oldS.substring(e.end);
try
{
Float.parseFloat(newS);
}
catch(NumberFormatException ex)
{
// Prevent the input from happening, as it's not a float
e.doit = false;
}
System.out.println(newS);
}
});
shell.pack();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
}
Have you tried the FormattedText Widgets from Nebula? - They are an easy way to implement these kind of input fields, see http://eclipse.org/nebula/widgets/formattedtext/formattedtext.php
In order to get the behavior that I wanted I had to use several listeners:
A VerifyListner restricts the characters that are accepted as partial input while typing
A FocusListener validates the total input when leaving focus. If the total input is not valid, an error decoration will be shown.
A ModifyListener checks if the error decoration can be hidden while typing. It does not show the error decoration since invalid partial input like "4e-" is allowed to finally enter "4e-3"
valueField.addVerifyListener((event) -> restrictInput(event));
valueField.addModifyListener((event) -> validateValueOnChange(valueField.getText()));
valueField.addFocusListener(new FocusListener() {
#Override
public void focusGained(org.eclipse.swt.events.FocusEvent e) {}
#Override
public void focusLost(org.eclipse.swt.events.FocusEvent event) {
validateValueOnFocusLoss(valueField.getText());
}
});
protected void restrictInput(VerifyEvent event) {
String allowedCharacters = "0123456789.,eE+-";
String text = event.text;
for (int index = 0; index < text.length(); index++) {
char character = text.charAt(index);
boolean isAllowed = allowedCharacters.indexOf(character) > -1;
if (!isAllowed) {
event.doit = false;
return;
}
}
}
protected void validateValueOnChange(String text) {
try {
Double.parseDouble(valueField.getText());
valueErrorDecorator.hide();
} catch (NumberFormatException exception) {
//expressions like "5e-" are allowed while typing
}
}
protected void validateValueOnFocusLoss(String value) {
try {
Double.parseDouble(valueField.getText());
valueErrorDecorator.hide();
} catch (NumberFormatException exception) {
valueErrorDecorator.show();
}
}
The ModifyListener could be further improved to check for partial input that is not able to finally give a valid total input, e.g. "4e-....3". In that special case the ModifyListener should activate the error decoration while typing.
In addition to #Tom Seidel's answer: You could use a org.eclipse.swt.widgets.Spinner. This allows only digits. You can specify min and max value and the return value is an int so no need to cast a String.
final Composite composite parent = new Composite(superParent, SWT.NONE);
parent.setLayout(new FillLayout());
final Spinner spinner = new Spinner(parent, SWT.BORDER);
spinner.setvalues(0, 10, Integer.MAX_VALUE, 0, 1, 10);
The value of the Spinner can than be retrieved by calling:
int selectedValue = spinner.getSelection();