diff --git a/src/net/java/sip/communicator/plugin/sipaccregwizz/FirstWizardPage.java b/src/net/java/sip/communicator/plugin/sipaccregwizz/FirstWizardPage.java new file mode 100644 index 000000000..4dd1d77f0 --- /dev/null +++ b/src/net/java/sip/communicator/plugin/sipaccregwizz/FirstWizardPage.java @@ -0,0 +1,305 @@ +/* + * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. + * See terms of license at gnu.org. + */ +package net.java.sip.communicator.plugin.sipaccregwizz; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import javax.swing.event.*; + +import net.java.sip.communicator.service.gui.*; +import net.java.sip.communicator.service.protocol.*; + +/** + * The FirstWizardPage is the page, where user could enter the uin + * and the password of the account. + * + * @author Yana Stamcheva + * @author Damian Minkov + */ +public class FirstWizardPage extends JPanel + implements WizardPage, DocumentListener { + + public static final String FIRST_PAGE_IDENTIFIER = "FirstPageIdentifier"; + + private JPanel uinPassPanel = new JPanel(new BorderLayout(10, 10)); + + private JPanel labelsPanel = new JPanel(new GridLayout(0, 1, 10, 10)); + + private JPanel valuesPanel = new JPanel(new GridLayout(0, 1, 10, 10)); + + private JLabel uinLabel = new JLabel(Resources.getString("uin")); + + private JLabel passLabel = new JLabel(Resources.getString("password")); + + private JTextField uinField = new JTextField(); + + private JPasswordField passField = new JPasswordField(); + + private JCheckBox rememberPassBox = new JCheckBox( + Resources.getString("rememberPassword")); + + private JPanel advancedOpPanel = new JPanel(new BorderLayout(10, 10)); + + private JPanel labelsAdvOpPanel = new JPanel(new GridLayout(0, 1, 10, 10)); + + private JPanel valuesAdvOpPanel = new JPanel(new GridLayout(0, 1, 10, 10)); + + private JCheckBox enableAdvOpButton = new JCheckBox( + Resources.getString("ovverideServerOps"), false); + + private JLabel serverLabel = new JLabel(Resources.getString("server")); + + private JLabel proxyLabel = new JLabel(Resources.getString("proxy")); + + private JLabel portLabel = new JLabel(Resources.getString("port")); + + private JTextField serverField = new JTextField(); + + private JTextField proxyField = new JTextField(); + + private JTextField portField = new JTextField("5060"); + + private JPanel mainPanel = new JPanel(); + + private SIPAccountRegistration registration; + + private WizardContainer wizardContainer; + + /** + * Creates an instance of FirstWizardPage. + * @param registration the SIPAccountRegistration, where + * all data through the wizard are stored + * @param wizardContainer the wizardContainer, where this page will + * be added + */ + public FirstWizardPage(SIPAccountRegistration registration, + WizardContainer wizardContainer) { + + super(new BorderLayout()); + + this.wizardContainer = wizardContainer; + + this.registration = registration; + + this.setPreferredSize(new Dimension(300, 150)); + + mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS)); + + this.init(); + + this.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); + } + + /** + * Initializes all panels, buttons, etc. + */ + private void init() { + this.uinField.getDocument().addDocumentListener(this); + this.rememberPassBox.setSelected(true); + + labelsPanel.add(uinLabel); + labelsPanel.add(passLabel); + + valuesPanel.add(uinField); + valuesPanel.add(passField); + + uinPassPanel.add(labelsPanel, BorderLayout.WEST); + uinPassPanel.add(valuesPanel, BorderLayout.CENTER); + uinPassPanel.add(rememberPassBox, BorderLayout.SOUTH); + + uinPassPanel.setBorder(BorderFactory + .createTitledBorder(Resources.getString("uinAndPassword"))); + + mainPanel.add(uinPassPanel); + + serverField.setEditable(false); + portField.setEditable(false); + proxyField.setEditable(false); + + enableAdvOpButton.addActionListener(new ActionListener(){ + public void actionPerformed(ActionEvent evt) { + // Perform action + JCheckBox cb = (JCheckBox)evt.getSource(); + + serverField.setEditable(cb.isSelected()); + portField.setEditable(cb.isSelected()); + proxyField.setEditable(cb.isSelected()); + }}); + + labelsAdvOpPanel.add(serverLabel); + labelsAdvOpPanel.add(proxyLabel); + labelsAdvOpPanel.add(portLabel); + + valuesAdvOpPanel.add(serverField); + valuesAdvOpPanel.add(proxyField); + valuesAdvOpPanel.add(portField); + + advancedOpPanel.add(enableAdvOpButton, BorderLayout.NORTH); + advancedOpPanel.add(labelsAdvOpPanel, BorderLayout.WEST); + advancedOpPanel.add(valuesAdvOpPanel, BorderLayout.CENTER); + + advancedOpPanel.setBorder(BorderFactory + .createTitledBorder(Resources.getString("advancedOptions"))); + + mainPanel.add(advancedOpPanel); + + this.add(mainPanel, BorderLayout.NORTH); + } + + /** + * Implements the WizardPage.getIdentifier to return + * this page identifier. + */ + public Object getIdentifier() { + return FIRST_PAGE_IDENTIFIER; + } + + /** + * Implements the WizardPage.getNextPageIdentifier to return + * the next page identifier - the summary page. + */ + public Object getNextPageIdentifier() { + return WizardPage.SUMMARY_PAGE_IDENTIFIER; + } + + /** + * Implements the WizardPage.getBackPageIdentifier to return + * the next back identifier - the default page. + */ + public Object getBackPageIdentifier() { + return WizardPage.DEFAULT_PAGE_IDENTIFIER; + } + + /** + * Implements the WizardPage.getWizardForm to return + * this panel. + */ + public Object getWizardForm() { + return this; + } + + /** + * Before this page is displayed enables or disables the "Next" wizard + * button according to whether the UIN field is empty. + */ + public void pageShowing() { + this.setNextButtonAccordingToUIN(); + } + + /** + * Saves the user input when the "Next" wizard buttons is clicked. + */ + public void pageNext() { + registration.setUin(uinField.getText()); + registration.setPassword(new String(passField.getPassword())); + registration.setRememberPassword(rememberPassBox.isSelected()); + + registration.setServerAddress(serverField.getText()); + registration.setProxy(proxyField.getText()); + registration.setPort(portField.getText()); + } + + /** + * Enables or disables the "Next" wizard button according to whether the + * UIN field is empty. + */ + private void setNextButtonAccordingToUIN() { + if (uinField.getText() == null || uinField.getText().equals("")) { + wizardContainer.setNextFinishButtonEnabled(false); + } + else { + wizardContainer.setNextFinishButtonEnabled(true); + } + } + + /** + * Handles the DocumentEvent triggered when user types in the + * UIN field. Enables or disables the "Next" wizard button according to + * whether the UIN field is empty. + */ + public void insertUpdate(DocumentEvent e) { + this.setNextButtonAccordingToUIN(); + this.setServerFieldAccordingToUIN(); + } + + /** + * Handles the DocumentEvent triggered when user deletes letters + * from the UIN field. Enables or disables the "Next" wizard button + * according to whether the UIN field is empty. + */ + public void removeUpdate(DocumentEvent e) { + this.setNextButtonAccordingToUIN(); + this.setServerFieldAccordingToUIN(); + } + + public void changedUpdate(DocumentEvent e) { + } + + public void pageHiding() { + } + + public void pageShown() { + } + + public void pageBack() { + } + + /** + * Fills the UIN and Password fields in this panel with the data comming + * from the given protocolProvider. + * @param protocolProvider The ProtocolProviderService to load the + * data from. + */ + public void loadAccount(ProtocolProviderService protocolProvider) { + AccountID accountID = protocolProvider.getAccountID(); + String password = (String)accountID.getAccountProperties() + .get(ProtocolProviderFactory.PASSWORD); + + this.uinField.setText(accountID.getUserID()); + + if(password != null) { + this.passField.setText(password); + this.rememberPassBox.setSelected(true); + } + } + + /** + * Parse the server part from the sip id and set it to server + * as default value. If Advanced option is enabled Do nothing. + */ + private void setServerFieldAccordingToUIN() + { + if(!enableAdvOpButton.isSelected()) + { + String uin = uinField.getText(); + int delimIndex = uin.indexOf("@"); + if (delimIndex != -1) + { + String newServerAddr = uin.substring(delimIndex + 1); + + serverField.setText(newServerAddr); + proxyField.setText(newServerAddr); + } + } + } + + /** + * Disables Next Button if Port field value is incorrect + */ + private void setNextButtonAccordingToPort() + { + try + { + wizardContainer.setNextFinishButtonEnabled(true); + } + catch (NumberFormatException ex) + { + wizardContainer.setNextFinishButtonEnabled(false); + } + } +} diff --git a/src/net/java/sip/communicator/plugin/sipaccregwizz/Resources.java b/src/net/java/sip/communicator/plugin/sipaccregwizz/Resources.java new file mode 100644 index 000000000..d1f3f014a --- /dev/null +++ b/src/net/java/sip/communicator/plugin/sipaccregwizz/Resources.java @@ -0,0 +1,81 @@ +/* + * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. + * See terms of license at gnu.org. + */ + +package net.java.sip.communicator.plugin.sipaccregwizz; + +import java.io.*; +import java.util.*; + +import net.java.sip.communicator.util.*; +/** + * The Messages class manages the access to the internationalization + * properties files. + * @author Yana Stamcheva + */ +public class Resources { + + private static Logger log = Logger.getLogger(Resources.class); + + private static final String BUNDLE_NAME + = "net.java.sip.communicator.plugin.sipaccregwizz.resources"; + + private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle + .getBundle(BUNDLE_NAME); + + public static ImageID SIP_LOGO = new ImageID("protocolIcon"); + + /** + * Returns an internationalized string corresponding to the given key. + * @param key The key of the string. + * @return An internationalized string corresponding to the given key. + */ + public static String getString(String key) { + try { + return RESOURCE_BUNDLE.getString(key); + + } catch (MissingResourceException e) { + + return '!' + key + '!'; + } + } + + /** + * Loads an image from a given image identifier. + * @param imageID The identifier of the image. + * @return The image for the given identifier. + */ + public static byte[] getImage(ImageID imageID) { + byte[] image = new byte[100000]; + + String path = Resources.getString(imageID.getId()); + try { + Resources.class.getClassLoader() + .getResourceAsStream(path).read(image); + + } catch (IOException e) { + log.error("Failed to load image:" + path, e); + } + + return image; + } + + /** + * Represents the Image Identifier. + */ + public static class ImageID { + private String id; + + private ImageID(String id) { + this.id = id; + } + + public String getId() { + return id; + } + } + +} diff --git a/src/net/java/sip/communicator/plugin/sipaccregwizz/SIPAccRegWizzActivator.java b/src/net/java/sip/communicator/plugin/sipaccregwizz/SIPAccRegWizzActivator.java new file mode 100644 index 000000000..fc1cfbc1c --- /dev/null +++ b/src/net/java/sip/communicator/plugin/sipaccregwizz/SIPAccRegWizzActivator.java @@ -0,0 +1,78 @@ +/* + * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. + * See terms of license at gnu.org. + */ +package net.java.sip.communicator.plugin.sipaccregwizz; + +import org.osgi.framework.*; +import net.java.sip.communicator.service.configuration.*; +import net.java.sip.communicator.service.gui.*; +import net.java.sip.communicator.service.protocol.*; +import net.java.sip.communicator.util.*; + +/** + * Registers the SIPAccountRegistrationWizard in the UI Service. + * + * @author Yana Stamcheva + */ +public class SIPAccRegWizzActivator implements BundleActivator { + + public static BundleContext bundleContext; + + private static Logger logger = Logger.getLogger( + SIPAccRegWizzActivator.class.getName()); + + private static ConfigurationService configService; + + /** + * Starts this bundle. + * @param bc BundleContext + * @throws Exception + */ + public void start(BundleContext bc) throws Exception { + + bundleContext = bc; + + ServiceReference uiServiceRef = bundleContext + .getServiceReference(UIService.class.getName()); + + UIService uiService + = (UIService) bundleContext.getService(uiServiceRef); + + AccountRegistrationWizardContainer wizardContainer + = uiService.getAccountRegWizardContainer(); + + SIPAccountRegistrationWizard sipWizard + = new SIPAccountRegistrationWizard(wizardContainer); + + wizardContainer.addAccountRegistrationWizard(sipWizard); + } + + public void stop(BundleContext bundleContext) throws Exception { + } + + /** + * Returns the ProtocolProviderFactory for the SIP protocol. + * @return the ProtocolProviderFactory for the SIP protocol + */ + public static ProtocolProviderFactory getSIPProtocolProviderFactory() { + + ServiceReference[] serRefs = null; + + String osgiFilter = "(" + + ProtocolProviderFactory.PROTOCOL + + "="+ProtocolNames.SIP+")"; + + try { + serRefs = bundleContext.getServiceReferences( + ProtocolProviderFactory.class.getName(), osgiFilter); + } + catch (InvalidSyntaxException ex){ + logger.error("SIPAccRegWizzActivator : " + ex); + } + + return (ProtocolProviderFactory) bundleContext.getService(serRefs[0]); + } +} diff --git a/src/net/java/sip/communicator/plugin/sipaccregwizz/SIPAccountRegistration.java b/src/net/java/sip/communicator/plugin/sipaccregwizz/SIPAccountRegistration.java new file mode 100755 index 000000000..6c10a73af --- /dev/null +++ b/src/net/java/sip/communicator/plugin/sipaccregwizz/SIPAccountRegistration.java @@ -0,0 +1,135 @@ +/* + * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. + * See terms of license at gnu.org. + */ +package net.java.sip.communicator.plugin.sipaccregwizz; + +/** + * The SIPAccountRegistration is used to store all user input data + * through the SIPAccountRegistrationWizard. + * + * @author Yana Stamcheva + */ +public class SIPAccountRegistration { + + private String uin; + + private String password; + + private boolean rememberPassword; + + private String serverAddress; + + private String port; + + private String proxy; + + private String preferredTransport; + + public String getPreferredTransport() + { + return preferredTransport; + } + + public void setPreferredTransport(String preferredTransport) + { + this.preferredTransport = preferredTransport; + } + + public String getProxy() + { + return proxy; + } + + public void setProxy(String proxy) + { + this.proxy = proxy; + } + + /** + * Returns the password of the sip registration account. + * @return the password of the sip registration account. + */ + public String getPassword() { + return password; + } + + /** + * Sets the password of the sip registration account. + * @param password the password of the sip registration account. + */ + public void setPassword(String password) { + this.password = password; + } + + /** + * Returns TRUE if password has to remembered, FALSE otherwise. + * @return TRUE if password has to remembered, FALSE otherwise + */ + public boolean isRememberPassword() { + return rememberPassword; + } + + /** + * Sets the rememberPassword value of this sip account registration. + * @param rememberPassword TRUE if password has to remembered, FALSE + * otherwise + */ + public void setRememberPassword(boolean rememberPassword) { + this.rememberPassword = rememberPassword; + } + + /** + * Returns the UIN of the sip registration account. + * @return the UIN of the sip registration account. + */ + public String getUin() { + return uin; + } + + /** + * The address of the server we will use for this account + * @return String + */ + public String getServerAddress() + { + return serverAddress; + } + + /** + * The port on the specified server + * @return int + */ + public String getPort() + { + return port; + } + + /** + * Sets the UIN of the sip registration account. + * @param uin the UIN of the sip registration account. + */ + public void setUin(String uin) { + this.uin = uin; + } + + /** + * Setting the server + * @param serverAddress String + */ + public void setServerAddress(String serverAddress) + { + this.serverAddress = serverAddress; + } + + /** + * Setting the port + * @param port int + */ + public void setPort(String port) + { + this.port = port; + } +} diff --git a/src/net/java/sip/communicator/plugin/sipaccregwizz/SIPAccountRegistrationWizard.java b/src/net/java/sip/communicator/plugin/sipaccregwizz/SIPAccountRegistrationWizard.java new file mode 100644 index 000000000..6ac184c8e --- /dev/null +++ b/src/net/java/sip/communicator/plugin/sipaccregwizz/SIPAccountRegistrationWizard.java @@ -0,0 +1,171 @@ +/* + * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. + * See terms of license at gnu.org. + */ +package net.java.sip.communicator.plugin.sipaccregwizz; + +import java.util.*; + +import net.java.sip.communicator.service.gui.*; +import net.java.sip.communicator.service.protocol.*; + +import org.osgi.framework.*; + +/** + * The SIPAccountRegistrationWizard is an implementation of the + * AccountRegistrationWizard for the SIP protocol. It should allow + * the user to create and configure a new SIP account. + * + * @author Yana Stamcheva + */ +public class SIPAccountRegistrationWizard implements AccountRegistrationWizard { + + private FirstWizardPage firstWizardPage; + + private SIPAccountRegistration registration + = new SIPAccountRegistration(); + + private WizardContainer wizardContainer; + + private ProtocolProviderService protocolProvider; + + private String propertiesPackage + = "net.java.sip.communicator.plugin.sipaccregwizz"; + + /** + * Creates an instance of SIPAccountRegistrationWizard. + * @param wizardContainer the wizard container, where this wizard + * is added + */ + public SIPAccountRegistrationWizard(WizardContainer wizardContainer) { + this.wizardContainer = wizardContainer; + } + + /** + * Implements the AccountRegistrationWizard.getIcon method. + * Returns the icon to be used for this wizard. + * @return byte[] + */ + public byte[] getIcon() { + return Resources.getImage(Resources.SIP_LOGO); + } + + /** + * Implements the AccountRegistrationWizard.getProtocolName + * method. Returns the protocol name for this wizard. + * @return String + */ + public String getProtocolName() { + return Resources.getString("protocolName"); + } + + /** + * Implements the AccountRegistrationWizard.getProtocolDescription + * method. Returns the description of the protocol for this wizard. + * @return String + */ + public String getProtocolDescription() { + return Resources.getString("protocolDescription"); + } + + /** + * Returns the set of pages contained in this wizard. + * @return Iterator + */ + public Iterator getPages() { + ArrayList pages = new ArrayList(); + firstWizardPage = new FirstWizardPage(registration, wizardContainer); + + pages.add(firstWizardPage); + + return pages.iterator(); + } + + /** + * Returns the set of data that user has entered through this wizard. + * @return Iterator + */ + public Iterator getSummary() { + Hashtable summaryTable = new Hashtable(); + + summaryTable.put("UIN", registration.getUin()); + summaryTable.put("Remember password", + new Boolean(registration.isRememberPassword())); + + return summaryTable.entrySet().iterator(); + } + + /** + * Installs the account created through this wizard. + * @return ProtocolProviderService + */ + public ProtocolProviderService finish() { + firstWizardPage = null; + ProtocolProviderFactory factory + = SIPAccRegWizzActivator.getSIPProtocolProviderFactory(); + + return this.installAccount(factory, + registration.getUin(), registration.getPassword()); + } + + /** + * Creates an account for the given user and password. + * @param providerFactory the ProtocolProviderFactory which will create + * the account + * @param user the user identifier + * @param passwd the password + * @return the ProtocolProviderService for the new account. + */ + public ProtocolProviderService installAccount( + ProtocolProviderFactory providerFactory, + String user, + String passwd) { + + Hashtable accountProperties = new Hashtable(); + + if(registration.isRememberPassword()) { + accountProperties.put(ProtocolProviderFactory.PASSWORD, passwd); + } + + accountProperties.put(ProtocolProviderFactory.SERVER_ADDRESS, + registration.getServerAddress()); + + accountProperties.put(ProtocolProviderFactory.PROXY_ADDRESS, + registration.getProxy()); + + accountProperties.put(ProtocolProviderFactory.SERVER_PORT, + registration.getPort()); + + if(protocolProvider != null) { + providerFactory.uninstallAccount(protocolProvider.getAccountID()); + this.protocolProvider = null; + } + + AccountID accountID = providerFactory.installAccount( + user, accountProperties); + + ServiceReference serRef = providerFactory + .getProviderForAccount(accountID); + + ProtocolProviderService protocolProvider + = (ProtocolProviderService) SIPAccRegWizzActivator.bundleContext + .getService(serRef); + + return protocolProvider; + } + + /** + * Fills the UIN and Password fields in this panel with the data comming + * from the given protocolProvider. + * @param protocolProvider The ProtocolProviderService to load the + * data from. + */ + public void loadAccount(ProtocolProviderService protocolProvider) { + + this.protocolProvider = protocolProvider; + + this.firstWizardPage.loadAccount(protocolProvider); + } +} diff --git a/src/net/java/sip/communicator/plugin/sipaccregwizz/SecondWizardPage.java b/src/net/java/sip/communicator/plugin/sipaccregwizz/SecondWizardPage.java new file mode 100644 index 000000000..398475291 --- /dev/null +++ b/src/net/java/sip/communicator/plugin/sipaccregwizz/SecondWizardPage.java @@ -0,0 +1,48 @@ +/* + * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. + * See terms of license at gnu.org. + */ +package net.java.sip.communicator.plugin.sipaccregwizz; + +import javax.swing.*; + +import net.java.sip.communicator.service.gui.*; + +public class SecondWizardPage extends JPanel + implements WizardPage { + + public static final String SECOND_PAGE_IDENTIFIER = "SecondPageIdentifier"; + + public Object getIdentifier() { + return SECOND_PAGE_IDENTIFIER; + } + + public Object getNextPageIdentifier() { + return FINISH_PAGE_IDENTIFIER; + } + + public Object getBackPageIdentifier() { + return FirstWizardPage.FIRST_PAGE_IDENTIFIER; + } + + public Object getWizardForm() { + return this; + } + + public void pageHiding() { + } + + public void pageShown() { + } + + public void pageShowing() { + } + + public void pageNext() { + } + + public void pageBack() { + } +} diff --git a/src/net/java/sip/communicator/plugin/sipaccregwizz/resources.properties b/src/net/java/sip/communicator/plugin/sipaccregwizz/resources.properties new file mode 100755 index 000000000..c192e59c1 --- /dev/null +++ b/src/net/java/sip/communicator/plugin/sipaccregwizz/resources.properties @@ -0,0 +1,12 @@ +protocolName=SIP +protocolDescription=The SIP service protocol +uin=SIP id: +password=Password: +rememberPassword=Remember password +uinAndPassword=ID and Password +advancedOptions=Advanced Options +ovverideServerOps=Override server default options +server=Connect Server +port=Port + +protocolIcon=net/java/sip/communicator/plugin/sipaccregwizz/resources/sip.png diff --git a/src/net/java/sip/communicator/plugin/sipaccregwizz/sipaccregwizz.manifest.mf b/src/net/java/sip/communicator/plugin/sipaccregwizz/sipaccregwizz.manifest.mf new file mode 100755 index 000000000..edbb2face --- /dev/null +++ b/src/net/java/sip/communicator/plugin/sipaccregwizz/sipaccregwizz.manifest.mf @@ -0,0 +1,31 @@ +Bundle-Activator: net.java.sip.communicator.plugin.sipaccregwizz.SIPAccRegWizzActivator +Bundle-Name: SIP account registration wizard +Bundle-Description: SIP account registration wizard. +Bundle-Vendor: sip-communicator.org +Bundle-Version: 0.0.1 +Import-Package: org.osgi.framework, + net.java.sip.communicator.util, + net.java.sip.communicator.service.configuration, + net.java.sip.communicator.service.configuration.event, + net.java.sip.communicator.service.protocol, + net.java.sip.communicator.service.protocol.icqconstants, + net.java.sip.communicator.service.protocol.event, + net.java.sip.communicator.service.contactlist, + net.java.sip.communicator.service.contactlist.event, + net.java.sip.communicator.service.gui, + net.java.sip.communicator.service.gui.event, + javax.swing, + javax.swing.event, + javax.swing.table, + javax.swing.text, + javax.swing.text.html, + javax.accessibility, + javax.swing.plaf, + javax.swing.plaf.metal, + javax.swing.plaf.basic, + javax.imageio, + javax.swing.filechooser, + javax.swing.tree, + javax.swing.undo, + javax.swing.event, + javax.swing.border