Swing GUI Client Listeners not responding to update of Remote RMI Property - swing

I am having some trouble with getting a JTree to redraw when an explicit call is made to its model (a call which I make once I have added some new nodes to it).
The code, which initially worked fine, fails now that the application is exported to RMI.
I store the DefaultTreeModel object in the Controller class, which is a Remote Object.
I add the DefaultTreeModel object to the JTree in my Client, using tree.addModel(controller.getModel());
I use an ActionListener subscribed to a button on the Client GUI to call a method in the Controller which performs the "Add new node" action.
I use a TreeModelListener to print a message to screen to prove that the Model Listener has fired.
Do Client side Swing listeners not work over RMI?
I have managed to reproduce the problem. I include the code for completeness but anticipate that someone will be able to reel off the answer based on experience.
Server Driver Class:
package server;
import java.io.IOException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import client.controller.TestTreeControllerService;
import server.controller.TestTreeControllerImpl;
public class TestTreeServerStart {
/**
* #param args
*/
public static void main(String[] args) {
new TestTreeServerStart();
}
public TestTreeServerStart() {
try {
LocateRegistry.createRegistry(1099);
TestTreeControllerService c = new TestTreeControllerImpl();
Registry registry = LocateRegistry.getRegistry();
registry.rebind("TestTreeControllerService", c);
System.out.println("Started the RMI Server");
}
catch (RemoteException e) {
System.out.println(e.getMessage());
}
}
}
Server Controller Implementation Class:
package server.controller;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import client.controller.TestTreeControllerService;
#SuppressWarnings("serial")
public class TestTreeControllerImpl extends UnicastRemoteObject implements TestTreeControllerService {
/**
*
*/
//private static final long serialVersionUID = -8137864611400855504L;
private DefaultTreeModel m ;
public DefaultTreeModel getModel() {
return m;
}
public TestTreeControllerImpl() throws RemoteException {
super();
m = new DefaultTreeModel(new DefaultMutableTreeNode("Root"));
}
public void addNodeAction() throws RemoteException {
DefaultTreeModel m = (DefaultTreeModel) getModel();
DefaultMutableTreeNode newNode = new DefaultMutableTreeNode("New Node");
DefaultMutableTreeNode root = (DefaultMutableTreeNode) m.getRoot();
root.add(newNode);
//m.insertNodeInto(newNode, (DefaultMutableTreeNode) m.getRoot(), m.getChildCount(m.getRoot()));
m.nodeStructureChanged(root);
}
}
Client Driver Class:
package client;
import java.rmi.Naming;
import java.rmi.RemoteException;
import client.controller.TestTreeControllerService;
import client.view.TreeTestClient;
public class TreeTestClientStart {
/**
* #param args
*/
public static void main(String[] args) {
try {
TestTreeControllerService c = (TestTreeControllerService) Naming.lookup("rmi://localhost:1099/TestTreeControllerService");
new TreeTestClient(c);
}
catch(RemoteException e) {
System.out.println("Remote service not found: " + e.getLocalizedMessage());
}
catch (Exception e) {
System.out.println("Splat");
}
}
}
Client Controller Interface:
package client.controller;
import javax.swing.tree.DefaultTreeModel;
public interface TestTreeControllerService extends java.rmi.Remote {
public DefaultTreeModel getModel() throws java.rmi.RemoteException;
public void addNodeAction() throws java.rmi.RemoteException;
}
Client UI:
package client.view;
import java.awt.Dimension;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import client.controller.TestTreeControllerService;
import client.view.action.AddNodeAction;
import client.view.action.RefreshTreeAction;
public class TreeTestClient {
private JTree t;
private TestTreeControllerService c;
public JTree getTree() {
return t;
}
public TestTreeControllerService getController() {
return c;
}
public void setTree(JTree tIn) {
t = tIn;
}
public TreeTestClient(TestTreeControllerService cIn) {
//Add controller
try {
c = cIn;
//Draw Frame & Panel - set dimensions
JFrame f = new JFrame();
f.setSize(new Dimension(800,600));
JPanel p = new JPanel();
p.setSize(new Dimension(800,600));
//Create a tree and add the Model from the Controller to it
t = new JTree();
t.setModel(c.getModel());
//Try a Tree Model Listener
t.getModel().addTreeModelListener(new RefreshTreeAction(this));
//Add listener to a button which adds nodes to the tree when clicked
JButton addNode = new JButton("Add node");
addNode.addActionListener(new AddNodeAction(this));
JScrollPane s = new JScrollPane(t);
p.add(s);
p.add(addNode);
p.setVisible(true);
f.add(p);
f.setVisible(true);
}
catch(Exception e) {
System.out.println("Splat");
}
}
}
*Client "Add Node" Action Listener (invokes Add Action in Controller) *
package client.view.action;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.rmi.RemoteException;
import javax.swing.table.DefaultTableModel;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import client.view.TreeTestClient;
public class AddNodeAction implements ActionListener {
private TreeTestClient treeTest;
public AddNodeAction(TreeTestClient treeTestIn) {
treeTest=treeTestIn;
}
#Override
public void actionPerformed(ActionEvent arg0) {
try {
treeTest.getController().addNodeAction();
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Client "Refresh Action" Tree Listener (Prints to Screen to prove that Listener fired)
package client.view.action;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import client.view.TreeTestClient;
public class RefreshTreeAction implements PropertyChangeListener, TreeModelListener {
private TreeTestClient treeTest;
public RefreshTreeAction(TreeTestClient treeTestIn) {
treeTest = treeTestIn;
}
private void refreshTree() {
System.out.println("Refresh tree fired");
}
#Override
public void treeNodesChanged(TreeModelEvent arg0) {
refreshTree();
}
#Override
public void treeNodesInserted(TreeModelEvent arg0) {
refreshTree();
}
#Override
public void treeNodesRemoved(TreeModelEvent arg0) {
refreshTree();
}
#Override
public void treeStructureChanged(TreeModelEvent arg0) {
refreshTree();
}
#Override
public void propertyChange(PropertyChangeEvent arg0) {
refreshTree();
}
}

The TreeModel exported by the server is serialized to the client as the client's own copy. The server doesn't know anything about what happens to the client's copy, and the client doesn't know anything about what happens to the server's copy. They are not the same object.

By adding the following code to an ActionListener subscribed to a new button on the GUI, I have been able to examine the contents of the Model at the click of a button:
//Loop contents of model attached to Client Tree
for (int i=0; i<t.getModel().getChildCount(t.getModel().getRoot()); i++) {
System.out.println("From Tree: Row #" + i + ": " + t.getModel().getChild(t.getModel().getRoot(), i));
}
//Loop contents of model object stored in Controller
try {
for (int i=0; i<c.getModel().getChildCount(c.getModel().getRoot()); i++) {
System.out.println("From Controller: Row #" + i + ": " + c.getModel().getChild(c.getModel().getRoot(), i));
}
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
I found that the reference to the Client's Model was a different version to the state being maintained in the Controller's model object. There was no output in the Client loop, but the Controller's loop gave the correct state.
I have subsequently added a Swing Timer to the GUI to refresh the tree's model to match that of the Constructor. An updated GUI Class and GUI Refresh Action follow, which work:
Updated UI:
package client.view;
import java.awt.Dimension;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.Timer;
import client.controller.TestTreeControllerService;
import client.view.action.AddNodeAction;
import client.view.action.GUIRefreshAction;
import client.view.action.RefreshTreeAction;
public class TreeTestClient {
private JTree t;
private TestTreeControllerService c;
public JTree getTree() {
return t;
}
public TestTreeControllerService getController() {
return c;
}
public void setTree(JTree tIn) {
t = tIn;
}
public TreeTestClient(TestTreeControllerService cIn) {
//Add controller
try {
c = cIn;
//Draw Frame & Panel - set dimensions
JFrame f = new JFrame();
f.setSize(new Dimension(800,600));
JPanel p = new JPanel();
p.setSize(new Dimension(800,600));
//Create a tree and add the Model from the Controller to it
t = new JTree();
t.setModel(c.getModel());
//Try a listener that doesn't use the Remote object
t.addTreeSelectionListener(new RefreshTreeAction(this));
//Try a property change listener on the TreeModel
t.addPropertyChangeListener("treeModel", new RefreshTreeAction(this));
//Try a Tree Model Listener
t.getModel().addTreeModelListener(new RefreshTreeAction(this));
//Add listener to a button which adds nodes to the tree when clicked
JButton addNode = new JButton("Add node");
addNode.addActionListener(new AddNodeAction(this));
JScrollPane s = new JScrollPane(t);
//Add a GUI redraw timer
Timer timer = new Timer(1000, new GUIRefreshAction(this));
timer.setInitialDelay(1);
timer.start();
p.add(s);
p.add(addNode);
p.setVisible(true);
f.add(p);
f.setVisible(true);
}
catch(Exception e) {
System.out.println("Splat");
}
}
}
GUI Refresh Listener Class
package client.view.action;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.rmi.RemoteException;
import client.view.TreeTestClient;
public class GUIRefreshAction implements ActionListener {
private TreeTestClient client;
public GUIRefreshAction(TreeTestClient clientIn) {
client = clientIn;
}
#Override
public void actionPerformed(ActionEvent e) {
//Update the Tree's Model to match latest on Server
try {
client.getTree().setModel(client.getController().getModel());
} catch (RemoteException e1) {
e1.printStackTrace();
}
}
}
I hope this helps someone who has the same requirements for a RMI Client Swing GUI to update in reaction to changes on the Server.

Related

Moving JavaFX Nodes Between Stages

I'm rewriting a Swing application in JavaFX, where I allow users to present multiple workspaces as either windows or tabs. However, my FX code will not display the contents moved from more than one tab into a new stage; only the contents of the currently-selected tab appear in my new stages. I've distilled my code into a small example below. Can anyone clue me in as to what's gone wrong?
package scenes;
import java.util.ArrayList;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class StageSwapper extends Application {
static public void main(String[] args) {
launch(args);
}
private TabPane tabs = new TabPane();
public void start(Stage stage) {
stage.setTitle("Stage Swapper");
BorderPane p = new BorderPane();
p.setCenter(tabs);
tabs.getTabs().addAll(new Swapee("First").createTab(), new Swapee("Second").createTab());
Scene s = new Scene(p);
stage.setScene(s);
stage.show();
launchSwap();
}
private void launchSwap() {
new Thread() {
public void run() {
try {
sleep(10000);
} catch (Exception e) {
e.printStackTrace();
}
Platform.runLater(new Runnable() {
public void run() {
for (Swapee s : Swapee.list) {
createWindow(s);
}
}
});
}
}.start();
}
public void createWindow(Swapee s) {
Stage window = new Stage();
window.setTitle("New Window");
window.setY(200);
window.setX(200);
BorderPane p = new BorderPane();
p.setCenter(s);
window.setScene(new Scene(p));
window.show();
}
}
class Swapee extends Label {
static private int count;
static ArrayList<Swapee> list = new ArrayList<>();
String name;
Swapee(String name) {
super("Swappable Item " + ++count);
this.name = name;
list.add(this);
}
Tab createTab() {
Tab t = new Tab(name);
t.setContent(this);
return t;
}
}
You haven't specified the size of the windows that you're creating. Right now they have width and length equal to 0. You may use the following approach:
BorderPane p = new BorderPane();
p.setPrefSize(Region.USE_COMPUTED_SIZE, Region.USE_COMPUTED_SIZE);
p.setCenter(s);
BorderPane will be resized according to its content and the window will be resized as well.

Updating Layout of Panel after changing label icon

I have created a project that will download the thumbnails of the images from a ftp server and display it in a panel using JLabel.
The images are being displayed but the layout of the panel only works if i call the panel once more (i.e using a button on the frame) then the layout corrects itself automatically. What am i doing wrong? Here is the code
EDIT- Updated the code with sscce
1. sscce.java
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
/**
*
* #author Rohn
*/
public class Sscce implements Interface{
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
JFrame frame=new JFrame();
frame.setVisible(true);
//frame.add(sci.);
Container c=frame.getContentPane();
JButton button=new JButton("Recall ShowCategoryImagesFunction");
button.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
sci.ShowCategoryImagesFunction("\\Nature\\Black And White"); //for testing purpose only
// if button is pressed then we get right layout and image load
}
});
c.setLayout(new FlowLayout());
c.add(button);
c.add(sci.ShowCategoryImagesFunction("\\Nature\\Black And White")); // default path for image load for first time
// problem in correctly loading images and text with layout
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
2. ShowCategoryImages.java
package sscce;
import it.sauronsoftware.ftp4j.FTPClient;
import it.sauronsoftware.ftp4j.FTPFile;
import java.awt.FlowLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
public class ShowCategoryImages{
//FTPClient client=null;
JPanel panel=new JPanel();
JLabel label=new JLabel();
FTPClient client=new FTPConnection().FTPConnection();
FTPFile[] list;
File thumbnails;
File[] files;
ImageIcon icon;
public JPanel ShowCategoryImagesFunction(String path){
// delete all the components on reload
if(panel.getComponents().length>0){
System.out.println(panel.getComponents().length);
panel.removeAll();
panel.revalidate();
panel.repaint();
}
//panel.setLayout(new GridLayout(0,4,2,2));
//panel.setLayout(new BoxLayout(panel,BoxLayout.X_AXIS));
panel.setLayout(new FlowLayout());
panel.revalidate();
panel.repaint();
panel.updateUI();
try{
//images in /wallpapers/nature/black and white/thumb
client.changeDirectory("\\Wallpapers"+path+"\\thumb"); //path of thumbnails
//temporary folder for holding images
thumbnails=new File("Thumbnails");
list=client.list();
if(thumbnails.exists()){
files = thumbnails.listFiles();
if(files!=null) { //some JVMs return null for empty dirs
for(File f: files) {
f.delete();
}
}
}
else
thumbnails.mkdir();
for(int i=0;i<list.length;i++){
System.out.println("running");
icon=new ImageIcon(thumbnails.getAbsolutePath()+"\\"+list[i].getName());
icon.getImage().flush();
client.download(client.currentDirectory()+"\\"+list[i].getName(), new java.io.File(thumbnails.getAbsolutePath()+"\\"+list[i].getName()));
label=new JLabel(list[i].getName());
label.setIcon(icon);
label.setVerticalTextPosition(SwingConstants.BOTTOM);
label.setHorizontalTextPosition(SwingConstants.CENTER);
panel.add(label);
panel.revalidate();
panel.repaint();
label.addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e){
JLabel la=(JLabel)e.getSource();
System.out.println(la.getIcon());
}
});
}
//client.disconnect(true);
}catch(Exception e){
System.out.println(e.getMessage());
}
return panel;
}
}
3. FTPConnection.java
import it.sauronsoftware.ftp4j.FTPClient;
public class FTPConnection {
//ftp connection on local host
public static FTPClient FTPConnection(){
String ftphost="127.0.0.1";
String ftpuser="newuser";
String ftppassword="wampp";
int ftpport=21;
FTPClient client=new FTPClient();
try{
if(client.isConnected()==true){
client.disconnect(true);
};
client.connect(ftphost, ftpport);
client.login(ftpuser, ftppassword);
}
catch(Exception e){
System.out.println(e.getMessage());
}
return client;
}
}
not entirely sure what you mean with not layout, but your code is missing a revalidate/repaint after adding the labels:
// adding all labels
forEach (thumb....) {
JLabel label = new JLabel(thumb);
panel.add(label);
}
panel.revalidate();
panel.repaint();

