001: package simpleorm.examples;
002:
003: import simpleorm.ui.*;
004:
005: import simpleorm.core.*; // .* OK, all classes prefixed with "S".
006: import javax.swing.*;
007: import javax.swing.event.*;
008: import java.awt.*;
009: import java.awt.event.*;
010: import java.util.*;
011: import java.text.NumberFormat;
012: import java.awt.geom.*;
013:
014: /** Demo of SimpleORM in a Swing Environment. Currently
015: mainly just plays with Swing classes, but will be a generalized
016: interface for editing any tables data. The tricky part is foreign
017: keys and lookups. <p>
018:
019: Also note that the nasty way that Swing handles threads complicates
020: the common case of a single threaded program. In the normal pattern,
021: the main thread sets up the forms, and then exits. A second thread
022: then does the work. A single threaded application using two threads!
023: This application uses <code>invokeAndWait()</code> to do all the work
024: in the Swing thread, which is much cleaner.<p>
025:
026: */
027:
028: public class SwingTest implements SUIConstants {
029:
030: static JFrame frame = null;
031: static ThreadLocal tlocal = new ThreadLocal();
032:
033: public static void main(String[] argv) throws Exception {
034: tlocal.set("MainLocal");
035: Runnable swing = new Runnable() {
036: public void run() {
037: try {
038: doMain();
039: } catch (Exception ex) {
040: throw new SException.Test(ex);
041: }
042: }
043: };
044: SwingUtilities.invokeAndWait(swing);
045: // Makes all the SimpleORM work happen in the Swing thread.
046: System.out.println("Exiting main thread..."
047: + Thread.currentThread() + tlocal.get());
048: }
049:
050: /** This executes in the Swing thread, so SOrm connections work nicely. */
051: static void doMain() throws Exception {
052: tlocal.set("SwingLocal");
053: TestUte.initializeTest(SwingTest.class);
054: //#### TestUte.createDeptEmp();
055: SConnection.begin();
056: editDept();
057: SConnection.commit();
058: SConnection.begin();
059: System.out.println("Exiting runnable..."
060: + Thread.currentThread() + tlocal.get());
061: }
062:
063: static void editDept() throws Exception {
064: frame = new JFrame();
065: frame.setTitle("Swing SimpleORM Tester");
066:
067: /* Simple Table
068: Object [][] ddata = readDeptData();
069: String [] headings = {"Dept ID", "Name"};
070: final JTable jtable = new JTable(ddata, headings);
071: JScrollPane scrollPane = new JScrollPane(jtable);
072: scrollPane.setVerticalScrollBarPolicy(
073: ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
074: JPanel jpanel = new JPanel();
075: jpanel.setLayout(new BorderLayout()); // Necessary for scrolling
076: jpanel.add(scrollPane, BorderLayout.CENTER);
077: frame.getContentPane().add(jpanel);
078: */
079:
080: frame.setJMenuBar(makeMenu());
081:
082: JComponent panel = makeTabs();
083:
084: // Add the top panel to the frame and start execution
085: frame.getContentPane().add(panel);
086: //frame.getContentPane().add(new JLabel("WestLab"), BorderLayout.WEST);
087:
088: //frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
089: frame.addWindowListener(new WindowAdapter() {
090: public void windowClosing(WindowEvent e) {
091: SConnection.commit();
092: SConnection.detachAndClose(); // Need listener.
093: System.exit(0); // #### Ugly, but how else to stop the thread? stop()?
094: }
095: });
096: frame.pack();
097: frame.setVisible(true);
098: }
099:
100: /** Menu not currently used. */
101: static JMenuBar makeMenu() throws Exception {
102: JMenuBar jmb = new JMenuBar();
103: JMenu file = new JMenu("UnusedMenu");
104: jmb.add(file);
105: JMenuItem item = new JMenuItem("SillyItem");
106: file.add(item);
107: item.addActionListener(new ActionListener() {
108: public void actionPerformed(ActionEvent e) {
109: System.out.println("Menu " + e.getActionCommand());
110: }
111: });
112: return jmb;
113: }
114:
115: static JComponent makeTabs() throws Exception {
116: // Tabs
117: JTabbedPane tabbedPane = new JTabbedPane();
118:
119: tabbedPane.addTab("List Depts", null, deptsTab());
120:
121: tabbedPane.addTab("Play", null, playTab());
122:
123: JPanel second = new GraphicsTab();
124: second.addMouseListener(new MListener());
125: tabbedPane.addTab("Graphics", null, second);
126: tabbedPane.setSelectedIndex(0);
127: return tabbedPane;
128: }
129:
130: public static JComponent deptsTab() {
131:
132: final DeptTableModel tModel = new DeptTableModel();
133: final JTable jtable = new JTable(tModel);
134: //jtable.setPreferredScrollableViewportSize(new Dimension(500, 70));
135: JScrollPane scrollPane = new JScrollPane(jtable);
136: scrollPane
137: .setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
138:
139: jtable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
140: ListSelectionModel rowSM = jtable.getSelectionModel();
141: rowSM.addListSelectionListener(new ListSelectionListener() {
142: public void valueChanged(ListSelectionEvent e) {
143: //Ignore extra messages.
144: if (e.getValueIsAdjusting())
145: return;
146: ListSelectionModel lsm = (ListSelectionModel) e
147: .getSource();
148: if (lsm.isSelectionEmpty()) {
149: System.out.println("No Row Selected.");
150: } else {
151: int selectedRow = lsm.getMinSelectionIndex(); // 0 is first
152: System.out.println("Row " + selectedRow
153: + " Selected ");
154: showDeptDialog(tModel.getValueAt(selectedRow, 0));
155: //throw new RuntimeException(); // Ignored!
156: }
157: }
158: });
159: return scrollPane;
160: }
161:
162: static class DeptTableModel extends
163: javax.swing.table.AbstractTableModel {
164: Object[][] ddata = readDeptData();
165: String deptIdLab = Department.DEPT_ID.getString(SUI_PROMPT);
166: String deptNameLab = Department.NAME.getString(SUI_PROMPT);
167: String[] headings = { deptIdLab, deptNameLab };
168:
169: public int getColumnCount() {
170: return 2;
171: }
172:
173: public int getRowCount() {
174: return ddata.length;
175: }
176:
177: public String getColumnName(int col) {
178: return headings[col];
179: }
180:
181: public Object getValueAt(int row, int col) {
182: return ddata[row][col];
183: }
184:
185: /** Read all the Departments(Id, Name) from the database. */
186: public static Object[][] readDeptData() {
187: ArrayList ddata = new ArrayList();
188: /// Prepare and execute the query
189: SPreparedStatement stmt = Department.meta.select("1=1",
190: "NAME");
191: SResultSet res = stmt.execute();
192:
193: /// loop through the results, adding up the budgets.
194: while (res.hasNext()) {
195: Department dept = (Department) res.getRecord();
196: Object[] rec = { dept.getString(Department.DEPT_ID),
197: dept.getString(Department.NAME) };
198: ddata.add(rec);
199: }
200: Object[][] darray = (Object[][]) ddata
201: .toArray(new Object[0][0]);
202: //Object [] darray = new Object[1][];
203: return darray;
204: }
205: } // DeptTableModel
206:
207: /** Called when the user selects a row. Non-Modal, but only one shown.*/
208: static void showDeptDialog(Object key) {
209: System.out.println("DeptDialog..." + Thread.currentThread()
210: + tlocal.get());
211: Department dept = (Department) Department.meta
212: .findOrCreate((String) key);
213:
214: if (jdialog == null) {
215: jdialog = new JDialog(frame, "My Dialog", false); // modalality
216: }
217: JPanel jpanel = new JPanel();
218: jpanel.setLayout(new GridLayout(0, 2));
219: String deptIdLab = Department.DEPT_ID.getString(SUI_PROMPT);
220: jpanel.add(new JLabel(deptIdLab));
221: jpanel.add(new JLabel(dept.getString(dept.DEPT_ID)));
222: String missionLab = Department.MISSION.getString(SUI_PROMPT);
223: jpanel.add(new JLabel(missionLab));
224: JTextField mission = new JTextField(30);
225: mission.setText(dept.getString(dept.MISSION));
226: jpanel.add(mission);
227:
228: jdialog.getContentPane().add(jpanel);
229: jdialog.pack();
230: jdialog.setLocationRelativeTo(frame);
231: jdialog.setVisible(true); // Display
232: }
233:
234: static JDialog jdialog = null;
235:
236: public static JPanel playTab() {
237: JPanel panel = new JPanel(); // Needed if more than one item
238: panel.add(new JLabel("Sliders Share Model"));
239: GridBagLayout gbl = new GridBagLayout();
240: panel.setLayout(gbl);
241:
242: /// Label, Field and Button
243: final JLabel label = new JLabel(
244: "<html><font color=red>Hello</font> World</html>",
245: JLabel.RIGHT);
246: // </html> must be last -- appending "!" resets.
247: label.setAlignmentX(Component.RIGHT_ALIGNMENT); // Don't work.
248: GridBagConstraints labelc = new GridBagConstraints();
249: labelc.anchor = labelc.WEST; // No good either.
250: gbl.setConstraints(label, labelc);
251: panel.add(label);
252:
253: final JTextField field = new JTextField(20);
254: GridBagConstraints fieldc = new GridBagConstraints();
255: gbl.setConstraints(label, fieldc);
256: panel.add(field);
257:
258: final JButton button = new JButton("Add !!");
259: button.addActionListener(new ActionListener() {
260: public void actionPerformed(ActionEvent evt) {
261: label.setText(field.getText() + "!!");
262: //JOptionPane.showMessageDialog(frame, "Pressed!");
263: }
264: });
265: GridBagConstraints buttonc = new GridBagConstraints();
266: buttonc.gridheight = 2;
267: gbl.setConstraints(button, buttonc);
268: panel.add(button);
269: label.setLabelFor(button); // For ADO
270:
271: /// Two sliders, one model.
272: BoundedRangeModel brm = new DefaultBoundedRangeModel(3, 2, 0,
273: 10);
274:
275: final JSlider slider1 = new JSlider(); //sliderModel);
276: slider1.setModel(brm);
277: GridBagConstraints slider1c = new GridBagConstraints();
278: slider1c.gridy = 1;
279: slider1c.gridx = 0;
280: slider1c.gridwidth = 2;
281: gbl.setConstraints(slider1, slider1c);
282: panel.add(slider1);
283:
284: final JSlider slider2 = new JSlider(); //sliderModel);
285: slider2.setModel(brm);
286: GridBagConstraints slider2c = new GridBagConstraints();
287: slider2c.gridy = 1;
288: slider2c.gridwidth = 1;
289: gbl.setConstraints(slider2, slider2c);
290: panel.add(slider2);
291:
292: /// Set a border for fun
293: panel.setBorder(BorderFactory.createCompoundBorder(
294: BorderFactory.createTitledBorder("Named Border"),
295: BorderFactory.createEmptyBorder(30, 30, 30, 30))); // top left bottom right
296:
297: return panel;
298: }
299:
300: /** This second tab is just used to play with graphic objects for
301: now. Later it will be used to do non-Form database I/O. */
302: static class GraphicsTab extends JPanel {
303: public void paintComponent(Graphics g) {
304: super .paintComponent(g); //paint background
305:
306: g.setColor(Color.yellow); // For the next graphic!
307: g.fillRect(5, 5, 200, 20);
308:
309: Graphics2D g2 = (Graphics2D) g;
310: GradientPaint redtowhite = new GradientPaint(5, 20,
311: Color.red, 200, 100, Color.white);
312: g2.setPaint(redtowhite);
313: g2.fill(new Ellipse2D.Double(5, 20, 200, 100));
314: }
315: }
316:
317: static class MListener implements MouseListener {
318: public void mousePressed(MouseEvent e) {
319: saySomething("Mouse pressed (# of clicks: "
320: + e.getClickCount() + ")", e);
321: }
322:
323: public void mouseReleased(MouseEvent e) {
324: saySomething("Mouse released (# of clicks: "
325: + e.getClickCount() + ")", e);
326: }
327:
328: public void mouseEntered(MouseEvent e) {
329: saySomething("Mouse entered", e);
330: }
331:
332: public void mouseExited(MouseEvent e) {
333: saySomething("Mouse exited", e);
334: }
335:
336: public void mouseClicked(MouseEvent e) {
337: saySomething("Mouse clicked (# of clicks: "
338: + e.getClickCount() + ")", e);
339: }
340:
341: void saySomething(String eventDescription, MouseEvent e) {
342: System.out.println(eventDescription + " detected on "
343: + e.getComponent().getClass().getName());
344: }
345: }
346: }
|