Java netbeans How to pass value to jComboBox - java

How to pass value from one class to jcombobox in another class
Public void getItem (){
try {
dBconnection...
while(rs.next){
String customers = rs.getString (1);
this.jcombobox1.addItem (customers);
}
}
}
From this method to jcombobox in another class. The error is in jcombobox?

Since you are already having B's class object in A lets say ex Bclassobj.
Public void getItem (){
try {
while(rs.next){
this.jcombobox1.addItem (rs.getString (1));
Bclassobj.Bclassjcombobox.addItem (rs.getString (1));
}
}
}

Generally this is a poor way of coding, no offense.
You should not mix the code for:
Getting the connection to database
Executing some SQL command and fetching data from ResultSet
Creating graphics
Simply change your method Public void getItem () to Public List<String> getCustomers(). This method's business should be just fetching the data from database, and returning the list of Customer's names as List<String>.
Then in your another class, simply call this method and set the whole List<String> as the model of your JComboBox.
See the example below:
public class AnotherClass extends JFrame{
private JComboBox<String> jComboBox;
public AnotherClass() {
init();
}
private void init(){
//... other components
DBClass db = new DBClass();
List<String> customers = db.getCustomers();
jComboBox = new JComboBox<>(customers.toArray(new String[]{}));
this.add(jComboBox);
//... other components
}
}
class DBClass{
public List<String> getCustomers (){
List<String> customers = new ArrayList<>();
try{
//dBconnection...
ResultSet rs = null;// your code for getting ResultSet
while(rs.next()){
String customer = rs.getString (1);
customers.add(customer);
}
}catch(SQLException e){
e.printStackTrace();
}
return customers;
}
}
Good Luck.

Related

How do I call variables from a Java class in another Class

If I have a class with prepared statements, how do I call them when a user presses a button.
class updateeButtonHandler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
name = displayName.getText();
price = bookPrice.getText();
Queries update = new Queries();???????????????????
}
}
Prepared Statement in different class
public int update(String price, String name) throws SQLException {
ps2.setString(1, name);
ps2.setString(2, price);
System.out.print("Update - ");
return ps2.executeUpdate();
}
Create an object and invoke the update method with parameters as shown below:
public void actionPerformed(ActionEvent e) {
name = displayName.getText();
price = bookPrice.getText();
Queries update = new Queries();
update.update(price, name);//invoke the method using the object
}

OOP inheritence, parents variable value not updated on child

this is simple login handler, i never have problem like this when put it on same class. then i try to put it on child class and i don't know what happening.
this is the GUI class
final static Functions.F_Koneksi F_K = new Functions.F_Koneksi();
final static Functions.F_Process F_P = new Functions.F_Process();
final static GUIController F_GUI = new GUIController();
protected javax.swing.JPasswordField jPasswordFieldPasswordLoginPane;
protected javax.swing.JTextField jTextFieldUsernameLoginPane;
...
private void jButtonLoginLoginPaneActionPerformed(java.awt.event.ActionEvent evt) {
switch (F_GUI.DoLogin()) {
case 1:
cl.show(MainPane, "BuyMovie");
break;
...
default:
LoginLabel.setText("username or password ... ");
}
}
and this is the GUIController class
int DoLogin(){
try {
System.err.println(jTextFieldUsernameLoginPane.getText());
char[] PassChars = jPasswordFieldPasswordLoginPane.getPassword();
String Pass = new String(PassChars);
return F_P.F_Login(jTextFieldUsernameLoginPane.getText(), Pass);
} catch (SQLException ex) {
LoginLabel.setText("connection error");
}
return 3;
}
and this is the F_Login method on F_Process
public int F_Login(String User, String Pass) throws SQLException {
ResultSet RS = Select("select * from blablabla"); //this query work already
int level = 8;
if (RS.next()) {
level = RS.getInt("Level");
}
return level;
}
the problem is when i set user and password textfield with right user pass its work but when user put it its not. i know something wrong with my OOP logic but i don't understand where. thank you
this is picture to make you understand what i mean
http://i.stack.imgur.com/1DsrF.png
http://i.stack.imgur.com/uXmGZ.png
Maybe its because the GUIController doesn't access the same jPasswordFieldPasswordLoginPane that the other gui access, to do it, you must pass the object to the GUIController class, like pass the reference in the constructor or setter method, and in the GUIController you access the correct jPasswordFieldPasswordLoginPane.

