관리 메뉴

nalaolla

Creating a JDBC GUI Application 본문

JAVA/99. ETC

Creating a JDBC GUI Application

날아올라↗↗ 2015. 12. 8. 23:04
728x90

Creating a JDBC GUI Application

Java in its core is inherently a GUI language, rich in more than one graphical user interface, such as AWT, Swing, JavaFX, QtJambi, SWT, and so forth. It presents a user-friendly mechanism for application interaction, giving a distinctive look and feel. Although they have different architectural cores, they do not fail to provide applications with consistent, intuitive user interface components. JDBC programming is really hard to realize without a GUI interface. These frameworks are suitable for creating database-oriented desktop applications. Swing is good but JavaFX is better and QtJambi is the best (IMHO); SWT is quite powerful, and yet I never liked it. Here we shall try to create a simple CRUD application with Swing, JavaFX, QtJambi, and SWT to get a taste of GUI from the perspective of a JDBC programmer.



Creating a Table

Because we shall be creating a database application, let's create a table with the following SQL DDL in MySQL.

CREATE TABLE Person(
   personId int (30) NOT NULL,
   firstName varchar (30) NOT NULL,
   middleName varchar (30) NOT NULL,
   lastName varchar (30) NOT NULL,
   email varchar (30) NOT NULL,
   phone varchar (30) NOT NULL,
   PRIMARY KEY (personId)
);

Listing 1: SQL DDL for creating a Person table in MySQL


JDBC Programming

Create a entity class that will act as a persistent object. This class is a POJO, used for convenience as a reference entity object while interacting with the controller bean from GUI classes.

public class Person {
   private int personId;
   private String firstName;
   private String middleName;
   private String lastName;
   private String email;
   private String phone;
   //...constructors, getters, and setters
}

Listing 2: Entity class, Person.java

The controller bean PersonBean is the heart of our JDBC application. Every communication with the database is accomplished through this controller. Also, here we have used JdbcRowSet to access all information to and from the graphical interface from the database. These two classes (Listing 1 andListing 2) will be same for every GUI framework used down the line.

