Rechercher
 

Swing - KDatabaseTree - Lister le contenu d'une base de données SQL

KLink - Un composant de type lien hypertexte KSqlQueryTable - Lister le contenu d'une requête SQL



Accès rapide :
La vidéo
Présentation du composant KDatabaseTree
Testons notre composant graphique

La vidéo

Cette vidéo vous apprend à coder une classe dérivant de JTree qui affiche les éléments (les tables) présents dans une base de données SQL, de manière hiérarchique. La connaissance préalable de JDBC est vivement conseillée.


KDatabaseTree - Lister le contenu d'une base de données SQL

Présentation du composant KDatabaseTree

Ce composant graphique permet d'afficher les éléments contenus dans une base de données relationnelles. La version proposée n'affiche que les tables, mais je vous invite à y afficher aussi les vues et les procédures stockées de la base de données. Voici un capture d'écran du composant KDatabaseTree.

Exemple d'utilisation du composant KDatabaseTree
ce composant ne dérive pas de JTree malgré ce que laisse présager le nom du composant. En réalité ce composant dérive de la classe JScrollPane, ce qui permet l'affichage de barres de scrolling, si nécessaire. Par contre ce JScrollPane contient bien une instance de la classe JTree.

Voici le code de la classe KDatabaseTree.

 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
 10 
 11 
 12 
 13 
 14 
 15 
 16 
 17 
 18 
 19 
 20 
 21 
 22 
 23 
 24 
 25 
 26 
 27 
 28 
 29 
 30 
 31 
 32 
 33 
 34 
 35 
 36 
 37 
 38 
 39 
 40 
 41 
 42 
 43 
 44 
 45 
 46 
 47 
 48 
 49 
 50 
 51 
 52 
 53 
 54 
 55 
 56 
 57 
 58 
 59 
 60 
 61 
 62 
 63 
 64 
 65 
 66 
 67 
 68 
 69 
 70 
 71 
 72 
 73 
 74 
 75 
 76 
 77 
 78 
 79 
 80 
 81 
 82 
 83 
 84 
 85 
 86 
 87 
 88 
 89 
 90 
 91 
 92 
 93 
 94 
 95 
 96 
 97 
 98 
 99 
 100 
 101 
 102 
 103 
 104 
 105 
 106 
 107 
 108 
 109 
 110 
 111 
 112 
 113 
 114 
 115 
 116 
 117 
 118 
 119 
 120 
 121 
 122 
 123 
 124 
 125 
package fr.koor.swing.jdbc;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.sql.Connection;
import java.util.EventListener;
import java.util.EventObject;
import java.util.Vector;

import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreePath;

import fr.koor.swing.jdbc.KDatabaseTreeNode.UserObject;


public class KDatabaseTree extends JScrollPane {

    private static final long serialVersionUID = 5063144763332643221L;

    private Vector<DatabaseSelectionListener> databaseSelectionListeners = new Vector<DatabaseSelectionListener>();
    private JTree jTree = new JTree();

    
    public KDatabaseTree() {
        super();
        this.setPreferredSize( new Dimension( 300, 200 ) );
        this.setViewportView( jTree );
        jTree.addMouseListener( new MouseAdapter() {
            @Override public void mouseClicked(MouseEvent mouseevent) {
                if ( mouseevent.getClickCount() == 2 ) {        // Double click
                    fireTableSelectionChanged( jTree.getSelectionPath() );
                }
            }
        });
    }


    public void setConnection( Connection connection ) {
        if ( connection == null ) {
            jTree.setModel( null );
            return;
        }
        
        try {
            KDatabaseTreeNode rootNode = new KDatabaseTreeNode( connection );
            jTree.setModel( new DefaultTreeModel( rootNode ) );
            jTree.setCellRenderer( new DatabaseCellRenderer() );
            jTree.expandRow( 1 );
        } catch ( Exception exception ) {
            exception.printStackTrace();
            jTree.setModel( null );
        }
    }

