listDemo/jython/ListDemo.py

  1: #! /usr/bin/env python
  2: # coding: utf-8
  3: ## ----------------------------------------
  4: ##
  5: ## (C) Copyright 2000-2010, 小粒ちゃん《監修》小泉ひよ子とタマゴ倶楽部
  6: ##
  7: ## ----------------------------------------
  8: #...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8
  9: """
 10: >>> tips()
 11: 
 12: >>> ## ----------------------------------------
 13: >>> None
 14: version: #1.0.64
 15: """
 16: ## ---------------------------------------- demo: jython
 17: """
 18: _jython=/Users/sketch/book/java_useBetter_1/_jython
 19: 
 20: cd /Users/sketch/book/java_useBetter_1/swing/JList/listDemo/jython
 21: 
 22: JYTHONPATH=$_jython jython -i ListDemo.py
 23: 
 24: ============================================================
 25: Version: 2.5.0 (Release_2_5_0:6476, Jun 16 2009, 13:33:26) 
 26: Module : ListDemo.py
 27: Date   : Sun Sep  5 19:50:01 2010
 28: ============================================================
 29: """
 30: from __init__ import *
 31: 
 32: ## ----------------------------------------
 33: ##package components;
 34: 
 35: from java.awt import BorderLayout
 36: from java.awt import Toolkit
 37: from java.awt.event import ActionListener
 38: from javax.swing import BorderFactory
 39: from javax.swing import Box
 40: from javax.swing import BoxLayout
 41: from javax.swing import DefaultListModel
 42: from javax.swing import JButton
 43: from javax.swing import JFrame
 44: from javax.swing import JList
 45: from javax.swing import JPanel
 46: from javax.swing import JScrollPane
 47: from javax.swing import JSeparator
 48: from javax.swing import JTextField
 49: from javax.swing import ListSelectionModel
 50: from javax.swing import SwingConstants
 51: from javax.swing.event import DocumentListener
 52: from javax.swing.event import ListSelectionListener
 53: 
 54: ## ----------------------------------------
 55: class ListDemo(JPanel, ListSelectionListener):
 56: 
 57:     def __init__(self,*args,**keys):
 58:         super(self.__class__,self).__init__(
 59:             layout=BorderLayout(),
 60:             **keys
 61:             )
 62:         hireString = "Hire"
 63:         fireString = "Fire"
 64: 
 65:         global                                          Xmodel; Xmodel = \
 66:         self.listModel = m = DefaultListModel()
 67:         for e in [
 68:             "Debbie Scott",
 69:             "Scott Hommel",
 70:             "Sharon Zakhour",
 71:         ]:
 72:             m.addElement(e)
 73: 
 74:         ##//Create the list and put it in a scroll pane.
 75:         global                                          Xview; Xview = \
 76:         self.list = JList(
 77:             model = self.listModel,
 78:             selectionMode = ListSelectionModel.SINGLE_SELECTION,
 79:             selectedIndex = 0,
 80:             visibleRowCount = 5,
 81:             valueChanged = self.valueChanged,
 82:             )
 83:         listScrollPane = JScrollPane(self.list)
 84: 
 85:         hireButton = JButton(
 86:             label = hireString,
 87:             actionCommand = hireString,
 88:             enabled = False,
 89:             )
 90:         ##hireListener = HireListener(hireButton)
 91:         hireListener = HireListener(hireButton, self)
 92:         hireListener._client = self
 93:         hireButton.actionPerformed = hireListener.actionPerformed
 94: 
 95:         def FireListener(e):
 96:             ##//This method can be called only if
 97:             ##//there's a valid selection
 98:             ##//so go ahead and remove whatever's selected.
 99:             index = self.list.selectedIndex
