001: /*
002: * ShellView.java
003: */
004:
005: package applicationpackage;
006:
007: import org.jdesktop.application.Action;
008: import org.jdesktop.application.ResourceMap;
009: import org.jdesktop.application.SingleFrameApplication;
010: import org.jdesktop.application.FrameView;
011: import org.jdesktop.application.TaskMonitor;
012: import org.jdesktop.application.Task;
013: import java.awt.event.ActionEvent;
014: import java.awt.event.ActionListener;
015: import java.util.ArrayList;/* DETAIL_ONLY */
016: import java.util.Collection;
017: import java.util.Iterator;
018: import java.util.LinkedList;/* DETAIL_ONLY */
019: import java.util.List;
020: import javax.persistence.RollbackException;
021: import javax.swing.Timer;
022: import javax.swing.Icon;
023: import javax.swing.JDialog;
024: import javax.swing.JFrame;
025: import javax.swing.event.ListSelectionEvent;
026: import javax.swing.event.ListSelectionListener;
027: import org.jdesktop.beansbinding.AbstractBindingListener;
028: import org.jdesktop.beansbinding.Binding;
029: import org.jdesktop.beansbinding.PropertyStateEvent;
030:
031: /**
032: * The application's main frame.
033: */
034: public class ShellView extends FrameView {
035:
036: public ShellView(SingleFrameApplication app) {
037: super (app);
038:
039: initComponents();
040:
041: // status bar initialization - message timeout, idle icon and busy animation, etc
042: ResourceMap resourceMap = getResourceMap();
043: int messageTimeout = resourceMap
044: .getInteger("StatusBar.messageTimeout");
045: messageTimer = new Timer(messageTimeout, new ActionListener() {
046: public void actionPerformed(ActionEvent e) {
047: statusMessageLabel.setText("");
048: }
049: });
050: messageTimer.setRepeats(false);
051: int busyAnimationRate = resourceMap
052: .getInteger("StatusBar.busyAnimationRate");
053: for (int i = 0; i < busyIcons.length; i++) {
054: busyIcons[i] = resourceMap.getIcon("StatusBar.busyIcons["
055: + i + "]");
056: }
057: busyIconTimer = new Timer(busyAnimationRate,
058: new ActionListener() {
059: public void actionPerformed(ActionEvent e) {
060: busyIconIndex = (busyIconIndex + 1)
061: % busyIcons.length;
062: statusAnimationLabel
063: .setIcon(busyIcons[busyIconIndex]);
064: }
065: });
066: idleIcon = resourceMap.getIcon("StatusBar.idleIcon");
067: statusAnimationLabel.setIcon(idleIcon);
068: progressBar.setVisible(false);
069:
070: // connecting action tasks to status bar via TaskMonitor
071: TaskMonitor taskMonitor = new TaskMonitor(getApplication()
072: .getContext());
073: taskMonitor
074: .addPropertyChangeListener(new java.beans.PropertyChangeListener() {
075: public void propertyChange(
076: java.beans.PropertyChangeEvent evt) {
077: String propertyName = evt.getPropertyName();
078: if ("started".equals(propertyName)) {
079: if (!busyIconTimer.isRunning()) {
080: statusAnimationLabel
081: .setIcon(busyIcons[0]);
082: busyIconIndex = 0;
083: busyIconTimer.start();
084: }
085: progressBar.setVisible(true);
086: progressBar.setIndeterminate(true);
087: } else if ("done".equals(propertyName)) {
088: busyIconTimer.stop();
089: statusAnimationLabel.setIcon(idleIcon);
090: progressBar.setVisible(false);
091: progressBar.setValue(0);
092: } else if ("message".equals(propertyName)) {
093: String text = (String) (evt.getNewValue());
094: statusMessageLabel
095: .setText((text == null) ? "" : text);
096: messageTimer.restart();
097: } else if ("progress".equals(propertyName)) {
098: int value = (Integer) (evt.getNewValue());
099: progressBar.setVisible(true);
100: progressBar.setIndeterminate(false);
101: progressBar.setValue(value);
102: }
103: }
104: });
105:
106: // tracking table selection
107: masterTable.getSelectionModel().addListSelectionListener(
108: new ListSelectionListener() {
109: public void valueChanged(ListSelectionEvent e) {
110: firePropertyChange("recordSelected",
111: !isRecordSelected(), isRecordSelected());
112: }
113: });/* DETAIL_ONLY */
114: detailTable.getSelectionModel().addListSelectionListener(
115: new ListSelectionListener() {
116: public void valueChanged(ListSelectionEvent e) {
117: firePropertyChange("detailRecordSelected",
118: !isDetailRecordSelected(),
119: isDetailRecordSelected());
120: }
121: }); /* DETAIL_ONLY */
122:
123: // tracking changes to save
124: bindingGroup.addBindingListener(new AbstractBindingListener() {
125: @Override
126: public void targetChanged(Binding binding,
127: PropertyStateEvent event) {
128: // save action observes saveNeeded property
129: setSaveNeeded(true);
130: }
131: });
132:
133: // have a transaction started
134: entityManager.getTransaction().begin();
135: }
136:
137: public boolean isSaveNeeded() {
138: return saveNeeded;
139: }
140:
141: private void setSaveNeeded(boolean saveNeeded) {
142: if (saveNeeded != this .saveNeeded) {
143: this .saveNeeded = saveNeeded;
144: firePropertyChange("saveNeeded", !saveNeeded, saveNeeded);
145: }
146: }
147:
148: public boolean isRecordSelected() {
149: return masterTable.getSelectedRow() != -1;
150: }
151:
152: /* DETAIL_ONLY */
153: public boolean isDetailRecordSelected() {
154: return detailTable.getSelectedRow() != -1;
155: }/* DETAIL_ONLY */
156:
157: @Action
158: public void newRecord() {
159: _masterClass_ _masterEntityInitial_ = new _masterClass_();
160: entityManager.persist(_masterEntityInitial_);
161: list.add(_masterEntityInitial_);
162: int row = list.size() - 1;
163: masterTable.setRowSelectionInterval(row, row);
164: masterTable.scrollRectToVisible(masterTable.getCellRect(row, 0,
165: true));
166: setSaveNeeded(true);
167: }
168:
169: @Action(enabledProperty="recordSelected")
170: public void deleteRecord() {
171: int[] selected = masterTable.getSelectedRows();
172: List<_masterClass_> toRemove = new ArrayList<_masterClass_>(
173: selected.length);
174: for (int idx = 0; idx < selected.length; idx++) {
175: _masterClass_ _masterEntityInitial_ = list
176: .get(/* JDK6ONLY */masterTable
177: .convertRowIndexToModel(/* JDK6ONLY */selected[idx]/* JDK6ONLY */)/* JDK6ONLY */);
178: toRemove.add(_masterEntityInitial_);
179: entityManager.remove(_masterEntityInitial_);
180: }
181: list.removeAll(toRemove);
182: setSaveNeeded(true);
183: }
184:
185: /* DETAIL_ONLY */
186: @Action(enabledProperty="recordSelected")
187: public void newDetailRecord() {
188: int index = masterTable.getSelectedRow();
189: _masterClass_ _masterEntityInitial_ = list
190: .get(/* JDK6ONLY */masterTable
191: .convertRowIndexToModel(/* JDK6ONLY */index/* JDK6ONLY */)/* JDK6ONLY */);
192: Collection<_detailClass_> _detailEntityInitial_s = _masterEntityInitial_
193: .get_joinCollectionCapital_();
194: if (_detailEntityInitial_s == null) {
195: _detailEntityInitial_s = new LinkedList<_detailClass_>();
196: _masterEntityInitial_
197: .set_joinCollectionCapital_(_detailEntityInitial_s);
198: }
199: _detailClass_ _detailEntityInitial_ = new _detailClass_();
200: entityManager.persist(_detailEntityInitial_);
201: _detailEntityInitial_.set_joinCapital_(_masterEntityInitial_);
202: _detailEntityInitial_s.add(_detailEntityInitial_);
203: masterTable.clearSelection();
204: masterTable.setRowSelectionInterval(index, index);
205: int row = _detailEntityInitial_s.size() - 1;
206: detailTable.setRowSelectionInterval(row, row);
207: detailTable.scrollRectToVisible(detailTable.getCellRect(row, 0,
208: true));
209: setSaveNeeded(true);
210: }
211:
212: @Action(enabledProperty="detailRecordSelected")
213: public void deleteDetailRecord() {
214: int index = masterTable.getSelectedRow();
215: _masterClass_ _masterEntityInitial_ = list
216: .get(/* JDK6ONLY */masterTable
217: .convertRowIndexToModel(/* JDK6ONLY */index/* JDK6ONLY */)/* JDK6ONLY */);
218: Collection<_detailClass_> _detailEntityInitial_s = _masterEntityInitial_
219: .get_joinCollectionCapital_();
220: int[] selected = detailTable.getSelectedRows();
221: List<_detailClass_> toRemove = new ArrayList<_detailClass_>(
222: selected.length);
223: for (int idx = 0; idx < selected.length; idx++) {/* JDK6ONLY */
224: selected[idx] = detailTable
225: .convertRowIndexToModel(selected[idx]);/* JDK6ONLY */
226: int count = 0;
227: Iterator<_detailClass_> iter = _detailEntityInitial_s
228: .iterator();
229: while (count++ < selected[idx])
230: iter.next();
231: _detailClass_ _detailEntityInitial_ = iter.next();
232: toRemove.add(_detailEntityInitial_);
233: entityManager.remove(_detailEntityInitial_);
234: }
235: _detailEntityInitial_s.removeAll(toRemove);
236: masterTable.clearSelection();
237: masterTable.setRowSelectionInterval(index, index);
238: setSaveNeeded(true);
239: }/* DETAIL_ONLY */
240:
241: @Action(enabledProperty="saveNeeded")
242: public Task save() {
243: return new SaveTask(getApplication());
244: }
245:
246: private class SaveTask extends Task {
247: SaveTask(org.jdesktop.application.Application app) {
248: super (app);
249: }
250:
251: @Override
252: protected Void doInBackground() {
253: try {
254: entityManager.getTransaction().commit();
255: entityManager.getTransaction().begin();
256: } catch (RollbackException rex) {
257: rex.printStackTrace();
258: entityManager.getTransaction().begin();
259: List<_masterClass_> merged = new ArrayList<_masterClass_>(
260: list.size());
261: for (_masterClass_ _masterEntityInitial_ : list) {
262: merged.add(entityManager
263: .merge(_masterEntityInitial_));
264: }
265: list.clear();
266: list.addAll(merged);
267: }
268: return null;
269: }
270:
271: @Override
272: protected void finished() {
273: setSaveNeeded(false);
274: }
275: }
276:
277: /**
278: * An example action method showing how to create asynchronous tasks
279: * (running on background) and how to show their progress. Note the
280: * artificial 'Thread.sleep' calls making the task long enough to see the
281: * progress visualization - remove the sleeps for real application.
282: */
283: @Action
284: public Task refresh() {
285: return new RefreshTask(getApplication());
286: }
287:
288: private class RefreshTask extends Task {
289: RefreshTask(org.jdesktop.application.Application app) {
290: super (app);
291: }
292:
293: @SuppressWarnings("unchecked")
294: @Override
295: protected Void doInBackground() {
296: try {
297: setProgress(0, 0, 4);
298: setMessage("Rolling back the current changes...");
299: setProgress(1, 0, 4);
300: entityManager.getTransaction().rollback();
301: Thread.sleep(1000L); // remove for real app
302: setProgress(2, 0, 4);
303:
304: setMessage("Starting a new transaction...");
305: entityManager.getTransaction().begin();
306: Thread.sleep(500L); // remove for real app
307: setProgress(3, 0, 4);
308:
309: setMessage("Fetching new data...");
310: java.util.Collection data = query.getResultList();
311: for (Object entity : data) {
312: entityManager.refresh(entity);
313: }
314: Thread.sleep(1300L); // remove for real app
315: setProgress(4, 0, 4);
316:
317: Thread.sleep(150L); // remove for real app
318: list.clear();
319: list.addAll(data);
320: } catch (InterruptedException ignore) {
321: }
322: return null;
323: }
324:
325: @Override
326: protected void finished() {
327: setMessage("Done.");
328: setSaveNeeded(false);
329: }
330: }
331:
332: @Action
333: public void showAboutBox() {
334: if (aboutBox == null) {
335: JFrame mainFrame = ShellApp.getApplication().getMainFrame();
336: aboutBox = new ShellAboutBox(mainFrame);
337: aboutBox.setLocationRelativeTo(mainFrame);
338: }
339: ShellApp.getApplication().show(aboutBox);
340: }
341:
342: /** This method is called from within the constructor to
343: * initialize the form.
344: * WARNING: Do NOT modify this code. The content of this method is
345: * always regenerated by the Form Editor.
346: */
347: @SuppressWarnings("unchecked")
348: // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
349: private void initComponents() {
350: }// </editor-fold>//GEN-END:initComponents
351:
352: // Variables declaration - do not modify//GEN-BEGIN:variables
353: private javax.swing.JPanel mainPanel;
354: private javax.swing.JMenuBar menuBar;
355: private javax.swing.JProgressBar progressBar;
356: private javax.swing.JLabel statusAnimationLabel;
357: private javax.swing.JLabel statusMessageLabel;
358: private javax.swing.JPanel statusPanel;
359: // End of variables declaration//GEN-END:variables
360:
361: private final Timer messageTimer;
362: private final Timer busyIconTimer;
363: private final Icon idleIcon;
364: private final Icon[] busyIcons = new Icon[15];
365: private int busyIconIndex = 0;
366:
367: private JDialog aboutBox;
368:
369: private boolean saveNeeded;
370: }
|