Java tutorial
// BlogBridge -- RSS feed reader, manager, and web based service // Copyright (C) 2002-2006 by R. Pito Salas // // This program is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free Software Foundation; // either version 2 of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along with this program; // if not, write to the Free Software Foundation, Inc., 59 Temple Place, // Suite 330, Boston, MA 02111-1307 USA // // Contact: R. Pito Salas // mailto:pitosalas@users.sourceforge.net // More information: about BlogBridge // http://www.blogbridge.com // http://sourceforge.net/projects/blogbridge // // $Id: SendFeedbackDialog.java,v 1.17 2006/11/14 13:19:47 spyromus Exp $ // package com.salas.bb.dialogs; import com.jgoodies.forms.factories.ButtonBarFactory; import com.jgoodies.forms.layout.CellConstraints; import com.jgoodies.uif.AbstractDialog; import com.jgoodies.uif.util.Resizer; import com.salas.bb.service.ServerService; import com.salas.bb.service.ServerServiceException; import com.salas.bb.utils.StringUtils; import com.salas.bb.utils.i18n.Strings; import com.salas.bb.utils.uif.BBFormBuilder; import com.salas.bb.utils.uif.ComponentsFactory; import com.salas.bb.utils.uif.HeaderPanelExt; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.util.*; import java.util.List; /** * Dialog for entering a feedback. */ public class SendFeedbackDialog extends AbstractDialog { private static final String THREAD_NAME = "Forums Loader"; private JTextArea wording; private JComboBox cbForum; private JTextField tfSubject; private JTextArea taMessage; private JTextField tfName; private JTextField tfEmail; private JButton btnReload; private JButton btnSend; private static String oldUserName; private static String oldEmail; private static int oldForumId; private static String oldSubject; private static String oldMessage; private static ForumEntry[] forumsList; /** * Constructs dialog box. * * @param owner the dialog's parent frame */ public SendFeedbackDialog(Frame owner) { super(owner); setTitle(Strings.message("sendfeedback.dialog.title")); initComponents(); } protected JComponent buildHeader() { return new HeaderPanelExt(Strings.message("sendfeedback.dialog.title"), Strings.message("sendfeedback.dialog.header")); } /** * Builds contents. * * @return the dialog's main content without header and border */ protected JComponent buildContent() { JPanel content = new JPanel(new BorderLayout()); content.add(createMainPanel(), BorderLayout.CENTER); content.add(buildButtonsBar(), BorderLayout.SOUTH); return content; } private JComponent buildButtonsBar() { return ButtonBarFactory.buildRightAlignedBar(btnSend, createCancelButton()); } // Creates main panel. private Component createMainPanel() { JScrollPane pane = new JScrollPane(taMessage); pane.setPreferredSize(new Dimension(500, 20)); BBFormBuilder builder = new BBFormBuilder("p, 2dlu, max(p;100dlu), 4dlu, p, 2dlu, max(p;150dlu), 0:grow"); builder.append(wording, 8); builder.appendUnrelatedComponentsGapRow(2); builder.append(Strings.message("sendfeedback.forum"), cbForum, btnReload); builder.nextLine(); builder.append(Strings.message("sendfeedback.name"), tfName); builder.append(Strings.message("sendfeedback.email"), tfEmail, 2); builder.append(Strings.message("sendfeedback.subject"), tfSubject, 6); builder.append(Strings.message("sendfeedback.message"), 1).setLabelFor(taMessage); builder.appendRelatedComponentsGapRow(2); builder.appendRow("pref:grow"); builder.append(pane, 8, CellConstraints.FILL, CellConstraints.FILL); builder.append(Strings.message("sendfeedback.notice"), 7); return builder.getPanel(); } /** Initializes components. */ private void initComponents() { btnSend = createAcceptButton(Strings.message("sendfeedback.send"), true); cbForum = new JComboBox(); cbForum.setEnabled(false); cbForum.addItemListener(new ForumSelectionListener()); taMessage = new JTextArea(); taMessage.setWrapStyleWord(true); taMessage.setLineWrap(true); tfSubject = new JTextField(); wording = ComponentsFactory.createWrappedMultilineLabel(Strings.message("sendfeedback.wording")); tfName = new JTextField(); tfEmail = new JTextField(); btnReload = new JButton(new ReloadForumsListAction()); } /** * Clears text and opens dialog. * * @param aName name of the user according to the preferences. * @param aEmail email of the user according to the preferences. */ public void open(String aName, String aEmail) { if (taMessage != null) { tfSubject.setText(oldSubject); taMessage.setText(oldMessage); tfName.setText(oldUserName != null ? oldUserName : aName); tfEmail.setText(oldEmail != null ? oldEmail : aEmail); setupForums(); } super.open(); if (!hasBeenCanceled()) { oldUserName = getFullName(); oldEmail = getEmail(); oldForumId = getForumId(); oldSubject = getSubject(); oldMessage = getMessage(); } } /** * Setups the list of forums. */ private void setupForums() { if (forumsList != null) { popuplateForumsBox(); selectForum(oldForumId); } else { loadForumsList(); } } /** * Selects given forum if the last is in the list. * * @param aForumId forum to select. */ private void selectForum(int aForumId) { if (aForumId == -1 || forumsList == null) return; ForumEntry entry = null; for (int i = 0; entry == null && i < forumsList.length; i++) { ForumEntry forumEntry = forumsList[i]; if (forumEntry.getId() == aForumId) entry = forumEntry; } if (entry != null) cbForum.setSelectedItem(entry); } /** Loads the list of forums available. */ private void loadForumsList() { btnReload.setEnabled(false); setStatusItem(new ForumEntry(-1, Strings.message("sendfeedback.forums.loading"))); Thread thread = new Thread(THREAD_NAME) { public void run() { ForumEntry error = null; try { Map forumsTable = ServerService.forumGetForums(); if (forumsTable != null) { Set entries = forumsTable.entrySet(); final List forums = new ArrayList(entries.size()); Iterator it = entries.iterator(); while (it.hasNext()) { Map.Entry entry = (Map.Entry) it.next(); int forumId = Integer.parseInt(entry.getKey().toString()); String forumName = entry.getValue().toString(); forums.add(new ForumEntry(forumId, forumName)); } // Store obtained forums list and populate combo-box SwingUtilities.invokeLater(new Runnable() { public void run() { forumsList = (ForumEntry[]) forums.toArray(new ForumEntry[forums.size()]); popuplateForumsBox(); } }); } else error = new ForumEntry(-1, Strings.message("sendfeedback.forums.no.forums.found")); } catch (ServerServiceException e) { error = new ForumEntry(-1, Strings.message("sendfeedback.forums.failed.loading")); } // Set error if necessary if (error != null) { final ForumEntry errorEntry = error; SwingUtilities.invokeLater(new Runnable() { public void run() { setStatusItem(errorEntry); } }); } btnReload.setEnabled(true); } }; thread.start(); } /** Invoked when selected forum changes to update the state of Send button. */ private void onForumSelectionChange() { Object item = cbForum.getSelectedItem(); btnSend.setEnabled(item != null && item instanceof ForumEntry && ((ForumEntry) item).getId() != -1); } /** * Puts single entry. * * @param entry entry. */ private void setStatusItem(ForumEntry entry) { cbForum.setEnabled(false); cbForum.removeAllItems(); cbForum.addItem(entry); } /** * Populates the forums box. */ private void popuplateForumsBox() { if (forumsList.length > 0) { cbForum.setEnabled(true); cbForum.removeAllItems(); for (int i = 0; i < forumsList.length; i++) cbForum.addItem(forumsList[i]); } else { setStatusItem(new ForumEntry(-1, Strings.message("sendfeedback.forums.no.forums.available"))); } } /** Accpets the entry only if the data is valid. */ public void doAccept() { ForumEntry selectedForum = (ForumEntry) cbForum.getSelectedItem(); String name = tfName.getText(); String email = tfEmail.getText(); String subject = tfSubject.getText(); String message = taMessage.getText(); String error = hasValidData(selectedForum, name, email, subject, message); if (error != null) { JOptionPane.showMessageDialog(this, error, Strings.message("sendfeedback.dialog.title"), JOptionPane.INFORMATION_MESSAGE); } else super.doAccept(); } /** * Validates the data and returns <code>TRUE</code> if the data is ready for sending. * * @param selectedForum selected forum entry. * @param aName the name of author. * @param aEmail the email address. * @param aSubject the subject of the post. * @param aMessage the message. * * @return <code>TRUE</code> if the data is ready for sending. */ static String hasValidData(ForumEntry selectedForum, String aName, String aEmail, String aSubject, String aMessage) { String error = null; if (selectedForum == null || selectedForum.getId() == -1) { error = Strings.message("sendfeedback.validation.unselected.forum"); } else if (StringUtils.isEmpty(aName)) { error = Strings.message("sendfeedback.validation.empty.name"); } else if (!StringUtils.isEmpty(aEmail) && !StringUtils.isValidEmail(aEmail)) { error = Strings.message("sendfeedback.validation.invalid.email"); } else if (StringUtils.isEmpty(aSubject)) { error = Strings.message("sendfeedback.validation.unspecified.subject"); } else if (StringUtils.isEmpty(aMessage)) { error = Strings.message("sendfeedback.validation.empty.message"); } return error; } /** * Returns text entered by user. * * @return the text. */ public String getMessage() { return taMessage.getText(); } /** * Resizes the specified component. This method is called during the build process and enables * subclasses to achieve a better aspect ratio, by applying a resizer, e.g. the * <code>Resizer</code>. * * @param component the component to be resized */ protected void resizeHook(JComponent component) { Resizer.DEFAULT.resize(component); } /** * Returns email entered by user. * * @return email. */ public String getEmail() { return tfEmail.getText().trim(); } /** * Returns ID of selected forum. * * @return ID of selected forum. */ public int getForumId() { return ((ForumEntry) cbForum.getSelectedItem()).getId(); } /** * Returns the subject line. * * @return subject. */ public String getSubject() { return tfSubject.getText(); } /** * Returns user name. * * @return name. */ public String getFullName() { return tfName.getText(); } /** * Clears old text, forum ID and subject of the message. */ public static void clearBackupData() { oldForumId = -1; oldSubject = null; oldMessage = null; } /** * Single forum entry. */ static class ForumEntry { private int id; private String name; /** * Creates entry. * * @param aId forum ID. * @param aName forum name. */ public ForumEntry(int aId, String aName) { id = aId; name = aName; } /** * Returns forum id. * * @return forum id. */ public int getId() { return id; } /** * Returns a string representation of the object. * * @return a string representation of the object. */ public String toString() { return name; } } /** * Reloads the list of forums. */ private class ReloadForumsListAction extends AbstractAction { /** Defines an <code>Action</code> object with a default description string and default icon. */ public ReloadForumsListAction() { super(Strings.message("sendfeedback.reload.forums")); } /** Invoked when an action occurs. */ public void actionPerformed(ActionEvent e) { loadForumsList(); } } private class ForumSelectionListener implements ItemListener { /** * Invoked when an item has been selected or deselected by the user. The code written for this * method performs the operations that need to occur when an item is selected (or deselected). */ public void itemStateChanged(ItemEvent e) { onForumSelectionChange(); } } }