public class PersonBean {
   static final String JDBC_DRIVER =
      "com.mysql.jdbc.Driver";
   static final String DB_URL =
      "jdbc:mysql://localhost:3306/mydatabase";
   static final String DB_USER = "user1";
   static final String DB_PASS = "secret";
   private JdbcRowSet rowSet = null;
   public PersonBean() {
      try {
         Class.forName(JDBC_DRIVER);
         rowSet = new JdbcRowSetImpl();
         rowSet.setUrl(DB_URL);
         rowSet.setUsername(DB_USER);
         rowSet.setPassword(DB_PASS);
         rowSet.setCommand("SELECT * FROM Person");
         rowSet.execute();

      catch (SQLException | ClassNotFoundException ex) {
         ex.printStackTrace();
      }
   }
   public Person create(Person p) {
      try {
         rowSet.moveToInsertRow();
         rowSet.updateInt("personId", p.getPersonId());
         rowSet.updateString("firstName", p.getFirstName());
         rowSet.updateString("middleName", p.getMiddleName());
         rowSet.updateString("lastName", p.getLastName());
         rowSet.updateString("email", p.getEmail());
         rowSet.updateString("phone", p.getPhone());
         rowSet.insertRow();
         rowSet.moveToCurrentRow();
      } catch (SQLException ex) {
         try {
            rowSet.rollback();
            p = null;
         } catch (SQLException e) {

         }
         ex.printStackTrace();
      }
      return p;
   }

   public Person update(Person p) {
      try {
         rowSet.updateString("firstName", p.getFirstName());
         rowSet.updateString("middleName", p.getMiddleName());
         rowSet.updateString("lastName", p.getLastName());
         rowSet.updateString("email", p.getEmail());
         rowSet.updateString("phone", p.getPhone());
         rowSet.updateRow();
         rowSet.moveToCurrentRow();
      } catch (SQLException ex) {
         try {
            rowSet.rollback();
         } catch (SQLException e) {

         }
         ex.printStackTrace();
      }
      return p;
   }

   public void delete() {
      try {
         rowSet.moveToCurrentRow();
         rowSet.deleteRow();
      } catch (SQLException ex) {
         try {
            rowSet.rollback();
         } catch (SQLException e) { }
         ex.printStackTrace();
      }

   }

   public Person moveFirst() {
      Person p = new Person();
      try {
         rowSet.first();
         p.setPersonId(rowSet.getInt("personId"));
         p.setFirstName(rowSet.getString("firstName"));
         p.setMiddleName(rowSet.getString("middleName"));
         p.setLastName(rowSet.getString("lastName"));
         p.setEmail(rowSet.getString("email"));
         p.setPhone(rowSet.getString("phone"));

      } catch (SQLException ex) {
         ex.printStackTrace();
      }
      return p;
   }

   public Person moveLast() {
      Person p = new Person();
      try {
         rowSet.last();
         p.setPersonId(rowSet.getInt("personId"));
         p.setFirstName(rowSet.getString("firstName"));
         p.setMiddleName(rowSet.getString("middleName"));
         p.setLastName(rowSet.getString("lastName"));
         p.setEmail(rowSet.getString("email"));
         p.setPhone(rowSet.getString("phone"));

      } catch (SQLException ex) {
         ex.printStackTrace();
      }
      return p;
   }

   public Person moveNext() {
      Person p = new Person();
      try {
         if (rowSet.next() == false)
            rowSet.previous();
         p.setPersonId(rowSet.getInt("personId"));
         p.setFirstName(rowSet.getString("firstName"));
         p.setMiddleName(rowSet.getString("middleName"));
         p.setLastName(rowSet.getString("lastName"));
         p.setEmail(rowSet.getString("email"));
         p.setPhone(rowSet.getString("phone"));

      } catch (SQLException ex) {
         ex.printStackTrace();
      }
      return p;
   }

   public Person movePrevious() {
      Person p = new Person();
      try {
         if (rowSet.previous() == false)
            rowSet.next();
         p.setPersonId(rowSet.getInt("personId"));
         p.setFirstName(rowSet.getString("firstName"));
         p.setMiddleName(rowSet.getString("middleName"));
         p.setLastName(rowSet.getString("lastName"));
         p.setEmail(rowSet.getString("email"));
         p.setPhone(rowSet.getString("phone"));

      } catch (SQLException ex) {
         ex.printStackTrace();
      }
      return p;
   }

   public Person getCurrent() {
      Person p = new Person();
      try {
         rowSet.moveToCurrentRow();
         p.setPersonId(rowSet.getInt("personId"));
         p.setFirstName(rowSet.getString("firstName"));
         p.setMiddleName(rowSet.getString("middleName"));
         p.setLastName(rowSet.getString("lastName"));
         p.setEmail(rowSet.getString("email"));
         p.setPhone(rowSet.getString("phone"));
      } catch (SQLException ex) {
         ex.printStackTrace();
      }
      return p;
   }
}

Listing 3: Controller class, PersonBean.java

GUI Front-end with Swing

AWT (Abstract Window Toolkit) relied on the runtime platform's native GUI components. After it rose from the drawback of AWT, Swing went through major improvement by creating its own components. This approach solved the problem of portability, which is the primary reason for the demise of AWT. Swing became the de facto GUI framework by being part of the larger family of Java products called the Java Foundation Class (JFC). Over a decade from its nativity, Swing components are seasoned, consistent, and reliable for creating any GUI application in Java. Swing is the default choice when working with any GUI-based application in Java.

public class PersonUI extends JPanel {

   private JTextField idField = new JTextField(10);
   private JTextField fNameField = new JTextField(30);

   //... mNameField, lNameField, emailField, phoneField

   private JButton createButton = new Jbutton("New...");
   //... updateButton, deleteButton, firstButton, prevButton, nextButton,
   //...lastButton
   private PersonBean bean = new PersonBean();

   public PersonUI() {
      setBorder(new TitledBorder
      (new EtchedBorder(),"Person Details"));
      setLayout(new BorderLayout(5, 5));
      add(initFields(), BorderLayout.NORTH);
      add(initButtons(), BorderLayout.CENTER);
      setFieldData(bean.moveFirst());
   }

   private JPanel initButtons() {
      JPanel panel = new JPanel();
      panel.setLayout(new FlowLayout(FlowLayout.CENTER, 3, 3));
      panel.add(createButton);
      createButton.addActionListener(new ButtonHandler());
      //...
      panel.add(lastButton);
      lastButton.addActionListener(new ButtonHandler());
      return panel;
   }