    // --- Ajout d'un renderer pour contrôler les icônes affichées --- 
    
    private static class DatabaseCellRenderer implements TreeCellRenderer {

        private JLabel nodeLabel = new JLabel();

        public Component getTreeCellRendererComponent(
                JTree tree, Object node, boolean selected, boolean expanded,
                boolean leaf, int row, boolean hasFocus) {
            UserObject data = (UserObject) ((DefaultMutableTreeNode) node).getUserObject();
            nodeLabel.setIcon( new ImageIcon( data.getIconUrl() ) );
            nodeLabel.setText( data.getText() );
            return nodeLabel;
        }
    }

    
    // --- Ajout d'un type de listener et de la classe d'événement associée ---
    
    public static class DatabaseSelectionEvent extends EventObject {

        private static final long serialVersionUID = 6132389637969225980L;
        
        private String tableName = null;
        
        public DatabaseSelectionEvent( Object source, String tableName ) {
            super( source );
            if ( tableName == null ) throw new NullPointerException();
            this.tableName = tableName;
        }
        
        public String getTableName() {
            return this.tableName;
        }
    }
    
    public static interface DatabaseSelectionListener extends EventListener {
        
        public void tableSelectionChanged( DatabaseSelectionEvent event );

    }
    
    public void addDatabaseSelectionListener( DatabaseSelectionListener listener ) {
        this.databaseSelectionListeners.addElement( listener );
    }

    public void removeDatabaseSelectionListener( DatabaseSelectionListener listener ) {
        this.databaseSelectionListeners.remove( listener ); 
    }
    
    private void fireTableSelectionChanged( TreePath path ) {
        Object [] data = path.getPath();
        DefaultMutableTreeNode node = (DefaultMutableTreeNode)data[ data.length-1 ];
        if ( node instanceof KDatabaseTreeNode.TableTreeNode == false ) return;
        
        UserObject userObject = (UserObject) node.getUserObject();
        DatabaseSelectionEvent event = new DatabaseSelectionEvent( this, userObject.getText() );
        for(DatabaseSelectionListener listener : this.databaseSelectionListeners) {
            listener.tableSelectionChanged( event );
        }
    }
        
}
KDatabaseTree - Lister le contenu d'une base de données SQL

Cette classe a besoin de diverses classes associées aux noeuds de l'arborescence : ces classes de noeuds sont contenues dans un seul fichier.

 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
 10 
 11 
 12 
 13 
 14 
 15 
 16 
 17 
 18 
 19 
 20 
 21 
 22 
 23 
 24 
 25 
 26 
 27 
 28 
 29 
 30 
 31 
 32 
 33 
 34 
 35 
 36 
 37 
 38 
 39 
 40 
 41 
 42 
 43 
 44 
 45 
 46 
 47 
 48 
 49 
 50 
 51 
 52 
 53 
 54 
 55 
 56 
 57 
 58 
 59 
 60 
 61 
 62 
 63 
 64 
 65 
 66 
 67 
 68 
 69 
 70 
 71 
 72 
 73 
 74 
 75 
 76 
 77 
package fr.koor.swing.jdbc;

import java.net.URL;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.swing.tree.DefaultMutableTreeNode;

public class KDatabaseTreeNode extends DefaultMutableTreeNode {
    
    private static final long serialVersionUID = -2126135007480343273L;

    
    public KDatabaseTreeNode( Connection connection ) throws SQLException {
        if ( connection == null ) return;
        String text = connection.getCatalog() + " database";
        URL url = getClass().getResource( "/images/database.png" );
        this.setUserObject( new UserObject( text, url ) );
        
        this.add( new TablesTreeNode( connection ) );
        // You can do the same for views and stored procedures
    }

    
    
    public static class TablesTreeNode extends DefaultMutableTreeNode {

        private static final long serialVersionUID = 5512631571960795765L;