Java SwingWorker load data from database to List

I have a problem with my MVC application that displays data in a JTable. Everything worked fine, but I decided to add a SwingWorker to retrieve data from the database.
My controller calls the model with data from the database. It looks like this.
Model.java
public class Model {
private List<Category> people = new Vector<Category>();
public List<Category> getPeople() {
return new ArrayList<Category>(people);
}
public void load() throws Exception {
people.clear();
DAOFactory factory = DAOFactory.getFactory(DAOFactory.MYSQL);
CategoryDAO personDAO = factory.getCategoryDAO();
people.addAll(personDAO.getCategory());
}
}
I add SwingWorker to getCategory class
MySQLCategodyDAO.java
public class MySQLCategoryDAO extends SwingWorker<Void, Vector<Object>> implements CategoryDAO{
private Job job;
private List<Category> cat;
public MySQLCategoryDAO(Job job){
this.job = job;
}
#Override
protected Void doInBackground() throws Exception {
// TODO Auto-generated method stub
if(job == Job.SELECT){
getCategory();
System.out.println("Table selected");
}
return null;
}
#Override()
public void done(){
}
public List<Category> getCategory() throws SQLException
{
cat = new ArrayList<Category>();
Connection conn = Database.getInstance().getConnection();
System.out.println(conn);
String sql = "select id, name from kategorie";
Statement selectStatement = conn.createStatement();
ResultSet results = selectStatement.executeQuery(sql);
while(results.next())
{
int id = results.getInt("id");
String name = results.getString("name");
Category category = new Category(id, name);
cat.add(category);
}
results.close();
selectStatement.close();
return cat;
}
}
View just retrieves the data from the model:
people = model.getPeople();
for (Category person : people) {
tablemodel
.addRow(new Object[] { person.getId(), person.getName() });
}
The problem comes when you call SwingWorker in class Model.java
public void load() throws Exception {
people.clear();
DAOFactory factory = DAOFactory.getFactory(DAOFactory.MYSQL);
CategoryDAO personDAO = factory.getCategoryDAO();
people.addAll(new MySQLCategoryDAO(Job.SELECT).execute()); - ERROR
}
Error:-
The method addAll(Collection<? extends Category>) in the type List<Category> is not applicable for the
arguments (void)
I know SwingWorker returns nothing, because there is an error. I should write the code in the method done(), but I have no idea how to solve it.
execute does not have a return value so it can't be used in the way you are trying to use it. The idea of SwingWorker is that the task should be executed asynchronously so you need to rework your design.
The SwingWorker bears a result (the List<Category>) and you either need to:
put the result somewhere from inside the SwingWorker (such as with the publish mechanism)
or call get from the outside to wait for the task to finish and return.
Here is the tutorial for review: http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html
Quick example:
class MySQLCategoryDAO extends SwingWorker<Void, Category> {
// ...
private List<Category> list; // do not modify inside doInBackground
MySQLCategoryDAO(Job job, List<Category> list) {
this.list = list;
// ...
}
#Override
protected Void doInBackground() {
// ...
while(results.next()) {
int id = results.getInt("id");
String name = results.getString("name");
publish(new Category(id, name)); // publish results to the EDT
}
// ...
return null;
}
#Override
protected void process(List<Category> chunks) {
list.addAll(chunks); // add results to the list on the EDT
// add to the JTable (?)
}
}
public void load() throws Exception {
people.clear();
DAOFactory factory = DAOFactory.getFactory(DAOFactory.MYSQL);
CategoryDAO personDAO = factory.getCategoryDAO();
// just execute
new MySQLCategoryDAO(Job.SELECT, people).execute();
}
If you want to populate the entire table at once then you can also publish a List after the loop instead of one Category at a time. process would receive a List<List<Category>> with a singular element.
Sorry my mistake.
From the view gets to model.getPeople (), but nothing is returned. I did a test:
But nothing is returned
public class Model {
private List<Category> people = new Vector<Category>();
public List<Category> getPeople() {
for (Category person : people) {
System.out.println(person.getName()); //no data
}
return new ArrayList<Category>(people);
}
public void load() throws Exception {
people.clear();
DAOFactory factory = DAOFactory.getFactory(DAOFactory.MYSQL);
new MySQLCategoryDAO(Job.SELECT,people).execute();
}
}