   private JPanel initFields() {
      JPanel panel = new JPanel();
      panel.setLayout(new MigLayout());
      panel.add(new JLabel("ID"), "align label");
      panel.add(idField, "wrap");
      idField.setEnabled(false);
      panel.add(new JLabel("First Name"), "align label");
      panel.add(fNameField, "wrap");
      //...
      panel.add(new JLabel("Phone"), "align label");
      panel.add(phoneField, "wrap");
      return panel;
   }

   private Person getFieldData() {
      Person p = new Person();
      p.setPersonId(Integer.parseInt(idField.getText()));
      p.setFirstName(fNameField.getText());
      p.setMiddleName(mNameField.getText());
      p.setLastName(lNameField.getText());
      p.setEmail(emailField.getText());
      p.setPhone(phoneField.getText());
      return p;
   }

   private void setFieldData(Person p) {
      idField.setText(String.valueOf(p.getPersonId()));
      fNameField.setText(p.getFirstName());
      mNameField.setText(p.getMiddleName());
      lNameField.setText(p.getLastName());
      emailField.setText(p.getEmail());
      phoneField.setText(p.getPhone());
   }

   private boolean isEmptyFieldData() {
      return (fNameField.getText().trim().isEmpty()
         && mNameField.getText().trim().isEmpty()
         && lNameField.getText().trim().isEmpty()
         && emailField.getText().trim().isEmpty()
         && phoneField.getText().trim().isEmpty());
   }

   private class ButtonHandler implements ActionListener {
      @Override
      public void actionPerformed(ActionEvent e) {
         Person p = getFieldData();
         switch (e.getActionCommand()) {
         case "Save":
            if (isEmptyFieldData()) {
               JOptionPane.showMessageDialog(null,
               "Cannot create an empty record");
               return;
            }
            if (bean.create(p) != null)
               JOptionPane.showMessageDialog(null,
               "New person created successfully.");
               createButton.setText("New...");
               break;
         case "New...":
            p.setPersonId(new Random()
            .nextInt(Integer.MAX_VALUE) + 1);
            p.setFirstName("");
            p.setMiddleName("");
            p.setLastName("");
            p.setEmail("");
            p.setPhone("");
            setFieldData(p);
            createButton.setText("Save");
            break;
         case "Update":
            if (isEmptyFieldData()) {
               JOptionPane.showMessageDialog(null,
               "Cannot update an empty record");
               return;
            }
            if (bean.update(p) != null)
               JOptionPane.showMessageDialog(
               null,"Person with ID:" + String.valueOf(p.getPersonId()
               + " is updated successfully"));
               break;
         case "Delete":
            if (isEmptyFieldData()) {
               JOptionPane.showMessageDialog(null,
               "Cannot delete an empty record");
               return;
            }
            p = bean.getCurrent();
            bean.delete();
            JOptionPane.showMessageDialog(
               null,"Person with ID:"
               + String.valueOf(p.getPersonId()
               + " is deleted successfully"));
               break;
         case "First":
            setFieldData(bean.moveFirst()); break;
         case "Previous":
            setFieldData(bean.movePrevious()); break;
         case "Next":
            setFieldData(bean.moveNext()); break;
         case "Last":
            setFieldData(bean.moveLast()); break;
         default:
            JOptionPane.showMessageDialog(null,
            "invalid command");
         }
      }
   }
}

Listing 4: Swing framework as a JDBC front-end

public class AppMain {
   public static void main(String[] args) {
      JFrame f=new JFrame();
      f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      f.getContentPane().setLayout(new FlowLayout(FlowLayout.CENTER));
      f.getContentPane().add(new PersonUI());
      f.setSize(600, 280);
      f.setVisible(true);
   }
}

Listing 5: Swing Application main class

JDBC1
Figure 1: Swing JDBC Application

GUI Front-end with JavaFX

JavaFX is the prodigal (if not pampered) child of Java's next generation GUI toolkit for developers who want to rapidly build rich cross-platform applications. The Swing library is massive and can be customized very efficiently. This is good as well as irritating at times. Creating a simple design may require one to set too many parameters. JavaFX is targeted for building a GUI application in a simpler, more intuitive way. But, there is a lack of many ready to use and frequently required GUI components in the library. However, in its prime stage, the ease of programming phenomenon of JavaFX seems promising. Some say it will replace Swing in the near future. Swing programmers have the proclivity for JavaFX, however; it will take time to catch up with the reliability of Swing GUI components.

public class PersonUI extends BorderPane {
   private Label msgLabel = new Label();
   private TextField idField = new TextField();
   //... mNameField, lNameField, emailField, phoneField

