JTree/JTable not reflecting database when change is done
I'm building an rss application using a hsql database. I'm stuck in updating the JTree when I made changes to a database table. I'm displaying the feed list and when I delete a feed in the database, the JTree is not refreshed. I've looked everywhere and tried all sorts of methods, but to avail. I also tried to create a custom model.
This is the code declaring the JTree. The JTree is inside a ScrollPane. In short, the class initializes the swing components. I'm using DefaultTreeModel for the model in JTree.
Code:
public Gui() {
super(new GridBagLayout());
.... //Some code initializing components
//Create the nodes.
top = new DefaultMutableTreeNode("RSS");
createNodes(top);
feedTree = new JTree(new DefaultTreeModel(top));
feedTree.setEnabled(true);
feedTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
feedTree.setRootVisible(false);
feedTree.addTreeSelectionListener(new TreeSelectionListener() {
public void valueChanged(TreeSelectionEvent e) {
selectedNode = (DefaultMutableTreeNode)feedTree.getLastSelectedPathComponent(); //selectedNode is already declared and initialized.
selectedTreePath = feedTree.getSelectionPath();
if (selectedNode == null) return;
Object nodeInfo = selectedNode.getUserObject();
if (selectedNode.isLeaf()) {
//ArticleInfo info = (ArticleInfo)nodeInfo;
displayURL(nodeInfo.toString()); //This displays the entries of the feed in a JEditorPane
}
if (DEBUG) {
System.out.println(nodeInfo.toString());
}
}});
//Create the scroll pane and add the tree to it.
feedView = new JScrollPane(feedTree);
... //more codes that initializes other components
inSplit = createInSplitPane(articleView, htmlView); //inSplit is a JSplitPane that contains a JTable and JEditorPane, both are contained in their individual JScrollPanes
outSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, feedView, inSplit); //outSplit is a JSplitPane that contains the JScrollPane containing the tree and the inSplit
outSplit.setOneTouchExpandable(true);
outSplit.setDividerLocation(180);
//Provide minimum sizes for the two components in the split pane
inSplit.setMinimumSize(new Dimension(100, 50));
feedView.setMinimumSize(new Dimension(100, 30));
//Add the split pane to this frame
c.weightx = 0.5;
c.fill = GridBagConstraints.BOTH;
c.gridx = 0;
c.gridy = 0;
c.anchor = GridBagConstraints.CENTER;
c.weighty = 0.5;
add(outSplit,c);
}
Here's a hierarchy of the application GUI (sorry that it's kinda messy):
JFrame
a. JPanel
a1. JSplitPane
a1a. JScrollPane
a1a1. JTree
a1b. JSplitPane
a1b1. JScrollPane
a1b1a. JTable
a1b2. JScrollPane
a1b2a. JEditorPane
This is the code that create the nodes during start-up.
Code:
private void createNodes(DefaultMutableTreeNode top) {
DefaultMutableTreeNode feed = null;
DefaultMutableTreeNode article = null;
try {
ResultSet r1 = db.getFeedList(); //This queries the list of feeds from the database
while(r1.next()) { //Create the nodes from the query result
feed = new DefaultMutableTreeNode(r1.getString("feed_name"));
top.add(feed);
}
} catch (SQLException e1) {
JOptionPane.showMessageDialog(getJFrame(),
"SQLException2: " + e1.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
} catch (ClassNotFoundException e1) {
JOptionPane.showMessageDialog(getJFrame(),
"ClassNotFoundException: " + e1.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
}
}
This is the code when I click on "Delete Feed" button:
Code:
deleteButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
try {
//Remember I said I initialized the selectedNode outside the constructor? It's for getting the feed title to delete.
if (selectedNode == null) { System.out.println("trying");return;}
Object nodeInfo = selectedNode.getUserObject();
if (selectedNode.isLeaf()) {
//The next three lines is deleting the feed in the database
String s = nodeInfo.toString();
int i = db.getFeedId(s);
db.deleteFeed(i);
((DefaultTreeModel)feedTree.getModel()).removeNodeFromParent(selectedNode);
//The last thing I tried was re-create the JTree, but I don't know how to reinitialize it in the scrollpane. As you can see, I even recreate the TreeSelectionListener.
createNodes(top);
feedTree = new JTree(new DefaultTreeModel(top));
feedTree.setEnabled(true);
feedTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
feedTree.setRootVisible(false);
feedTree.addTreeSelectionListener(new TreeSelectionListener() {
public void valueChanged(TreeSelectionEvent e) {
selectedNode = (DefaultMutableTreeNode)
feedTree.getLastSelectedPathComponent();
selectedTreePath = feedTree.getSelectionPath();
if (selectedNode == null) return;
Object nodeInfo = selectedNode.getUserObject();
if (selectedNode.isLeaf()) {
displayURL(nodeInfo.toString()); //Again, displayURL is to display the entries in the JEditorPane
}
if (DEBUG) {
System.out.println(nodeInfo.toString());
}
}});
if(!feedTree.isEnabled())
feedTree.setEnabled(true);
//As you can see, I'm tried all kinds of reload/repaint/revalidate to every component I can find the methods for
((DefaultTreeModel)feedTree.getModel()).reload();
//frame.repaint();
//((DefaultTreeModel)feedTree.getModel()).reload();
//feedView.repaint();
//feedView.revalidate();
}
} //some catch statements
}});
I'm really sorry for the messy code and other things that are messy. I'm really stuck and I'm trying to meet my deadline. I have been staring at the code for three days with little sleep. Please help!!! =(
I don't even know where to start debugging, since there's no error compiling. I'm having the same problem with JTable. I know that these components are just displaying a view of the data, and the model is the one that controls the data. But HOW do I get the component to refresh???!!! Please, Please, Please help!!! Thank YOU so MUCH!!!