GWT - Hibernate: How to display results from MySQL into GWT client

I am very starter to GWT and Hibernate. I made a simple GWT RPC application that adds a user to MySQL using Hibernate. I declared a single method in service interface i.e. addUser that adds a user(i.e. firstName & LastName) to MySQL calling Hibernate method. Its is working fine. Now added a 2nd method to retrieve users from DB & display.
Here are service interfaces
service interfaces
package rpctest.client;
import java.util.ArrayList;
import hibDomain.User;
import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
#RemoteServiceRelativePath("testService")
public interface RpctestService extends RemoteService {
public String addUser(String firstName,String lastName) throws
llegalArgumentException;
public ArrayList<User> getUser();
}
-------------------------------------
package rpctest.client;
import java.util.ArrayList;
import hibDomain.User;
import com.google.gwt.user.client.rpc.AsyncCallback;
public interface RpctestServiceAsync {
void addUser(String firstName, String lastName,
AsyncCallback<String> callback);
void getUser(AsyncCallback<ArrayList<User>> asyncCallback);
}
Here is entry point class
package rpctest.client;
import java.util.ArrayList;
import hibDomain.User;
import rpctest.shared.FieldVerifier;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
/**
* Entry point classes define <code>onModuleLoad()</code>.
*/
public class Rpctest implements EntryPoint {
final TextBox firstName = new TextBox();
final TextBox lastName = new TextBox();
final Button ans = new Button("Add User");
//final Label label1 = new Label("First Name");
//final Label label2 = new Label("Last Name");
private FlexTable userFlexTable = new FlexTable();
//final Label errorLabel = new Label();
private VerticalPanel mainpanel = new VerticalPanel();
private HorizontalPanel addpanel1 = new HorizontalPanel();
private HorizontalPanel addpanel2 = new HorizontalPanel();
private final RpctestServiceAsync calNumbers = GWT
.create(RpctestService.class);
/**
* This is the entry point method.
*/
public void onModuleLoad() {
userFlexTable.setText(0, 0, "User ID");
userFlexTable.setText(0, 1, "First Name");
userFlexTable.setText(0, 2, "Second Name");
userFlexTable.setText(0, 3, "Remove");
//add input boxes to panel
addpanel1.add(firstName);
addpanel1.add(lastName);
firstName.setFocus(true);
//add input
mainpanel.add(userFlexTable);
mainpanel.add(addpanel1);
addpanel1.add(ans);
ans.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
addStock();
}
});
lastName.addKeyPressHandler(new KeyPressHandler() {
public void onKeyPress(KeyPressEvent event) {
if (event.getCharCode() == KeyCodes.KEY_ENTER) {
addStock();
}
}
});
RootPanel.get().add(mainpanel);
}
private void addStock(){
String name1 = firstName.getValue();
// Stock code must be between 1 and 10 chars that are numbers, letters, or dots.
/*if (!name1.matches("^[0-9A-Z\\.]{1,10}$")) {
Window.alert("'" + name1 + "' is not a valid name.");
firstName.selectAll();
return;
}*/
firstName.setValue("");
String name2 = lastName.getValue();
/*if (!name2.matches("^[0-9A-Z\\.]{1,10}$")) {
Window.alert("'" + name1 + "' is not a valid name.");
lastName.selectAll();
return;
}*/
lastName.setValue("");
firstName.setFocus(true);
calNumbers.addUser(name1,name2,
new AsyncCallback<String>() {
public void onFailure(Throwable caught) {
// Show the RPC error message to the user
Window.alert("check your inputs");
}
#Override
public void onSuccess(String result) {
// TODO Auto-generated method stub
// Add the user to the table.
int row = userFlexTable.getRowCount();
userFlexTable.setText(row, 1, result);
}
});
calNumbers.getUser(new AsyncCallback< ArrayList<User>>() {
public void onFailure(Throwable caught) {
// Show the RPC error message to the user
Window.alert("Problem in database connection");
}
#Override
public void onSuccess( ArrayList<User> result) {
// TODO Auto-generated method stub
}
});
}
}
Here is service implementation
package rpctest.server;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
//import com.hib.HibernateUtil;
import org.hibernate.Session;
import org.hibernate.Transaction;
import hibDomain.User;
import rpctest.client.RpctestService;
public class RpctestServiceImpl extends RemoteServiceServlet implements RpctestService {
public String addUser(String name1, String name2)
throws IllegalArgumentException {
Transaction trns = null;
Session session =
HibernateUtil.getSessionFactory().openSession();
try {
trns = session.beginTransaction();
User user = new User();
user.setFirstName(name1);
user.setLastName(name2);
session.save(user);
session.getTransaction().commit();
} catch (RuntimeException e) {
if(trns != null){
trns.rollback();
}
e.printStackTrace();
} finally{
session.flush();
session.close();
}
return name1+name2; // to test flextable entris only
}
#Override
public ArrayList<User> getUser()
{
List<User> getUser = null;
Transaction trns = null;
Session session =
HibernateUtil.getSessionFactory().openSession();
try {
trns = session.beginTransaction();
getUser = session.createQuery("from User").list();
/* for (Iterator<User> iter = users.iterator(); iter.hasNext();)
{
User user = iter.next();
User[] arrOfObjects = new User[]{user};
} */
trns.commit();
} catch (RuntimeException e) {
if(trns != null){
trns.rollback();
}
e.printStackTrace();
} finally{
session.flush();
session.close();
}
return (ArrayList<User>) getUser;
}
}
The getUser method in service implementation class is showing an error, highlighting method return type i.e. ArrayList But eclipse is giving no suggestion.
Ok. Now, on the client page, create an async call to the service you have created. This link would help you:
http://examples.roughian.com/index.htm#Tutorials~RPC_To_Java
EDIT:
My apologies.
I assume you have serialized the "user" class. If not, you have to serialize it:
class user implements java.io.serializable;
If you want the resultset to convert to the array, do a check if list is null and if result list is not null, convert it to array and assign to user[] like:
try{
....
.... .list();
if(!users.isEmpty(){
getUser = users.toArray();
}
}
and then you can return getUser to the client side.

TreeModelListener not responding to changes in TreeModel which it subscribes to

I'm having some bother understanding why I cannot get a TreeModelChanged listener to respond to changes in the model which it subscribes to.
I have managed to reproduce the problem in a small example.
The SysOut message does not print to the console whenever a new node is added to the tree.
I intend to replace the SysOut message with some commands to redraw the tree. At the moment I am using a SysOut message just to prove that the listener is not being fired.
Am I missing something fundamental?
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
public class TreeTest {
private JTree t;
private DefaultTreeModel m ;
public static void main(String[] args) {
new TreeTest();
}
public TreeTest() {
//Draw Frame & Panel - set dimensions
JFrame f = new JFrame();
f.setSize(new Dimension(800,600));
JPanel p = new JPanel();
p.setSize(new Dimension(800,600));
//Create a Tree Model. Give it a String at the root.
m = new DefaultTreeModel(new DefaultMutableTreeNode("Root"));
//Create a tree and add the Model to it
t = new JTree();
t.setModel(m);
//Try a Tree Model Listener
m.addTreeModelListener(new TreeModelListener() {
private void doSomething() {
//Should fire whenever a node is added to the model
System.out.println("Responding to TreeModelListener");
}
#Override
public void treeStructureChanged(TreeModelEvent e) {
doSomething();
}
#Override
public void treeNodesRemoved(TreeModelEvent e) {
doSomething();
}
#Override
public void treeNodesInserted(TreeModelEvent e) {
doSomething();
}
#Override
public void treeNodesChanged(TreeModelEvent e) {
doSomething();
}
});
//Add listener to a button which adds nodes to the tree when clicked
JButton addNode = new JButton("Add node");
addNode.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
DefaultMutableTreeNode newNode = new DefaultMutableTreeNode("New Node");
DefaultMutableTreeNode root = (DefaultMutableTreeNode) m.getRoot();
root.add(newNode);
}
});
JScrollPane s = new JScrollPane(t);
p.add(s);
p.add(addNode);
p.setVisible(true);
f.add(p);
f.setVisible(true);
}
}
that's because the model doesn't know about the addition, it happens under its feet. Use the methods on DefaultTreeModel to do the insertion:
model.insertNodeInto(newNode, root, root.getChildCount())
Edit
a TreeNode is just a (more or less) dumb data structure. As you can see in the api, it's not an Observable, so there is no way for the model which uses that data structure to detect if anything changed on the node. To make it aware of the change, you have to do one of two things
use the node manipulation methods of the model
update the node and notify the model manually (calling nodesWereInserted)
The first is the preferable way (keeps control where it belongs), the second might be needed in more complex contexts (though I would strongly recommend to never do it, that's why SwingX DefaultTreeTableModel doesn't have them exposed :)