   private Button createButton = new Button("New...");
   //... updateButton, deleteButton, firstButton, prevButton,
   //... nextButton, lastButton

   private PersonBean bean = new PersonBean();

   public personUI() {
      setPadding(new Insets(10, 10, 10, 10));
      setTop(msgLabel);
      setCenter(initFields());
      setBottom(initButtons());
      setFieldData(bean.moveFirst());
   }

   private Pane initButtons() {
      HBox box = new HBox();
      box.setAlignment(Pos.CENTER);
      box.setSpacing(5);
      box.getChildren().add(createButton);
      createButton.setOnAction(new ButtonHandler());
      box.getChildren().add(updateButton);
      //...
      box.getChildren().add(lastButton);
      lastButton.setOnAction(new ButtonHandler());
      return box;
   }

   private Pane initFields() {
      GridPane grid = new GridPane();
      grid.setAlignment(Pos.CENTER);
      grid.setPadding(new Insets(10, 10, 10, 10));
      grid.setHgap(20);
      grid.setVgap(2);
      grid.add(new Label("ID"), 1, 0);
      grid.add(idField, 2, 0);
      idField.setEditable(false);
      grid.add(new Label("First Name"), 1, 1);
      grid.add(fNameField, 2, 1);
      //...
      return grid;
   }

   private Person getFieldData() {
      Person p = new Person();
      p.setPersonId(Integer.parseInt(idField.getText()));
      //...
      return p;
   }

   private void setFieldData(Person p) {
      idField.setText(String.valueOf(p.getPersonId()));
      //...
   }

   private boolean isEmptyFieldData() {
      //...
   }

   private class ButtonHandler implements EventHandler<ActionEvent> {
      @Override
      public void handle(ActionEvent e) {
         Person p = getFieldData();
         if (e.getSource().equals(createButton)
         && createButton.getText().equals("Save")) {
            if (isEmptyFieldData()) {
               msgLabel.setText("Cannot create an empty record");
               return;
            }
            if (bean.create(p) != null)
               msgLabel.setText("New person created successfully.");
            createButton.setText("New...");
         } else if (e.getSource().equals(createButton)
            && createButton.getText().equals("New...")) {
            p.setPersonId(new Random().nextInt(Integer.MAX_VALUE) + 1);
            p.setFirstName("");
            //...
            setFieldData(p);
            createButton.setText("Save");
         } else if (e.getSource().equals(updateButton)) {
            if (isEmptyFieldData()) {
            msgLabel.setText("Cannot update an empty record");
            return;
         }
         if (bean.update(p) != null)
            msgLabel.setText("Person with ID:"
            + String.valueOf(p.getPersonId()
            + " is updated successfully"));
         } else if (e.getSource().equals(deleteButton)) {

            if (isEmptyFieldData()) {
               msgLabel.setText("Cannot delete an empty record");
               return;
            }
            p = bean.getCurrent();
            bean.delete();
            msgLabel.setText("Person with ID:"
            + String.valueOf(p.getPersonId()
            + " is deleted successfully"));
         } else if (e.getSource().equals(firstButton)) {
            setFieldData(bean.moveFirst());
         } else if (e.getSource().equals(prevButton)) {
            setFieldData(bean.movePrevious());
         } else if (e.getSource().equals(nextButton)) {
            setFieldData(bean.moveNext());
         } else if (e.getSource().equals(lastButton)) {
            setFieldData(bean.moveLast());
         }
      }
   }
}

Listng 6: JavaFX framework as JDBC front-end

public class AppMain extends Application {
   public static void main(String[] args) {
      Application.launch(args);
   }
   @Override
   public void start(Stage stage) throws Exception {
      stage.setScene(new Scene(new PersonUI(), 600, 280));
      stage.show();
   }
}

Listing 7: JavaFX application main class

JDBC2
Figure 2: JavaFX JDBC Application

GUI Front-end with QtJambi

Some frameworks die hard; QtJambi is one of a kind. It is the easiest and best of all Java GUI frameworks for desktop application development. If you like Swing and JavaFX, you'll simply love QtJambi. The architecture inherits the Qt GUI framework for C++. You can build a graphical interface within no time, efficiently. When compared with other frameworks, one of the best part is in creating layouts. They are simply the best and easiest where other frameworks toddle; Swing is the worst. A deviation from Swing is that it uses "signals and slots" for delegating events whereas Swing uses a listener pattern. Unfortunately, the QtJambi community does not seem very active. It is really hard to see this framework not getting much attention form the Java community to thrive upon.

public class PersonUI extends QWidget {

