View Javadoc

1   /*
2    *  XNap - A P2P framework and client.
3    *
4    *  See the file AUTHORS for copyright information.
5    *
6    *  This program is free software; you can redistribute it and/or modify
7    *  it under the terms of the GNU General Public License as published by
8    *  the Free Software Foundation.
9    *
10   *  This program is distributed in the hope that it will be useful,
11   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   *  GNU General Public License for more details.
14   *
15   *  You should have received a copy of the GNU General Public License
16   *  along with this program; if not, write to the Free Software
17   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18   */
19  package org.xnap.plugin.overnet.gui;
20  
21  import java.awt.BorderLayout;
22  import java.awt.FlowLayout;
23  import java.awt.GridBagLayout;
24  import java.awt.event.ActionEvent;
25  import java.awt.event.ActionListener;
26  import java.awt.event.ComponentEvent;
27  import java.awt.event.ComponentListener;
28  import java.awt.event.KeyEvent;
29  
30  import javax.swing.AbstractAction;
31  import javax.swing.Action;
32  import javax.swing.Box;
33  import javax.swing.BoxLayout;
34  import javax.swing.JButton;
35  import javax.swing.JLabel;
36  import javax.swing.JPanel;
37  import javax.swing.KeyStroke;
38  
39  import org.apache.log4j.Logger;
40  import org.xnap.XNap;
41  import org.xnap.event.StateEvent;
42  import org.xnap.event.StateListener;
43  import org.xnap.gui.ActionProvider;
44  import org.xnap.gui.ConsolePane;
45  import org.xnap.gui.component.HistoryTextField;
46  import org.xnap.gui.component.XNapButton;
47  import org.xnap.gui.util.GUIHelper;
48  import org.xnap.gui.util.GridBagHelper;
49  import org.xnap.plugin.overnet.OvernetPlugin;
50  import org.xnap.plugin.overnet.gui.action.ConnectAction;
51  import org.xnap.plugin.overnet.gui.action.DisconnectAction;
52  import org.xnap.plugin.overnet.net.OvernetCore;
53  import org.xnap.plugin.overnet.net.msg.OvernetMessage;
54  import org.xnap.plugin.overnet.net.msg.client.CommandMessage;
55  import org.xnap.plugin.overnet.net.msg.core.CoreStatusMessage;
56  import org.xnap.plugin.overnet.net.msg.core.MessageListener;
57  
58  import com.jgoodies.forms.factories.DefaultComponentFactory;
59  
60  
61  public class OvernetPanel extends JPanel implements MessageListener,
62                                                      StateListener,
63                                                      ActionProvider,
64                                                      ComponentListener
65  {
66      private static Logger logger = Logger.getLogger(OvernetPanel.class);
67  
68      //--- Constant(s) ---
69      //--- Data field(s) ---
70  
71      /***
72       * Text area where status messages from the core are shown. If there are
73       * too many messages the old ones will be cropped.
74       */
75      private ConsolePane cpConsole = new ConsolePane(true);
76  
77      /***
78       * Input field for entering commands which are sent to the core.
79       */
80      private HistoryTextField jteInput = new HistoryTextField("", 20);
81  
82      /***
83       * Connects to the core.
84       */
85      private ConnectAction acConnect = new ConnectAction();
86  
87      /***
88       * Disconnects from the core.
89       */
90      private DisconnectAction acDisconnect = new DisconnectAction();
91  
92      /***
93       * Sends the input.
94       */
95      private SendAction acSend = new SendAction();
96  
97      /***
98       * Displays the connection status.
99       */
100     private JLabel jlStatus = new JLabel(XNap.tr("Status:", 0, 1));
101 
102     //--- Constructor(s) ---
103     public OvernetPanel()
104     {
105         initialize();
106         OvernetPlugin.getMessageHandler().subscribe(CoreStatusMessage.TYPE, this);
107         OvernetPlugin.getInstance().getCore().addStateListener(this);
108         stateChanged(null);
109         addComponentListener(this);
110         
111         GUIHelper.setMnemonics(this);
112     }
113 
114     public Action[] getActions()
115     {
116         return new Action[] { acConnect, acDisconnect };
117     }
118 
119     /* (non-Javadoc)
120      * @see java.awt.event.ComponentListener#componentHidden(java.awt.event.ComponentEvent)
121      */
122     public void componentHidden(ComponentEvent e)
123     {
124     }
125 
126     /* (non-Javadoc)
127      * @see java.awt.event.ComponentListener#componentMoved(java.awt.event.ComponentEvent)
128      */
129     public void componentMoved(ComponentEvent e)
130     {
131     }
132 
133     /* (non-Javadoc)
134      * @see java.awt.event.ComponentListener#componentResized(java.awt.event.ComponentEvent)
135      */
136     public void componentResized(ComponentEvent e)
137     {
138     }
139 
140     /* (non-Javadoc)
141      * @see java.awt.event.ComponentListener#componentShown(java.awt.event.ComponentEvent)
142      */
143     public void componentShown(ComponentEvent e)
144     {
145         jteInput.requestFocus();
146     }
147 
148     /***
149      * Does some cleanup removing listeners.
150      */
151     public void dispose()
152     {
153         OvernetPlugin.getMessageHandler().unsubscribe(CoreStatusMessage.TYPE,
154                                                       this);
155         OvernetPlugin.getInstance().getCore().removeStateListener(this);
156     }
157 
158     //--- Method(s) ---
159 
160     /***
161      * Implements the {@link MessageListener} interface.
162      */
163     public void messageReceived(OvernetMessage msg)
164     {
165         if (msg instanceof CoreStatusMessage) {
166             String message = ((CoreStatusMessage)msg).message;
167 
168             if (message != null) {
169                 cpConsole.appendLater(message + "\n");
170             }
171         }
172     }
173 
174     /***
175      * Implements the {@link StateListener} interface.
176      */
177     public void stateChanged(StateEvent event)
178     {
179         OvernetCore core = OvernetPlugin.getInstance().getCore();
180         String msg =
181             (core.getDescription() != null) ? core.getDescription()
182                                             : core.getState().getDescription();
183         jlStatus.setText(XNap.tr("Status: {0} ", core.getState()));
184         cpConsole.appendLater(msg + "\n");
185     }
186 
187     private void initialize()
188     {
189         setLayout(new GridBagLayout());
190         GridBagHelper.add(this,
191                           DefaultComponentFactory.getInstance().createSeparator(XNap
192                                                                                 .tr("Core Connection")));
193 
194         JPanel jpTop = new JPanel(new BorderLayout());
195         GridBagHelper.add(this, jpTop);
196 
197         JPanel jpButtons = new JPanel(new FlowLayout());
198         jpButtons.add(new XNapButton(acConnect));
199         jpButtons.add(new XNapButton(acDisconnect));
200         jpTop.add(jpButtons, BorderLayout.WEST);
201         jpTop.add(jlStatus, BorderLayout.EAST);
202 
203         // console
204         GridBagHelper.add
205 			(this,
206 			 DefaultComponentFactory.getInstance().createSeparator
207 			 (XNap.tr("Console")));
208         GridBagHelper.addPanel(this, cpConsole);
209 
210         // register Shift+Page_UP and Shift+Page_DOWN for console
211 		ActionListener al =
212             cpConsole.getActionForKeyStroke
213 			(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN, 0));
214         cpConsole.registerKeyboardAction
215 			(al,
216 			 KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN, KeyEvent.SHIFT_MASK),
217 			 WHEN_IN_FOCUSED_WINDOW);
218 		
219         al = cpConsole.getActionForKeyStroke
220 			(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP, 0));
221         cpConsole.registerKeyboardAction
222 			(al,
223 			 KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP, KeyEvent.SHIFT_MASK),
224 			 WHEN_IN_FOCUSED_WINDOW);
225 
226         // input
227         Box boxBottom = new Box(BoxLayout.X_AXIS);
228         boxBottom.add(jteInput);
229         GUIHelper.bindEnterKey(jteInput, acSend);
230         boxBottom.add(Box.createHorizontalStrut(5));
231         boxBottom.add(new JButton(acSend));
232         GridBagHelper.add(this, boxBottom);
233     }
234 
235     /***
236      * Sends a command.
237     */
238     private class SendAction extends AbstractAction
239     {
240         public SendAction()
241         {
242             putValue(Action.NAME, XNap.tr("Send"));
243             putValue(Action.SHORT_DESCRIPTION, XNap.tr("Sends command."));
244             putValue(Action.MNEMONIC_KEY, new Integer('S'));
245         }
246 
247         public void actionPerformed(ActionEvent event)
248         {
249             String s = jteInput.getText();
250 
251             if (s.length() > 0) {
252                 OvernetCore.send(new CommandMessage(s.trim()));
253                 jteInput.setText("");
254             }
255         }
256     }
257 }