Java, держи глобальный сеанс базы данных в свинг-приложении - PullRequest
2 голосов
/ 22 марта 2012

Хорошо. У меня есть мэйнфрейм, который содержит два контейнера. Одна содержит мои кнопки-мастера, а другая - панель содержимого. У меня есть несколько классов Window1, Window2 и т. Д., Которые я создаю в своем классе мэйнфреймов, а затем переключаюсь через cardLayout, который решает, какой класс Window должен быть видим в contentPane.

Каждый из этих классов Window требует подключения к базе данных. В настоящее время я инстанцирую соединение с базой данных в классах окна по отдельности, но я хочу некоторую форму глобальной сессии, где я подключаюсь с момента, когда я передал свой класс Window1 (также известный как класс входа в систему), пока я не закрою приложение, что, когда я доберусь до других классов Window, я смогу читать и записывать в базу данных, используя этот сеанс.

Мой класс MainFrame:

public class MainFrame {
private static void createAndShowGUI() {
    JFrame frame = new JFrame("Stackoverflowquestion");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLocationRelativeTo(null);

    final JPanel contentPane = new JPanel();
    contentPane.setLayout(new CardLayout(5, 5));

    Database db = new Database();
    //Trying to make some kind of global database instance but fails

    Window1 win1 = new Window1();
    contentPane.add(win1);
    Window2 win2 = new Window2();
    contentPane.add(win2);
    Window3 win3 = new Window3();
    contentPane.add(win3);
    Window4 win4 = new Window4();
    contentPane.add(win4);
    Window5 win5 = new Window5();
    contentPane.add(win5);
    Window6 win6 = new Window6();
    contentPane.add(win6);

    JPanel buttonPanel = new JPanel(); 
    final JButton previousButton = new JButton("< PREVIOUS");
    previousButton.setEnabled(false);
    final JButton nextButton = new JButton("NEXT >");
    final JButton cancelButton = new JButton("CANCEL");
    buttonPanel.add(cancelButton);
    buttonPanel.add(previousButton);
    buttonPanel.add(nextButton);            

    nextButton.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent ae) {
            nextButton.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
            Verifiable verifiable = null;
            Component[] contents = contentPane.getComponents();
            for(Component component : contents) {
                if(component.isVisible() && component instanceof Verifiable) {
                    verifiable = (Verifiable)component;
                }
            }
            if(verifiable != null && verifiable.isDataValid()) {
                CardLayout cardLayout = (CardLayout) contentPane.getLayout();
                cardLayout.next(contentPane); 
                previousButton.setEnabled(true);
                nextButton.setCursor(Cursor.getDefaultCursor()); 

            }
        }
    });

    cancelButton.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent ae) {
            System.exit(0);
              //Should close the database session
        }

    });

    frame.add(contentPane);
    frame.add(buttonPanel, BorderLayout.PAGE_END);
    frame.setSize(400, 400);
    frame.setVisible(true);
}
    public static void main(String[] args) {

        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
} 

Пример класса Window:

public class Window1 extends JPanel implements Verifiable {

public static final String IDENTIFIER = "FIRST";

JTextField txtUsername = new JTextField();
JPasswordField txtPassword = new JPasswordField();

Database db = new Database();
     //As I said, I currently intantiate a database connection separetely which
     //I want to get rid of 
public Window1() {
    init();
}

private void init() {
    JLabel lblUsername = new JLabel("Username:", JLabel.CENTER);
    lblUsername.setBounds(10, 91, 135, 77);
    txtUsername = new JTextField();
    txtUsername.setBounds(155, 116, 188, 27);

    JLabel lblPassword = new JLabel("Password:", JLabel.CENTER);
    lblPassword.setBounds(0, 163, 149, 77);
    txtPassword = new JPasswordField();
    txtPassword.setBounds(155, 188, 188, 27);
    setLayout(null);

    add(lblUsername);
    add(txtUsername);
    add(lblPassword);
    add(txtPassword);
    String title = "Log in";
    setBorder(BorderFactory.createTitledBorder(title));
}

@Override
public boolean isDataValid() {
    String username = new String(txtUsername.getText());
    String password = new String(txtPassword.getPassword());

    try {
        DatabaseConnection conn = db.getDatabaseConnection(username, password, "test", "test", "test");
        db.getTest(conn);
        return true;
        } catch (LoginFailedException e) {
            JOptionPane.showMessageDialog(this, "Something went wrong", 
                    "Error", JOptionPane.ERROR_MESSAGE);
            return false;
    }
}

@Override
public String getIdentifier() {
    return IDENTIFIER;
}

}

1 Ответ

2 голосов
/ 22 марта 2012

Я бы использовал шаблон синглтона.Это в основном позволяет вам иметь один экземпляр объекта, и вы можете получить его где угодно.Узнайте больше здесь: http://en.wikipedia.org/wiki/Singleton_pattern

В моем примере ниже у вас может быть соединение с базой данных, которое вы будете использовать для создания любых обращений к базе данных, которые вы хотите.Я делаю то же самое в проекте, над которым я сейчас работаю.Это прекрасно работает:)

Вот пример:

public class DatabaseConnection {

  private static DatabaseConnection instance; //note this is static

  private DatabaseConnection() { //note this is private
  }

  public static DatabaseConnection getInstance() { //note this is static
    if (instance == null) {
      instance = new DatabaseConnection();
    }
    return instance;
  }

Вы также можете попробовать то, что Википедия называет традиционным способом (увидев это, я думаю, что именно так я и сделаю это сейчасвключено).

public class DatabaseConnection {
  private static final DatabaseConnection instance = new DatabaseConnection();

  // Private constructor prevents instantiation from other classes
  private DatabaseConnection() { }

  public static DatabaseConnection getInstance() {
    return instance;
  }
}
...