   private QLineEdit idField = new QLineEdit();
   //... mNameField, lNameField, emailField, phoneField

   private QPushButton createButton = new QPushButton("New...");
   //... updateButton, deleteButton, firstButton, prevButton, 
   //... nextButton,lastButton
   private PersonBean bean = new PersonBean();
   public PersonUI() {
      QVBoxLayout vlayout = new QVBoxLayout();
      vlayout.addLayout(initFields());
      vlayout.addLayout(initButtons());
      setFieldData(bean.moveFirst());
      setLayout(vlayout);
   }

   private QHBoxLayout initButtons() {
      QHBoxLayout hlayout = new QHBoxLayout();
      hlayout.addWidget(createButton);
      createButton.clicked.connect(this, "createAction()");
      hlayout.addWidget(updateButton);
      //...
      lastButton.clicked.connect(this, "moveLastAction()");
      return hlayout;
   }

   private QFormLayout initFields() {
      QFormLayout form = new QFormLayout();
      form.addRow("ID", idField);
      idField.setReadOnly(true);
      form.addRow("First Name", fNameField);
      //...
      form.addRow("Phone", phoneField);
      return form;
   }

   private Person getFieldData() {
      Person p = new Person();
      //...
      return p;
   }

   private void setFieldData(Person p) {
      idField.setText(String.valueOf(p.getPersonId()));
      //...
   }

   private boolean isEmptyFieldData() {
      //...
   }

   private void createAction() {
      Person p = getFieldData();
      switch (createButton.text()) {
      case "Save":
         if (isEmptyFieldData()) {
            QMessageBox.critical(this, "Invalid data",
            "Cannot create an empty record");
            return;
         }
         if (bean.create(p) != null)
            QMessageBox.information(this, "Create Successful",
            "New person created successfully.");
            createButton.setText("New...");
            break;
      case "New...":
         p.setPersonId(new Random().nextInt(Integer.MAX_VALUE) + 1);
         p.setFirstName("");
         //...
         setFieldData(p);
         createButton.setText("Save");
         break;
      }
   }

   private void updateAction() {
      Person p = getFieldData();
      if (isEmptyFieldData()) {
         QMessageBox.critical(this, "Invalid data",
         "Cannot update an empty record");
         return;
      }
      if (bean.update(p) != null)
         QMessageBox.information(this,
         "Update Successful","Person with ID:"
         + String.valueOf(p.getPersonId()
         + " is updated successfully"));
   }

   private void deleteAction() {
      Person p = getFieldData();
      if (isEmptyFieldData()) {
         QMessageBox.critical(this, "Invalid data",
         "Cannot delete an empty record");
         return;
      }
      p = bean.getCurrent();
      bean.delete();
      QMessageBox.information(this, "Delete Successful",
      "Person with ID:"+ String.valueOf(p.getPersonId()
      + " is deleted successfully"));
   }

   private void moveFirstAction() {
      setFieldData(bean.moveFirst());
   }

   private void movePreviousAction() {
      setFieldData(bean.movePrevious());
   }

   private void moveNextAction() {
      setFieldData(bean.moveNext());
   }

   private void moveLastAction() {
      setFieldData(bean.moveLast());
   }
}

Listing 8: QtJambi framework as a JDBC front-end

public class AppMain {
   public static void main(String[] args) {
      QApplication.initialize(args);
      QWidget w=new PersonUI();
      w.show();
      QApplication.exec();
   }
}

Listing 9: QtJambi application main class

JDBC3
Figure 3: QtJambi JDBC Application

Creating a Database GUI with SWT

SWT(Standard Widget Toolkit) with JFace is a versatile, robust GUI development library. The Eclipse IDE is built upon SWT. This framework allayed the complexity of Swing and uses heavyweight components from the underlying platform to boost speed and native appearance. Communication with the operating system is performed with JNI (Java Native Interface). Although Swing components have the advantage of being lightweight and, in doing so, it reinvented the wheel, thus degrading performance. SWT is best suited for performance but not as intuitive a QtJambi.

public class PersonUI extends Composite {
   private Shell shell=this.getShell();

   private Text idField;
   //... mNameField, lNameField, emailField, phoneField

   private Button createButton;
   //... updateButton, deleteButton, firstButton,
   //... prevButton, nextButton, lastButton

