/* * 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.dictaccregwizz; import java.awt.*; import java.awt.event.*; import java.util.*; import java.util.List; import javax.swing.*; import javax.swing.event.*; import net.java.dict4j.*; import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.util.swing.*; /** * The FirstWizardPage is the page, where user could enter the host, * port and the strategy of the account. * * @author ROTH Damien * @author LITZELMANN Cedric */ public class FirstWizardPage extends TransparentPanel implements WizardPage, DocumentListener, ActionListener { public static final String FIRST_PAGE_IDENTIFIER = "FirstPageIdentifier"; private JPanel hostPortPanel = new TransparentPanel(new BorderLayout(10, 10)); private JPanel labelsPanel = new TransparentPanel(); private JPanel valuesPanel = new TransparentPanel(); private JLabel hostLabel = new JLabel(Resources.getString("plugin.dictaccregwizz.HOST")); private JPanel emptyPanel = new TransparentPanel(); private JLabel hostExampleLabel = new JLabel("Ex: dict.org"); private JLabel portLabel = new JLabel(Resources.getString("plugin.dictaccregwizz.PORT")); private JTextField hostField = new JTextField(); private JTextField portField = new JTextField("2628"); private JPanel strategyPanel = new TransparentPanel(new BorderLayout(10, 10)); private JPanel strategyTitleBloc = new TransparentPanel(new BorderLayout()); private JLabel strategyTitle = new JLabel(Resources.getString( "plugin.dictaccregwizz.STRATEGY_LIST")); private JButton strategyLoader = new JButton(Resources.getString( "plugin.dictaccregwizz.SEARCH_STRATEGIES")); private StrategiesList strategiesList; private JTextArea strategyDescription = new JTextArea(Resources.getString( "plugin.dictaccregwizz.STRATEGY_DESCRIPTION")); private ProgressPanel searchProgressPanel; private JPanel mainPanel = new TransparentPanel(new BorderLayout()); private Object nextPageIdentifier = WizardPage.SUMMARY_PAGE_IDENTIFIER; private DictAccountRegistrationWizard wizard; private String initstrategy = ""; private ThreadManager searchThread = null; private boolean firstAccount = false; private boolean isPageCommitted = false; /** * Initial AccountID (null if new account) * Used to check if there are modifications to the account */ private AccountID initAccountID = null; /** * Creates an instance of FirstWizardPage. * * @param wizard the parent wizard */ public FirstWizardPage(DictAccountRegistrationWizard wizard) { super(new BorderLayout()); this.wizard = wizard; this.setPreferredSize(new Dimension(300, 150)); mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS)); this.searchThread = new ThreadManager(this); this.searchProgressPanel = new ProgressPanel(this.searchThread); this.firstAccount = !this.hasAccount(); if (this.firstAccount) { this.initFirstAccount(); } else { this.init(); } this.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); } /** * Initializes all panels, buttons, etc. */ private void init() { // Host and port Field this.hostField = new JTextField(); this.portField = new JTextField("2628"); this.hostField.getDocument().addDocumentListener(this); this.portField.getDocument().addDocumentListener(this); this.hostExampleLabel.setForeground(Color.GRAY); this.hostExampleLabel.setFont(hostExampleLabel.getFont().deriveFont(8)); this.emptyPanel.setMaximumSize(new Dimension(40, 35)); this.hostExampleLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 8, 0)); labelsPanel.add(hostLabel); labelsPanel.add(emptyPanel); labelsPanel.add(portLabel); valuesPanel.add(hostField); valuesPanel.add(hostExampleLabel); valuesPanel.add(portField); hostPortPanel.add(labelsPanel, BorderLayout.WEST); hostPortPanel.add(valuesPanel, BorderLayout.CENTER); hostPortPanel.setBorder(BorderFactory.createTitledBorder( Resources.getString("plugin.dictaccregwizz.SERVER_INFO"))); this.labelsPanel.setLayout(new BoxLayout(labelsPanel, BoxLayout.Y_AXIS)); this.valuesPanel.setLayout(new BoxLayout(valuesPanel, BoxLayout.Y_AXIS)); mainPanel.add(hostPortPanel); this.portField.addKeyListener(new KeyListener() { public void keyTyped(KeyEvent evt) { // If evt isn't a digit, we don't add it if (!Character.isDigit(evt.getKeyChar())) { evt.consume(); } } // Not used public void keyPressed(KeyEvent evt) {;} public void keyReleased(KeyEvent evt) {;} }); // Strategies list this.strategiesList = new StrategiesList(); JScrollPane scrollPane = new JScrollPane(); scrollPane.getViewport().add(this.strategiesList); this.strategyPanel.add(scrollPane); // Strategy title + button this.strategyTitleBloc.add(this.strategyTitle, BorderLayout.WEST); this.strategyTitleBloc.add(this.strategyLoader, BorderLayout.EAST); // Button action listener this.strategyLoader.setActionCommand("populateList"); this.strategyLoader.addActionListener(this); // South Panel JPanel sSouthPanel = new TransparentPanel(new BorderLayout()); // Description this.strategyDescription.setLineWrap(true); this.strategyDescription.setLineWrap(true); this.strategyDescription.setRows(4); this.strategyDescription.setWrapStyleWord(true); this.strategyDescription.setAutoscrolls(false); sSouthPanel.add(this.strategyDescription); // Message sSouthPanel.add(this.searchProgressPanel, BorderLayout.SOUTH); this.strategyPanel.add(sSouthPanel, BorderLayout.SOUTH); this.strategyPanel.add(this.strategyTitleBloc, BorderLayout.NORTH); this.strategyPanel.setBorder(BorderFactory.createTitledBorder( Resources.getString("plugin.dictaccregwizz.STRATEGY_SELECTION"))); mainPanel.add(this.strategyPanel); this.add(mainPanel, BorderLayout.NORTH); } /** * Initialize the UI for the first account */ private void initFirstAccount() { // Data init this.hostField = new JTextField("dict.org"); this.portField = new JTextField("2628"); // Init strategies list this.strategiesList = new StrategiesList(); this.mainPanel = new TransparentPanel(new BorderLayout()); JPanel infoTitlePanel = new TransparentPanel(new FlowLayout(FlowLayout.CENTER)); JTextArea firstDescription = new JTextArea(Resources.getString( "plugin.dictaccregwizz.FIRST_ACCOUNT")); JLabel title = new JLabel(Resources.getString( "plugin.dictaccregwizz.ACCOUNT_INFO_TITLE")); // Title title.setFont(title.getFont().deriveFont(Font.BOLD, 14.0f)); infoTitlePanel.add(title); this.mainPanel.add(infoTitlePanel, BorderLayout.NORTH); this.mainPanel.add(this.searchProgressPanel, BorderLayout.SOUTH); // Description firstDescription.setLineWrap(true); firstDescription.setEditable(false); firstDescription.setOpaque(false); firstDescription.setRows(6); firstDescription.setWrapStyleWord(true); firstDescription.setAutoscrolls(false); this.mainPanel.add(firstDescription); } /** * Implements the WizardPage.getIdentifier to return this * page identifier. * * @return Returns the identifier of the current (the first) page of the * wizard. */ public Object getIdentifier() { return FIRST_PAGE_IDENTIFIER; } /** * Implements the WizardPage.getNextPageIdentifier to return * the next page identifier - the summary page. * * @return Returns the identifier of the next page of the wizard. */ public Object getNextPageIdentifier() { return nextPageIdentifier; } /** * Implements the WizardPage.getBackPageIdentifier to return * the next back identifier - the default page. * * @return Returns the identifier of the previous page of the wizard. */ public Object getBackPageIdentifier() { return WizardPage.DEFAULT_PAGE_IDENTIFIER; } /** * Implements the WizardPage.getWizardForm to return this * panel. * @return Returns this form of the wizard. */ 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.setNextButtonEnabled(); } /** * Saves the user input when the "Next" wizard buttons is clicked. */ public void commitPage() { String host = hostField.getText(); int port = Integer.parseInt(portField.getText()); boolean isModified = false; if (this.initAccountID instanceof AccountID) { // We check if there are modifications to the server String accHost = this.initAccountID.getAccountPropertyString( ProtocolProviderFactory.SERVER_ADDRESS); int accPort = Integer.parseInt(this.initAccountID .getAccountPropertyString(ProtocolProviderFactory.SERVER_PORT)); if (accHost != host || accPort != port) { isModified = true; } } // We check if a strategy has been selected if (this.strategiesList.getModel().getSize() == 0) { // No Strategy, we get them this.populateStrategies(); if (!this.searchThread.waitThread()) { // TODO error dialog : thread interrupted ? no thread ? this.strategiesList.clear(); } } if (this.strategiesList.getModel().getSize() == 0) { // No strategy, maybe not connected // Information message is already on the wizard nextPageIdentifier = FIRST_PAGE_IDENTIFIER; this.revalidate(); } else { nextPageIdentifier = SUMMARY_PAGE_IDENTIFIER; DictAccountRegistration registration = wizard.getRegistration(); registration.setHost(host); registration.setPort(port); registration.setStrategy( (Strategy) this.strategiesList.getSelectedValue()); } isPageCommitted = true; } /** * Enables or disables the "Next" wizard button according to whether the UIN * field is empty. */ private void setNextButtonEnabled() { boolean hostOK = DictConnection.isUrl(hostField.getText()); boolean portOK = (this.portField.getText().length() != 0) && Integer.parseInt(this.portField.getText()) > 10; if (this.firstAccount) { wizard.getWizardContainer().setNextFinishButtonEnabled(true); } else if (hostOK && portOK) { this.strategyLoader.setEnabled(true); wizard.getWizardContainer().setNextFinishButtonEnabled(true); } else { // Disable the finish button wizard.getWizardContainer().setNextFinishButtonEnabled(false); // Clear the list and disable the button this.strategiesList.clear(); this.strategyLoader.setEnabled(false); } } /** * 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. * * @param e the DocumentEvent triggered when user types in the UIN * field. */ public void insertUpdate(DocumentEvent e) { this.setNextButtonEnabled(); } /** * 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. * * @param e The DocumentEvent triggered when user deletes letters * from the UIN field. */ public void removeUpdate(DocumentEvent e) { this.setNextButtonEnabled(); } /** * Handles the DocumentEvent triggered when user changes an * attribute or set of attributes from the UIN field. * Currently this notification has no effect and is just here to implement * the DocumentListener interface. * * @param e The DocumentEvent triggered when an attribute or set of * attributes changed from the UIN field. */ public void changedUpdate(DocumentEvent e) { } /** * Invoked when this WizardPage will be hidden eighter because the user has * clicked "Back" or "Next". * This function has no effect. */ public void pageHiding() { } /** * Invoked when this WizardPage will be shown eighter because the user has * clicked "Back" on the next wizard page or "Next" on the previous one. * This function has no effect. */ public void pageShown() { } /** * Invoked when user clicks on the "Back" wizard button. * This function has no effect. */ public void pageBack() { } /** * Fills the Host, Port and Strategy 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 host = accountID .getAccountPropertyString(ProtocolProviderFactory.SERVER_ADDRESS); String port = accountID .getAccountPropertyString(ProtocolProviderFactory.SERVER_PORT); String strategy = accountID .getAccountPropertyString(ProtocolProviderFactory.STRATEGY); this.initAccountID = accountID; // Host field this.hostField.setText(host); // Port Field this.portField.setText(port); // Load strategies this.initstrategy = strategy; this.populateStrategies(); } /** * Handles the action of the button. * * @param e The event generated when the button is pressed. */ public void actionPerformed(ActionEvent e) { // Button action -> populate the list if (e.getActionCommand().equals("populateList")) { this.populateStrategies(); } } /** * Checks if an account is stored for this protocol * @return TRUE, if an account is stored - FALSE otherwise */ private boolean hasAccount() { ProtocolProviderFactory factory = DictAccRegWizzActivator.getDictProtocolProviderFactory(); ArrayList registeredAccounts = factory.getRegisteredAccounts(); return !registeredAccounts.isEmpty(); } /** * Start the thread which will populate the Strategies List */ public void populateStrategies() { // Clear ArrayList this.strategiesList.clear(); boolean ok = this.searchThread.submitRequest(this.hostField.getText(), Integer.parseInt(this.portField.getText())); if (!ok) { // TODO Display error } } /** * Automatic selection of a strategy */ public void autoSelectStrategy() { this.strategiesList.autoSelectStrategy(this.initstrategy); } /** * * @param strategies */ public void setStrategies(List strategies) { this.strategiesList.setStrategies(strategies); } /** * Informs the user of the current status of the search * Should only be called by the thread * @param message Search status */ public void progressMessage(String message) { this.searchProgressPanel.nextStep(message); } /** * Informs the wizard that the search of the strategies is complete. * Should only be called by the thread */ public void strategiesSearchComplete() { setStrategyButtonEnable(true); this.searchProgressPanel.finish(); } /** * Informs the wizard that the search of the strategies is a failure * Should only be called by the thread * @param reason Reason message * @param de Exception thrown */ public void strategiesSearchFailure(String reason, DictException de) { strategiesSearchComplete(); // TODO SHOW ERROR MESSAGE } /** * Enables or disable the Next Button and the Strategy Button * @param e TRUE enables - FALSE disables */ public void setStrategyButtonEnable(boolean e) { // During all the process the buttons and the fieldsset are in the same state this.hostField.setEnabled(e); this.portField.setEnabled(e); this.strategyLoader.setEnabled(e); wizard.getWizardContainer().setNextFinishButtonEnabled(e); } public Object getSimpleForm() { return mainPanel; } /** * Indicates if this is the first dict account * * @return TRUE if this is the first dict account - FALSE otherwise */ public boolean isFirstAccount() { return this.firstAccount; } public boolean isCommitted() { return isPageCommitted; } }