I am stuck here and see only one solution which I am trying to refrain from because, it will make my code look messy. I have a JComboBox.addPopupMenuListener in one class. I have another class which implements addPopupMenuListener. In the other class, I extract the items from DB and store them in a List.
I am completely clueless now on how do I add items from this List to JComboBox. Any ideas?
Problem - although I have declared JComboBox combobox; as public I am unable to use this combobox in the implementing class. What do I do? Below is the Code -
package tg.com.bugtracker.loginpage;
import java.awt.*;
import javax.swing.*;
public class LoginPanel extends JPanel {
public JComboBox<String> combobox;
public LoginPanel() {
GridBagLayout layout = new GridBagLayout();
setLayout(layout);
GridBagConstraints constraints = new GridBagConstraints();
constraints.gridx = 1;
constraints.gridy = 0;
constraints.insets = new Insets(10,10,10,10);
constraints.anchor = GridBagConstraints.LINE_START;
combobox = new JComboBox<>();
combobox.setPreferredSize(new Dimension(250, 20));
combobox.addPopupMenuListener(new loginNames());
add(combobox, constraints);
}
}
Implementing Class -
package tg.com.bugtracker.loginpage;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import java.sql.*;
import java.util.List;
public class loginNames implements PopupMenuListener{
@Override
public void popupMenuCanceled(PopupMenuEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent arg0) {
// TODO Auto-generated method stub
}
public List<String> loginNames;
@Override
public void popupMenuWillBecomeVisible(PopupMenuEvent arg0) {
String URL = "jdbc:ucanaccess://C:\\Users\\bharat.nanwani\\Desktop\\BugTrackerDB.accdb";
ResultSet rs;
PreparedStatement p;
String sqlquery = "SELECT FirstName FROM UserDetails;";
try {
Connection cnn = DriverManager.getConnection(URL);
p = cnn.prepareStatement(sqlquery);
rs = p.executeQuery();
rs.close();
p.close();
while (rs.next()) {
String names = rs.getString("FirstName");
loginNames.add(names);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
You cannot use combobox
in class loginNames
because combobox
is a member of the LoginPanel
class. I'm not sure if you've learned the details of classes and object though, so I will give you two possible fixes and then explain them.
Here are two fixes:
1) Change the declaration
public JComboBox<String> combobox
to
public static JComboBox<String> combobox
.
Then use LoginPanel.combobox
to access the combobox in the loginNames
class.
2) Add the following constructor to loginNames
:
private LoginPanel login;
public loginNames( LoginPanel login ) {
this.login = login;
}
Then, you can access the combobox in loginNames
class by typing this.login.combobox
.
A basic concept of classes and objects is that you use classes as a template to create objects. LoginPanel
is a class and you create LoginPanel
objects with the code new LoginPanel()
. Every object (i.e. instance of LoginPanel
) will have some variables and methods associated with it. For example, in your not-working code, every LoginPanel
object has a unique JComboBox<String>
variable named combobox
associated.
The reason why you cannot access combobox
from listNames
is that listNames
does not know what LoginPanel
object you are talking about. It knows there is a LoginPanel
class, but there can exist 2 or more LoginPanel
objects at any given time and those LoginPanel
objects will all have different combobox
es.
In the first fix provided, we added the static
keyword to combobox
. What static
does is that it tells the computer that instead of having a different combobox
for each LoginPanel
object, we're just going to have one global combobox
that all LoginPanel
objects will share. More specifically, combobox
becomes associated with the LoginPanel
class and it is no longer associated with LoginPanel
objects. If you do this, there can only be one combobox
so you are able to refer to that in the listNames
class with the code LoginPanel.combobox
.
For the second fix, recall that we cannot just access combobox
from the listNames
class because there is a different combobox
associated with every LoginPanel
object (and more than 1 LoginPanel
object may exist). In the second fix, we directly address this problem by passing a reference in the constructor to the specific LoginPanel
object we're talking about. By passing this reference, we specify that login
is the LoginPanel
object we want to modify and it has a unique combobox
that we're going to add our list elements to. Therefore, you are able to type login.combobox
to access combobox
.
Both fixes are not what would ideally be used. As others have mentioned, Java Swing follows the Model-View-Controller pattern, and so, it is expected that your applications using Java Swing will also use this pattern. The ComboBoxModel
class would allow you to achieve this pattern. Adding a static
keyword won't give you the Model-View-Controller pattern.
I looked at your code, and since you didn't fully following Java naming conventions, I figured you might be a bit new to Java and possibly object-oriented programming. Since you may not want to spend a lot of time learning how ComboBoxModel
works and changing all your code to follow the Model-View-Controller pattern, I've offered what I hope is a quick alternative that is easier to explain conceptually and will get you the functionality you want.