   private PersonBean bean = new PersonBean();

   public PersonUI(Composite parent, int style) {
      super(parent, style);
      setLayout(new FillLayout(SWT.VERTICAL));
      initFields(this, SWT.NONE);
      initButtons(this, SWT.NONE);
      setFieldData(bean.moveFirst());

   }

   private Button createButton(Composite c, String caption, int style) {
      Button b = new Button(c, style);
      b.setText(caption);
      return b;
   }

   private void initButtons(Composite parent, int style) {
      Composite c = new Composite(parent, style);
      c.setLayout(new RowLayout(SWT.HORIZONTAL));
      createButton = createButton(c, "New...", SWT.PUSH);
      createButton.addSelectionListener(new ButtonHandler());
      //...
   }

   private void initFields(Composite parent, int style) {
      Composite c = new Composite(parent, style);
      GridLayout grid = new GridLayout(2, false);
      c.setLayout(grid);
      new Label(c, SWT.NONE).setText("ID");
      idField = new Text(c, SWT.BORDER);
      idField.setEditable(false);
      new Label(c, SWT.NONE).setText("First Name");
      fNameField = new Text(c, SWT.BORDER);
      //...
   }

   private Person getFieldData() {
      Person p = new Person();
      //...
      return p;
   }

   private void setFieldData(Person p) {
      //...
   }

   private boolean isEmptyFieldData() {
      //...
   }

   private class ButtonHandler extends SelectionAdapter {

      public void widgetSelected(SelectionEvent e) {
         Person p = getFieldData();
         if (e.getSource().equals(createButton)
         && createButton.getText().equals("Save")) {
            if (isEmptyFieldData()) {
               new MessageBox(shell, SWT.OK)
               .setText("Cannot create an empty record");
               return;
            }
         if (bean.create(p) != null)
            new MessageBox(shell, SWT.OK)
            .setText("New person created successfully.");
            createButton.setText("New...");
         } else if (e.getSource().equals(createButton)
            && createButton.getText().equals("New...")) {
            p.setPersonId(new Random()
            .nextInt(Integer.MAX_VALUE) + 1);
            //...
            setFieldData(p);
            createButton.setText("Save");
         } else if (e.getSource().equals(updateButton)) {
               if (isEmptyFieldData()) {
               new MessageBox(shell, SWT.OK)
               .setText("Cannot update an empty record");
               return;
            }
            if (bean.update(p) != null)
               new MessageBox(shell, SWT.OK)
               .setText("Person with ID:"
               + String.valueOf(p.getPersonId()
               + " is updated successfully"));

         } else if (e.getSource().equals(deleteButton)) {
            if (isEmptyFieldData()) {
               new MessageBox(shell, SWT.OK)
               .setText("Cannot delete an empty record");
               return;
            }
            p = bean.getCurrent();
            bean.delete();
            new MessageBox(shell, SWT.OK)
            .setText("Person with ID:"
            + String.valueOf(p.getPersonId()
            + " is deleted successfully"));

         } else if (e.getSource().equals(firstButton)) {
            setFieldData(bean.moveFirst());
         } else if (e.getSource().equals(prevButton)) {
            setFieldData(bean.movePrevious());
         } else if (e.getSource().equals(nextButton)) {
            setFieldData(bean.moveNext());
         } else if (e.getSource().equals(lastButton)) {
            setFieldData(bean.moveLast());
         }
      }
   }
}

Listing 10: SWT framework as a JDBC front-end

public class AppMain {
   public static void main(String[] args) {
      Display display = new Display();
      Shell shell = new Shell(display);
      shell.setLayout(new RowLayout(SWT.VERTICAL));
      shell.setSize(600, 280);
      new PersonUI(shell, SWT.BORDER);
      shell.pack();
      shell.open();
      while (!shell.isDisposed()) {
         if (!display.readAndDispatch())
            display.sleep();
      }
      display.dispose();
   }
}

Listing 11: SWT Application main class

JDBC4
Figure 4: SWT JDBC Application

Conclusion

These four frameworks are the stalwarts of Java GUI application in the desktop arena. There are advantages and disadvantages in all the sides. If you look for consistent look and feel Swing would be the obvious choice. JavaFX can be another choice. If you look for robustness, SWT reigns supreme. QtJambi though natively rendered like SWT, it provides a happy balance of simplicity, intuitiveness and performance as well.


728x90