This is my first post in this group. I don't know if the attached files are
allowed, so I put the code following.
That problem is in the TLoginPanel.getUserId()! When I call it at the first
time (from the "main" thread) it goes fine.
But when the call is from the JMenuItem it runs at the Event-dispath thread,
in this case the method getUserId() deadLocks (in the wait() call). Why do
it's (getUserId()) called before the GUI is shown and the action is
performed? Why do I have to do to prevent this???
--- TIndex.java ---
import com.gc.systray.*;
import com.nitromidia.db.mysql;
import java.util.*;
import org.w3c.dom.*;
import java.io.File;
import java.io.IOException;
import login.TLoginPanel;
import systray.TSysTrayIcon;
import javax.swing.JPopupMenu;
import javax.swing.JMenuItem;
import java.awt.event.*;
public class TIndex {
// Configurações da classe
private static mysql db;
private TLoginPanel fLogin;
private Integer fUserId;
// Construtor
public TIndex() {
loadSysTray();
db = new mysql("127.0.0.1","root","","intranet");
db.connect();
showLogin();
}
public void showLogin() {
System.out.println("TIndex.showLogin(): "+
Thread.currentThread().getName());
if (fLogin == null) {
fLogin = new TLoginPanel(db);
fUserId = fLogin.getUserId();
} else {
javax.swing.SwingUtilities.invokeLater(new Runnable () {
public void run() {
System.out.println("TIndex.showLogin().<anonymous>Runnable().run(): "+
Thread.currentThread().getName());
fLogin.fLoginThread = new Thread(fLogin,"login");
fLogin.fLoginThread.start(); // Why do this two lines
isn't synchronized?
fUserId = fLogin.getUserId(); // If I uncomment this
line I get the deadLock
}
});
//fLogin.fLoginThread.start();
}
if (fUserId == null) {
fUserId = new Integer(-1);
}
System.out.println("login passed");
System.out.println("User ID: "+ fUserId.intValue());
}
// Ínicio a partir da linha de comando
public static void main(String[] args) {
//javax.swing.SwingUtilities.invokeLater(new Runnable () {
//public void run() {
new TIndex();
//}
//});
}
private void loadSysTray() {
// Carrega a DLL
if (!SystemTrayIconManager.initializeSystemDependent()) {
System.out.println("Failed to run systray icon.");
System.exit(1);
}
// Carrega o Ícone
int quick = SystemTrayIconManager.loadImage("./inc/icone.bmp");
if (quick == -1) {
System.out.println("Failed to run systray icon (image error).");
return;
}
// Instancia a classe
final SystemTrayIconManager mgr = new SystemTrayIconManager(quick,
"Intranet Nitromidia");
// Configura a classe
mgr.addSystemTrayIconListener(new TSysTrayIcon());
mgr.setLeftClickView(fLogin);
mgr.setVisible(true);
// Adiciona o Menu
JPopupMenu fSysMenu = new JPopupMenu();
JMenuItem fLoginItem = new JMenuItem();
JMenuItem fLogoutItem = new JMenuItem();
fLoginItem.setText("Login");
fSysMenu.add(fLoginItem);
fLogoutItem.setText("Logout");
fSysMenu.add(fLogoutItem);
ActionListener theLoginList = new ActionListener() {
public void actionPerformed(ActionEvent e) {
showLogin();
}
};
fLoginItem.addActionListener(theLoginList);
mgr.setRightClickView(fSysMenu);
}
}
--- TLoginPanel.java ---
package login;
import com.nitromidia.db.mysql;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.border.BevelBorder;
import javax.swing.border.CompoundBorder;
import java.awt.event.*;
import java.awt.*;
import java.util.*;
public class TLoginPanel extends JFrame implements Runnable {
public Thread fLoginThread;
private mysql db;
private JPanel fPanel;
private Integer fUserId;
private JTextField fLoginField;
private JPasswordField fPassField;
private JButton fLoginButton;
private final int fWindowWidth = 200;
private final int fWindowHeight = 130;
public TLoginPanel (mysql theDb) {
super("Login");
this.db = theDb;
fLoginThread = new Thread(this,"login");
fLoginThread.start();
//draw();
}
public void draw() {
if (fPanel == null) {
fPanel = (JPanel) getContentPane();
setBorder();
buildForm();
setSize(fWindowWidth,fWindowHeight);
Dimension theScreenSize =
Toolkit.getDefaultToolkit().getScreenSize();
setLocation(new Point((int)
(theScreenSize.getWidth()/2)-(fWindowWidth/2),(int)
(theScreenSize.getHeight()/2)-(fWindowHeight/2)));
setVisible(true);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
setVisible(false);
unlock();
}
});
} else {
setVisible(true);
}
}
public void run() {
this.draw();
}
public synchronized Integer getUserId() {
System.out.println("getUserId(): "+
Thread.currentThread().getName());
try {
wait();
} catch (InterruptedException e) {
System.err.println("erro");
}
return fUserId;
}
public void buildForm() {
GridBagLayout gridbag = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
fPanel.setLayout(gridbag);
c.fill = GridBagConstraints.HORIZONTAL;
JLabel theLoginLabel = new JLabel("Login: ");
c.gridx = 0;
c.gridy = 0;
gridbag.setConstraints(theLoginLabel, c);
fPanel.add(theLoginLabel);
fLoginField = new JTextField();
fLoginField.setPreferredSize(new Dimension(100,20));
c.gridx = 1;
c.gridy = 0;
gridbag.setConstraints(fLoginField,c);
fPanel.add(fLoginField);
JLabel thePassLabel = new JLabel("Senha: ");
c.gridx = 0;
c.gridy = 1;
gridbag.setConstraints(thePassLabel,c);
fPanel.add(thePassLabel);
fPassField = new JPasswordField();
fPassField.setPreferredSize(new Dimension(100,20));
c.gridx = 1;
c.gridy = 1;
gridbag.setConstraints(fPassField,c);
fPanel.add(fPassField);
fLoginButton = new JButton("Login");
fLoginButton.setPreferredSize(new Dimension(100,20));
c.gridx = 0;
c.gridy = 2;
c.gridwidth = GridBagConstraints.REMAINDER;
gridbag.setConstraints(fLoginButton,c);
fPanel.add(fLoginButton);
TLoginListener theActionListener = new TLoginListener(this);
fLoginButton.addActionListener(theActionListener);
}
public void setBorder() {
EmptyBorder eb = new EmptyBorder(3,3,3,3);
BevelBorder bb = new BevelBorder(BevelBorder.LOWERED);
CompoundBorder cb = new CompoundBorder(eb,bb);
fPanel.setBorder(cb);
System.out.println("login.");
}
public synchronized void unlock() {
notifyAll();
}
class TLoginListener implements ActionListener {
private TLoginPanel fLoginPanel;
public TLoginListener(TLoginPanel theLogin) {
fLoginPanel = theLogin;
}
public void actionPerformed(ActionEvent e) {
TDoLogin theLoginThread = new TDoLogin(db,fLoginPanel);
new Thread(theLoginThread).start();
}
}
class TDoLogin implements Runnable {
private mysql db;
private TLoginPanel fParent;
public TDoLogin(mysql db,TLoginPanel theParent) {
this.fParent = theParent;
this.db = db;
}
public void run() {
String stmt = "select id\n from usuario\n where login = '"
+ fLoginField.getText() +"'\n and BINARY senha
= '"
+ new String(fPassField.getPassword()) +"'";
db.query(stmt);
Hashtable rs = db.nextRecord();
if (rs == null || rs.size() == 0) {
JOptionPane theAlert = new JOptionPane("Login");
theAlert.showMessageDialog(fParent,"Falha na
autenticação");
} else {
fLoginField.setEditable(false);
fPassField.setEditable(false);
fLoginButton.setEnabled(false);
fParent.setVisible(false);
fUserId = new Integer((String) rs.get("id"));
System.out.println("TDoLogin.run(): "+
Thread.currentThread().getName());
unlock();
}
}
}
}