        public TablesTreeNode( Connection connection ) throws SQLException {
            URL url = getClass().getResource( "/images/tables.png" );
            this.setUserObject( new UserObject( "Tables", url ) );

            DatabaseMetaData metaData = connection.getMetaData();
            try ( ResultSet resultSet = metaData.getTables(null, null, "%", null) ) {               
                while( resultSet.next() ) {
                    this.add( new TableTreeNode( resultSet.getString( 3 ) ) );
                }
            }
        }
    }

    public static class TableTreeNode extends DefaultMutableTreeNode {

        private static final long serialVersionUID = 2744534418719443466L;

        public TableTreeNode( String tableName ) {
            URL url = getClass().getResource( "/images/table.png" );
            this.setUserObject( new UserObject( tableName, url ) );
        }
        
        @Override public boolean isLeaf() {
            return true;
        }
        
    }

    public static class UserObject {
        private String text;
        private URL iconUrl;
        
        public UserObject( String text, URL iconUrl ) {
            this.text = text;
            this.iconUrl = iconUrl;
        }
        
        public String getText() {
            return text;
        }
        
        public URL getIconUrl() {
            return iconUrl;
        }
    }
}
Les diverses classes de noeuds utilisés pour l'arborescence.

Testons notre composant graphique

Pour pouvoir tester ce composant, il vous faut une base de données, ainsi que le driver JDBC permettant la connexion à cette base de données. Prenez soin de mettre le JAR du driver JDBC accessible du CLASSPATH.

 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
 10 
 11 
 12 
 13 
 14 
 15 
 16 
 17 
 18 
 19 
 20 
 21 
 22 
 23 
 24 
 25 
 26 
 27 
 28 
 29 
 30 
 31 
 32 
 33 
 34 
 35 
 36 
 37 
 38 
 39 
 40 
 41 
 42 
 43 
 44 
 45 
 46 
 47 
 48 
 49 
 50 
 51 
 52 
 53 
 54 
 55 
 56 
 57 
 58 
 59 
import java.awt.BorderLayout;
import java.sql.Connection;
import java.sql.DriverManager;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.plaf.nimbus.NimbusLookAndFeel;

import fr.koor.swing.jdbc.KDatabaseTree;
import fr.koor.swing.jdbc.KDatabaseTree.DatabaseSelectionEvent;

public class Test extends JFrame {
    
    private static final long serialVersionUID = 4443303248990993973L;
    
    
    public Test() {
        super( "KDatabaseTree component test" );
        this.setSize( 200, 300 );
        this.setLocationRelativeTo( null );
        this.setDefaultCloseOperation( DISPOSE_ON_CLOSE );
        
        // --- On récupère le contentPane ---
        JPanel contentPane = (JPanel) getContentPane();
        
        // --- On ajoute le composant d'affichage de contenu de la base ---
        String driver = "org.mariadb.jdbc.Driver";
        String url = "jdbc:mariadb://localhost:3306/WebStore";
        String login = "root";
        String password = "";
        try {
            Class.forName( driver );
            try ( Connection connection = DriverManager.getConnection( url, login, password ) ) {
                KDatabaseTree tree = new KDatabaseTree();
                tree.setConnection( connection );
                tree.addDatabaseSelectionListener( this::displayTableName );
                contentPane.add( tree, BorderLayout.CENTER );
            }           
        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }
    
    
    // --- Affiche le nom de la table double-cliquée ---
    public void displayTableName( DatabaseSelectionEvent event ) {
        System.out.println( event.getTableName() );
    }
        

    // --- Point d'entrée du programme ---
    public static void main(String[] args) throws Exception {
        UIManager.setLookAndFeel( new NimbusLookAndFeel() );
        Test frame = new Test();
        frame.setVisible(true);
    }
    
}
Classe de test du composant KDatabaseTree


KLink - Coder un composant de type lien hypertexte KSqlQueryTable - Lister le contenu d'une requête SQL