Java Data-Entity model: Constructing general types

I have had some trouble with using a general type in a static method.
All comments on the source code are welcome, especially ones that significantly improve the code. I am also currently not planning on using any external framework, apart from JDBC, to keep it still simple, please do not put too much emphasis on that.
My view on not using external frameworks is also supported by the fact that the operations I will be using on the database are very minimal:
Inserting data
Updating data
Retrieving all fields. (And simply by putting in a different SQL Query you could already select what fields to retrieve
I do not plan on making a full framework, so I know that it will not be supporting everything. The speed of retrieving all fields is neither a real issue, as this will be pretty much only done on server bootup, and if used at any other time it will be done in a background task for which I do not really care when it is finished.
Entity.java:
abstract public class Entity<KeyType, DataType> {
protected KeyType key;
protected List<Object> data;
public Entity() {
data = new ArrayList<>();
}
//abstract public static Map<KeyType, DataType> getAll();
protected List<Object> createData(final DataAction dataAction) {
List<Object> list = new ArrayList<>();
if (dataAction == DataAction.INSERT) {
list.add(key);
}
list.addAll(data);
if (dataAction == DataAction.UPDATE) {
list.add(key);
}
return list;
}
abstract public void insert();
abstract public void update();
protected static <KeyType, DataType> Map<KeyType, DataType> getData(final Class<DataType> dataTypeClass, final String query) {
Map<KeyType, DataType> map = new HashMap<>();
try {
PreparedStatement preparedStatement = DatabaseConnection.getConnection().prepareStatement(query);
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
KeyType key = (KeyType)resultSet.getObject(1);
int index = 2;
List<Object> dataList = new ArrayList<>();
while (resultSet.getObject(index) != null) {
dataList.add(resultSet.getObject(index));
index++;
}
DataType dataObject = null;
try {
dataObject = dataTypeClass.getConstructor(List.class).newInstance(dataList);
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException ex) {
Logger.getLogger(Entity.class.getName()).log(Level.SEVERE, null, ex);
}
map.put(key, dataObject);
}
} catch (SQLException ex) {
Logger.getLogger(Entity.class.getName()).log(Level.SEVERE, null, ex);
}
return map;
}
protected void executeQuery(final String query, final List<Object> data) {
try {
PreparedStatement preparedStatement = DatabaseConnection.getConnection().prepareStatement(query);
int dataIndex = 0;
for (Object dataObject : data) {
preparedStatement.setObject(dataIndex, dataObject);
dataIndex++;
}
preparedStatement.execute();
preparedStatement.close();
} catch (SQLException ex) {
Logger.getLogger(Entity.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
A concrete implementation, Account.java:
public class Account extends Entity<String, Account> {
private final static String SELECT_ALL_QUERY = "SELECT * FROM accounts";
private final static String INSERT_QUERY = "INSERT INTO accounts (username, password) VALUES(?, ?)";
private final static String UPDATE_QUERY = "UPDATE accounts SET password=? WHERE username=?";
private String username;
private String password;
public Account(final String username, final String password) {
this.username = username;
this.password = password;
key = username;
data.add(password);
}
public Account(final List<Object> data) {
this((String)data.get(0), (String)data.get(1));
}
public String getUsername() {
return username;
}
public void setUsername(final String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(final String password) {
this.password = password;
}
public static Map<String, Account> selectAll() {
return getData(Account.class, SELECT_ALL_QUERY);
}
#Override
public void insert() {
executeQuery(INSERT_QUERY, createData(DataAction.INSERT));
}
#Override
public void update() {
executeQuery(UPDATE_QUERY, createData(DataAction.UPDATE));
}
}
I am generally happy about the concrete implementation, it seems like I have managed to bring it down to a bare minimum, except public Account(final List<Object> data) does not seem that nice, but I can live with it.
However, as guessed, the getData() from Entity is definately not nice, and I would like to improve it if possible.
What I would like to use is something like DataType dataObject = new DataType(dataList), but it seems like Generic Type Arguments cannot be instantiated.
So are there any ways of optimizing my current code in my current view? And is it possible to decouple the concrete classes and abstract classes even more?
EDIT:
Added a relevant question (I don't think I should make a fully new question for this thing, right?):
Is there a way to move the static Strings (SQL Queries) and the insert() and update() out of the Account class, into the Entity class?
To avoid the use of reflection in your getData method you should accept a factory that given a ResultSet creates instances of the specific type. Your selectAll method would then be something like:
public static Map<String, Account> selectAll()
{
return getData(
new EntityFactory<Account>()
{
public Account newInstance(ResultSet resultSet) throws SQLException
{
return new Account(resultSet.getString(0), resultSet.getString(1));
}
},
SELECT_ALL_QUERY
);
}
The getData method then ends up something like:
protected static <K, T extends Entity<K>> Map<K, T> getData(EntityFactory<T> entityFactory, String query)
{
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try
{
connection = dataSource.getConnection();
preparedStatement = connection.prepareStatement(query);
resultSet = preparedStatement.executeQuery();
Map<K, T> entities = new HashMap<>();
while (resultSet.next())
{
Entity<K> entity = entityFactory.newInstance(resultSet);
entities.put(entity.getKey(), entity);
}
return entities;
}
finally
{
closeQuietly(resultSet);
closeQuietly(prepareStatement);
closeQuietly(connection);
}
}
And assumes the Entity looks like:
public interface Entity<K>
{
public K getKey();
}
This allows you to remove the reflection and keeps the code that understands the database structure in one place. You should also use a similar template pattern to map from the domain object to the prepared statement when doing inserts and updates.
Now you've asked for comments on the code in general.
First off, code like this violates the Single Responsibility Principal and Seperation Of Concerns. A domain class should be a domain class and not contain persistance logic. Look at patterns like the Data Access Object for how this should be done.
Second, while I'm all for keeping it simple, Hibernate solved this problem a long time ago and JPA standardized it - you need a very good reason not to use one or both of these APIs.
Finally, your use of database resources - if you are going to use JDBC directly you have to clean up properly. Database connections are expensive resources and should be handled as such, the basic template for any JDBC call should be:
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try
{
connection = //get connection from pool or single instance.
preparedStatement = connection.prepareStatement("SELECT * FROM table WHERE column = ?");
preparedStatement.setString(1, "some string");
resultSet = preparedStatement.executeQuery();
while (resultSet.next())
{
//logic goes here.
}
}
catch (SQLException e)
{
//Handle exceptions.
}
finally
{
closeQuietly(resultSet);
closeQuietly(prepareStatement);
closeQuietly(connection);
}
The closeQuietly method has to be overloaded but should take the general form:
try
{
if (resultSet != null)
{
resultSet.close();
}
}
catch (SQLException e)
{
//Log exceptions but don't re-throw.
}
Well, as Darwind and Nick Holt told you, in a normal situation, you should use JPA, which is the Java standard specification for object-relational mapping. You can use Hibernate, EclipseLink or any other framework behind. Their design is can manage connections, transactions. In addition, using standards rather than exotic frameworks means that you can get help more easily for the community.
Another option is using Spring JDBC, which is quite light and facilitates many things.
Anyway, I suppose you did this for learning purpose so let's try to go further.
First, I think you should separate the classes in charge or retrieving the data (call it manager or Data Access Object -DAO-) and the entites representing the data themselves.
For me, using the class to get all the data as you did isn't a problem in itself. The problem is the position of the key is hardcoded. This should not be determined directly a generic (I mean the same for all the Entity implementation). This makes queries subjects to bugs when the first field is not the key (are you sure a select * from... will ALWAYS return the key in the first position? ) or with a composite key.
I think a better solution is to crate a Mapper interface and to implement it for each entity.
public interface RecordMapper<KeyType, DataType extends Entity> {
public void appendToMap(ResultSet resultSet, Map<KeyType, DataType>) throws SQLException;
}
The implementation of the mapper should be in charge of instanciating your entity, retrieving the key from the resultset, populating your entity and putting it in the map you expect.
public class AccountMapper implement RecordMapper<String, Account>{
public void appendToMap(ResultSet resultSet, Map<String, Account> accounts) throws SQLException {
String user= resultSet.getString("userName");
String pwd= resultSet.getString("passWord");
Account account = new Account(user, pwd);
accounts.put(user, account);
}
}
As I told you should move your data access methods in a DAO:
public class DAO{
public <KeyType, DataType> Map<KeyType, DataType> getData(final RecordMapper<KeyType, DataType> mapper, final String query) {
Map<KeyType, DataType> map = new HashMap<>();
try {
PreparedStatement preparedStatement = DatabaseConnection.getConnection().prepareStatement(query);
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
mapper.appendToMap(resultSet, map);
}
} catch (SQLException ex) {
Logger.getLogger(Entity.class.getName()).log(Level.SEVERE, null, ex);
} finally {
if(resultSet != null){
try{resultSet.close();} catch (Exception e){}
}
if(preparedStatement!= null){
try{preparedStatement.close();} catch (Exception e){}
}
}
return map;
}
public void executeQuery(final String query, final List<Object> data) {
try {
PreparedStatement preparedStatement = DatabaseConnection.getConnection().prepareStatement(query);
int dataIndex = 0;
for (Object dataObject : data) {
preparedStatement.setObject(dataIndex, dataObject);
dataIndex++;
}
preparedStatement.execute();
} catch (SQLException ex) {
Logger.getLogger(Entity.class.getName()).log(Level.SEVERE, null, ex);
} finally {
if(resultSet != null){
try{resultSet.close();} catch (Exception e){}
}
if(preparedStatement!= null){
try{preparedStatement.close();} catch (Exception e){}
}
}
}
}
To answer your second quenstion, I think that putting your request string in the abstract parent instead of is certainly not a good idea. Each time you create new entity, you have to create a new query in the parent. Weird...unless I haven't understood properly your question.
Personnaly I think that the queries should be build dynamically and you should use reflection and annotations but the answer should be a bit long. Once again, you can get a look at JPA to see how creating an entity should look like. By the way, it should be even better if the entities didn't have to extend a parent Entity class.

I'm Using Camick's ListTableModel and RowTableModel, NO DATA IN JTABLE

I am trying to use the ListTableModel and tried following some examples online and still finding it difficult to show 'resultSet' data in my Jtable. Im using the model-view-controller method building a GUI application in netbeans. All of my GUI components are placed in views and the controller is handling any updates as well visibility to this view. The model class has all the queries and is responsible for accessing the database directly using JDBC.
The "Jtable" "searchTable" is created and initialized inside the view class and is being accessed by my controller via a method (getSearchTable()).
public JTable getSearchTable(){
// view class
return searchTable;
}
I have the "ListTableModel" being created inside the controller class and following Camick's tutorial.
private Product_View productView;
private Product_Model productModel;
private Product product;
public Product_Controller(Product_Model model, Product_View view){
this.productModel = model;
this.productView = view;
view.addSaveListener(new SaveListener());
view.addCloseListener(new CloseListener());
view.addSearchSingleListener(new SearchListener());
}
public void displayProductView(){
this.productView.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
this.productView.setVisible(true);
} class SearchListener implements ActionListener {
public SearchListener() {
}
#Override
public void actionPerformed(ActionEvent ae) {
ListTableModel model = null;
String prodName = productView.getProductName();
JTable tempTable = productView.getSearchTable();
model = productModel.getProduct(prodName, model);
tempTable = new JTable(model);
}
}
Finally the method "getProduct" is inside the model class and being called by my controller class.
public ListTableModel getProduct(String productName, ListTableModel model){
String query = "SELECT * FROM Products WHERE name='" + productName + "';";
Statement stmt;
try {
stmt = this.conn.createStatement();
stmt.executeQuery (query);
ResultSet rs = stmt.getResultSet();
writeResultSet(rs);
model = ListTableModel.createModelFromResultSet(rs);
rs.close ();
stmt.close ();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return model;
}
The Jtable does not return anything, how can i view my ResultSet data (i have printed out the values being returned by "writeResultSet" to the console and so the query is working correctly?
Creating a table doesn't add the table to the GUI. Somewhere in your code you need code like:
frame.add( table );
If you are updating an existing table then you don't create a new table all you do is:
table.setModel(...);
after recreating the model.
Edit:
To test your SQL create a simple SSCCE with code something like:
ListTableModel model = ListTableModel.createModelFromResultSet( resultSet );
JTable table = new JTable( model );
frame.add( new JScrollPane( table ) );
frame.setSize(...);
frame.setVisible( true );

Categories

Resources