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: ## ========================================