trouble executing actionlistener in swing applet embedded in html

Following is the applet code below:
import javax.swing.*;
import java.awt.*;
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.ImageObserver;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.UnknownHostException;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.beans.*;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import javax.swing.ImageIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class ui extends JApplet implements ActionListener{
public static JPanel panel2;
private JTextField subnetField =null;
public static JPanel panel3;
public static Font fc;
public static String[] subn;
public static String searchnet;
boolean flag=false;
public void init()
{
String hostname = null;
String hostaddress=null;
try {
InetAddress addr = InetAddress.getLocalHost();
// Get IP Address
hostaddress=addr.getHostAddress();
// Get hostname
hostname = addr.getHostName();
} catch (UnknownHostException e) {
}
subn= hostaddress.split("\\.");
System.out.println(subn[2]);
searchnet=subn[2];
//WindowDestroyer listener=new WindowDestroyer();
//addWindowListener(listener);
Container contentPane = getContentPane();
contentPane.setBackground(Color.WHITE);
contentPane.setLayout(new GridLayout(3,0));
JPanel panel1 =new JPanel();
panel2 =new JPanel();
panel1.setBackground(Color.WHITE);
panel1.setLayout(new BoxLayout(panel1, BoxLayout.Y_AXIS));
JLabel lb2 = new JLabel("You are at: "+hostname+" "+hostaddress+" ");
lb2.setFont(new Font("sans-serif",Font.BOLD,15));
lb2.setForeground(Color.RED);
JPanel panel1_1 =new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.gridx = 1;
c.gridy = 2;
panel1_1.setBackground(Color.WHITE);
panel1_1.add(lb2, c);
//lb2.setAlignmentX(Component.CENTER_ALIGNMENT);
//panel1_1.add(lb2, BorderLayout.EAST);
panel1_1.setAlignmentX(Component.CENTER_ALIGNMENT);
panel1.add(panel1_1);
panel3=new JPanel();
panel3.setLayout(new GridLayout(2,0));
panel3.setBackground(Color.WHITE);
panel1.add(panel3);
UIManager.put("Button.background", Color.white);
UIManager.put("Button.foreground", Color.red);
fc = new Font("sans-serif",Font.BOLD,15);
UIManager.put("Button.font", fc);
JButton searchButton= new JButton("Search");
//Border b = new SoftBevelBorder(BevelBorder.LOWERED) ;
//searchButton.setBorder(b);
searchButton.setAlignmentX(Component.CENTER_ALIGNMENT);
panel1.add(searchButton);
searchButton.addActionListener(this);
contentPane.add(panel1);
panel2.setBackground(Color.WHITE);
contentPane.add(panel2);
//contentPane.add(searchButton);
//JButton closeButton=new JButton("Close");
//contentPane.add(closeButton);
//closeButton.addActionListener(this);
contentPane.setVisible(true);
}
public void actionPerformed(ActionEvent e)
{
if (e.getActionCommand ().equals ("Close"))
{
System.exit(0);
}
if (e.getActionCommand ().equals ("Search"))
{
panel2.setVisible(false);
panel2.removeAll();
panel2.revalidate();
panel3.setVisible(false);
panel3.removeAll();
panel3.revalidate();
if(flag){
searchnet=subnetField.getText();
}
result(panel2);//puts panel 2&panel 3 in the ui
panel2.setVisible(true);
panel3.setVisible(true);
}
}
public boolean complete;
public JPanel call(){
return null;
}
public void result(JPanel pn){
.
.
.
}
}
}
private void addColumnName(JPanel pn) {
// TODO Auto-generated method stub
}
public void addDataToTable(JPanel p, String element, int type){
......
}
private static void open(URI uri) {
if (Desktop.isDesktopSupported()) {
Desktop desktop = Desktop.getDesktop();
try {
desktop.browse(uri);
} catch (Exception e) {
// TODO: error handling
}
} else {
// TODO: error handling
}
}
public static void main(String[] args){
ui start=new ui();
start.setVisible(true);
JFrame f = new JFrame("Find Device");
ui applet=new ui();
applet.init();
f.setLocationRelativeTo(null);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(800,450);
f.setVisible(true);
}
}
then the html file looks like this:
<html>
<applet code=ui.class
archive="webapplet.jar"
width=800 height=450>
</applet>
</body>
</html>
when i run the program via eclipse as an applet it runs fine, but when i put it in the html file, the init() seems to show up but the actionlistener on the button never seems to work
Any help would be really appreciated. Thanks!!
ps: will be happy to share any additional details if required
Emm... you mean the code never works as
System.exit(0);
?
If you mean "Close" button inactivity so it shouldn't close Internet Browser ... so that's OK :)
And this one as
InetAddress addr = InetAddress.getLocalHost();
Hmm... As for applet, I guess you should use getCodeBase() instead
Good luck :)