100:             self.listModel.remove(index)
101:             size = self.listModel.getSize()     # NG: .size
102:             if not size:            #//Nobody's left, disable firing.
103:                 self.fireButton.enabled = False
104:             else:                   #//Select an index.
105:                 if index == self.listModel.getSize():
106:                     ##//removed item in last position
107:                     index -= 1
108:                 self.list.selectedIndex = index
109:                 self.list.ensureIndexIsVisible(index)
110: 
111:         self.fireButton = JButton(
112:             label = fireString,
113:             actionCommand = fireString,
114:             actionPerformed = FireListener,
115:             )
116: 
117:         self.employeeName = JTextField(10,
118:             actionPerformed = hireListener,     # .actionPerformed,
119:             )
120:         self.employeeName.document.addDocumentListener(hireListener)
121:         ##String name = listModel.getElementAt(
122:         ##                      list.getSelectedIndex()).toString();
123: 
124:         ##//Create a panel that uses BoxLayout.
125:         buttonPane = c = JPanel(
126:             border = BorderFactory.createEmptyBorder(5,5,5,5),
127:             )
128:         buttonPane.layout = BoxLayout(buttonPane, BoxLayout.LINE_AXIS)
129:         for e in [
130:             self.fireButton,
131:             Box.createHorizontalStrut(5),
132:             JSeparator(SwingConstants.VERTICAL),
133:             Box.createHorizontalStrut(5),
134:             self.employeeName,
135:             hireButton,
136:         ]:
137:             c.add(e)
138: 
139:         for e, constraints in [
140:             (listScrollPane, BorderLayout.CENTER  ),
141:             (buttonPane,     BorderLayout.PAGE_END),
142:         ]:
143:             self.add(e, constraints)
144: 
145:     ##//This method is required by ListSelectionListener.
146:     def valueChanged(self, e):
147:         print "... selectedIndex:",self.list.selectedIndex
148:         if not e.valueIsAdjusting:
149:             if self.list.selectedIndex == -1:
150:                 ##//No selection, disable fire button.
151:                 self.fireButton.enabled = False
152:             else:
153:                 ##//Selection, enable the fire button.
154:                 self.fireButton.enabled = True
155: 
156:     """
157:      * Create the GUI and show it.  For thread safety,
158:      * this method should be invoked from the
159:      * event-dispatching thread.
160:     """
161:     @staticmethod
162:     def createAndShowGUI():
163:         ##//Create and set up the window.
164:         frame = JFrame(
165:             defaultCloseOperation = JFrame.EXIT_ON_CLOSE,
166:             title = "ListDemo",
167:             contentPane = ListDemo(opaque = True)   #//content panes must be opaque
168:             )
169: 
170:         ##//Create and set up the content pane.
171: 
172:         ##//Display the window.
173:         frame.pack()
174:         frame.visible = True
175: 
176: ## ----------------------------------------
177: class HireListener(ActionListener, DocumentListener):
178:     ##//This listener is shared by the text field and the hire button.
179:     alreadyEnabled = False
180: 
181:     def __init__(self, button, client):
182:         self.button = button
183:         self._client = client
184: 
185:     ##//Required by ActionListener.
186:     def actionPerformed(self, e):
187:         print "... HireListener.actionPerformed"
188:         name = self._client.employeeName.text
189: 
190:         ##//User didn't type in a unique name...
191:         if name=="" or self._alreadyInList(name):
192:             Toolkit.getDefaultToolkit().beep()
193:             self._client.employeeName.requestFocusInWindow()
194:             self._client.employeeName.selectAll()
195:             return
196: 
197:         index = self._client.list.selectedIndex
198:         if index == -1:     #//no selection, so insert at beginning
199:             index = 0
200:         else:               #//add after the selected item
201:             index += 1
202: 
203:         self._client.listModel.insertElementAt(
204:             self._client.employeeName.text, index)
205:         
206:         ##//If we just wanted to add to the end, we'd do this:
207:         ##//listModel.addElement(employeeName.getText());
208: 
209:         ##//Reset the text field.
210:         self._client.employeeName.requestFocusInWindow()
211:         self._client.employeeName.setText("")
212: 
213:         ##//Select the new item and make it visible.
214:         self._client.list.setSelectedIndex(index)
215:         self._client.list.ensureIndexIsVisible(index)
216: 
217:     ##//This method tests for string equality. You could certainly
218:     ##//get more sophisticated about the algorithm.  For example,
219:     ##//you might want to ignore white space and capitalization.
220:     def _alreadyInList(self, name):
221:         return self._client.listModel.contains(name)
222: 
223:     ##//Required by DocumentListener.
224:     def insertUpdate(self, e):
225:         self._enableButton()
226: 
227:     ##//Required by DocumentListener.
228:     def removeUpdate(self, e):
229:         self._handleEmptyTextField(e)
230: 
231:     ##//Required by DocumentListener.
232:     def changedUpdate(self, e):
233:         print "<<< changedUpdate ***"
234:         if not self._handleEmptyTextField(e):
235:             self._enableButton()
236: 
237:     ## ----------------------------------------
238:     def _enableButton(self):
239:         if not self.alreadyEnabled:
240:             self.button.enabled = True
241: 
242:     def _handleEmptyTextField(self, e):
243:         if e.document.length <= 0:
244:             self.button.enabled = False
245:             self.alreadyEnabled = False
246:             return True
247:         return False
248: 
249: ## ----------------------------------------
250: def tips():
251:     ##Schedule a job for the event dispatch thread:
252:     ##creating and showing this application's GUI.
253:     ListDemo.createAndShowGUI()
254: 
255: ## ----------------------------------------
256: if __name__=='__main__':
257:     inform()
258:     testmod()
259: 
260: ## ========================================