You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

228 lines
6.9 KiB

  1. package gui;
  2. import javax.swing.*;
  3. import java.awt.event.*;
  4. import java.util.*;
  5. /**
  6. * a simple GUI that simulates a slow database for name, email entries. For details see constructor {@link MainGui#MainGui() }.
  7. * This class provides a simple static {@link #main(String[])} to start/run the GUI window.
  8. */
  9. public class MainGui {
  10. private JFrame frame = null;
  11. private JPanel cp = new JPanel();
  12. private JPanel topPanel = new JPanel();
  13. private JPanel middlePanel = new JPanel();
  14. private JPanel bottomPanel = new JPanel();
  15. private JTextField tfName = new JTextField("", 20);
  16. private JTextField tfMail = new JTextField("", 20);
  17. private JButton btBack = new JButton("<--");
  18. private JButton btForward = new JButton("-->");
  19. private JButton btAdd = new JButton("Neu");
  20. private ArrayList<DBEntry> database = new ArrayList<DBEntry>();
  21. private int index = 0;
  22. private JMenuItem menuNew = new JMenuItem("Neu");
  23. private JMenuItem menuEnd = new JMenuItem("Ende");
  24. /** inner class representing one entry to DB */
  25. private class DBEntry {
  26. String name;
  27. String email;
  28. }
  29. /** inner class to be used for ActionListener back */
  30. private class BackAction implements ActionListener {
  31. @Override
  32. public void actionPerformed(ActionEvent e) {
  33. // always save current entry before loading next
  34. DBEntry entry = new DBEntry(); // we create a new DBEntry object instead manipulating the
  35. // existing one to simulate real new reference to a new object.
  36. entry.name = tfName.getText();
  37. entry.email = tfMail.getText();
  38. saveFieldsToDB(entry, index);
  39. if (index >= 1) {
  40. index--;
  41. DBEntry entryLoaded = getEntryFromDB(index);
  42. tfName.setText(entryLoaded.name);
  43. tfMail.setText(entryLoaded.email);
  44. }
  45. }
  46. }
  47. /** inner class to be used for ActionListener forward */
  48. private class ForwardAction implements ActionListener {
  49. @Override
  50. public void actionPerformed(ActionEvent e) {
  51. // always save current entry before loading next
  52. DBEntry entry = new DBEntry(); // we create a new DBEntry object instead manipulating the
  53. // existing one to simulate real new reference to a new object.
  54. entry.name = tfName.getText();
  55. entry.email = tfMail.getText();
  56. saveFieldsToDB(entry, index);
  57. if (index < database.size() - 1) {
  58. index++;
  59. DBEntry entryLoaded = getEntryFromDB(index);
  60. tfName.setText(entryLoaded.name);
  61. tfMail.setText(entryLoaded.email);
  62. }
  63. }
  64. }
  65. /** inner class to be used for ActionListener exit program */
  66. private class EndAction implements ActionListener {
  67. @Override
  68. public void actionPerformed(ActionEvent e) {
  69. System.exit(0);
  70. }
  71. }
  72. /** inner class to be used for ActionListener add */
  73. private class AddAction implements ActionListener {
  74. @Override
  75. public void actionPerformed(ActionEvent e) {
  76. // always save current entry before loading next
  77. DBEntry entry = new DBEntry(); // we create a new DBEntry object instead manipulating the
  78. // existing one to simulate real new reference to a new object.
  79. entry.name = tfName.getText();
  80. entry.email = tfMail.getText();
  81. saveFieldsToDB(entry, index);
  82. addEmptyEntryToDB();
  83. index = database.size() - 1;
  84. DBEntry entryLoaded = getEntryFromDB(index);
  85. tfName.setText(entryLoaded.name);
  86. tfMail.setText(entryLoaded.email);
  87. }
  88. }
  89. /** manipulation of DB and simulates slow connection by Thread.wait() */
  90. private void saveFieldsToDB(DBEntry entry, int index) {
  91. database.set(index, entry);
  92. doWait();
  93. }
  94. /** add an empty entry at end of db (quickly) */
  95. private void addEmptyEntryToDB() {
  96. DBEntry dbEntry = new DBEntry();
  97. dbEntry.name = "";
  98. dbEntry.email = "";
  99. database.add(dbEntry);
  100. }
  101. /** reads from DB (quickly) */
  102. private DBEntry getEntryFromDB(int index) {
  103. return this.database.get(index);
  104. }
  105. /** performing a Thread.wait() for 3 sec */
  106. private void doWait() {
  107. try {
  108. synchronized (database) {
  109. database.wait(3 * 1000); // simulates "slow" database by waiting 3sec before this Thread
  110. // continues. wait needs monitor of the object, thus synchronized
  111. }
  112. } catch (InterruptedException e1) {
  113. // intentionally blank; wait did not work or was earlier interrupted. No problem for us.
  114. }
  115. }
  116. /**
  117. * constructor that configures and shows the GUI window. It contains two text inputs for name and
  118. * email address and three buttons BACK, ADD and FORWARD. For each button own inner classes are
  119. * defined as {@link ActionListener}: {@link BackAction}, {@link ForwardAction }, {@link AddAction
  120. * }, which all three call the {@link #doWait()} method, which simulates a slow database. Thus, it
  121. * will have an effect to move the code of the ActionListeners to extra Threads in order to keep
  122. * the GUI responsive.
  123. *
  124. * @see Runnable
  125. * @see Thread
  126. * @see ActionListener
  127. *
  128. */
  129. public MainGui() {
  130. // dummy data to "database"
  131. DBEntry e1 = new DBEntry();
  132. e1.name = "Max Muster";
  133. e1.email = "max.muster@hs-fulda.de";
  134. DBEntry e2 = new DBEntry();
  135. e2.name = "Jane Doe";
  136. e2.email = "jane.doe@somewhere.com";
  137. this.database.add(e1);
  138. this.database.add(e2);
  139. // setup the GUI
  140. this.frame = new JFrame("SimpleDB");
  141. this.frame.setContentPane(this.cp);
  142. this.cp.setLayout(new BoxLayout(this.cp, BoxLayout.Y_AXIS));
  143. this.topPanel.add(new JLabel("Name"));
  144. this.topPanel.add(this.tfName);
  145. this.middlePanel.add(new JLabel("E-Mail-Adresse"));
  146. this.middlePanel.add(this.tfMail);
  147. this.cp.add(this.topPanel);
  148. this.cp.add(this.middlePanel);
  149. this.bottomPanel.add(this.btBack);
  150. this.bottomPanel.add(this.btAdd);
  151. this.bottomPanel.add(this.btForward);
  152. this.cp.add(this.bottomPanel);
  153. // set menu
  154. JMenuBar jmb = new JMenuBar();
  155. JMenu menu = new JMenu("Datei");
  156. this.frame.setJMenuBar(jmb);
  157. jmb.add(menu);
  158. menu.add(menuNew);
  159. menu.addSeparator();
  160. menu.add(menuEnd);
  161. // register all ActionListeners to GUI components
  162. this.btBack.addActionListener(new BackAction());
  163. this.btForward.addActionListener(new ForwardAction());
  164. ActionListener actionAdd = new AddAction();
  165. this.btAdd.addActionListener(actionAdd);
  166. this.menuNew.addActionListener(actionAdd);
  167. menuEnd.addActionListener(new EndAction());
  168. // initially show current db fields (of index 0)
  169. DBEntry entry = getEntryFromDB(index);
  170. tfName.setText(entry.name);
  171. tfMail.setText(entry.email);
  172. this.frame.setSize(800, 200);
  173. this.frame.setVisible(true);
  174. }
  175. /**
  176. * a simple main which only creates an instance of {@link MainGui}.
  177. *
  178. * @param args cmd line arguments (ignored)
  179. */
  180. public static void main(String[] args) {
  181. new MainGui();
  182. }
  183. }