graphstream / gs-core

Graphstream core
http://graphstream-project.org/
Other
399 stars 108 forks source link

Failed to add keyboard listeners to DefaultView #326

Open ema-pe opened 5 years ago

ema-pe commented 5 years ago

Graphstream version: 1.3 (using maven)

Problem: I'm not sure if it is a bug, or it is simply a my problem or a misunderstood. The problem is the DefaultView don't add correctly the keyboard listener to the frame, but only the default listener.

In the source code, there is a method provided to set the keyboard manager, but it is not added into the frame, instead only the default manager.

I know that there is more focus on the 2.x branch, but I think it is not difficult to fix this problem. I repeat the I'm not sure if this problem is really a bug, it may be a my failure using Swing and GraphStream.

How to reproduce: try to run the following code. If you type any keyboard's key no text is printed on the standard output.

package app;

import java.awt.event.KeyEvent;

import org.graphstream.graph.implementations.SingleGraph;
import org.graphstream.ui.view.View;
import org.graphstream.ui.view.util.ShortcutManager;
import org.graphstream.ui.graphicGraph.GraphicGraph;

public class App {
    public static void main(String args[]) {
        var graph = new SingleGraph("test", false, true);

        graph.addEdge("AB", "A", "B");
        graph.addEdge("CD", "C", "D");
        graph.addEdge("BD", "B", "D");

        var viewer = graph.display();

        viewer.getDefaultView().setShortcutManager(new ShortcutManager() {

            private View view;

            @Override
            public void init(GraphicGraph graph, View view) {
                this.view = view;
                view.addKeyListener(this);
            }

            @Override
            public void release() {
                view.removeKeyListener(this);
            }

            @Override
            public void keyPressed(KeyEvent e) {
                System.out.println("keyPressed!");
            }

            @Override
            public void keyReleased(KeyEvent e) {
                System.out.println("keyReleased!");
            }

            @Override
            public void keyTyped(KeyEvent e) {
                System.out.println("keyTyped!");
            }
        });
    }
}

Workaround (until it will be fixed): I use reflection to get the frame and then I add the keyboard listener to it. It is not elegant, but if you run this code it works as intended.

package app;

import javax.swing.JPanel;
import javax.swing.JFrame;
import java.awt.event.KeyListener;
import java.awt.event.KeyEvent;

import org.graphstream.graph.implementations.SingleGraph;
import org.graphstream.ui.swingViewer.ViewPanel;
import org.graphstream.ui.swingViewer.DefaultView;

public class App {
    public static void main(String args[]) {
        var graph = new SingleGraph("test", false, true);

        graph.addEdge("AB", "A", "B");
        graph.addEdge("CD", "C", "D");
        graph.addEdge("BD", "B", "D");

        var viewer = graph.display();

        try {
        var frame = ((DefaultView) viewer.getDefaultView())
            .getClass().getDeclaredField("frame");
        frame.setAccessible(true);
        ((JFrame) frame.get(((DefaultView) viewer.getDefaultView())))
            .addKeyListener(new KeyListener() {
                @Override
                public void keyPressed(KeyEvent e) {
                    System.out.println("keyPressed!");
                }

                @Override
                public void keyReleased(KeyEvent e) {
                    System.out.println("keyReleased!");
                }

                @Override
                public void keyTyped(KeyEvent e) {
                    System.out.println("keyTyped!");
                }
            });
        } catch (NoSuchFieldException|IllegalAccessException e) {
            e.printStackTrace();
            System.exit(1);
        }
    }
}
hichbra commented 5 years ago

Your first example works perfectly fine with me (I just added the missing Viewer import and corrected these "var").

import java.awt.event.KeyEvent;

import org.graphstream.graph.implementations.SingleGraph;
import org.graphstream.ui.view.View;
import org.graphstream.ui.view.Viewer;
import org.graphstream.ui.view.util.ShortcutManager;
import org.graphstream.ui.graphicGraph.GraphicGraph;

public class Issue {
    public static void main(String args[]) {
        SingleGraph graph = new SingleGraph("test", false, true);

        graph.addEdge("AB", "A", "B");
        graph.addEdge("CD", "C", "D");
        graph.addEdge("BD", "B", "D");

        Viewer viewer = graph.display();

        viewer.getDefaultView().setShortcutManager(new ShortcutManager() {

            private View view;

            @Override
            public void init(GraphicGraph graph, View view) {
                this.view = view;
                view.addKeyListener(this);
            }

            @Override
            public void release() {
                view.removeKeyListener(this);
            }

            @Override
            public void keyPressed(KeyEvent e) {
                System.out.println("keyPressed!");
            }

            @Override
            public void keyReleased(KeyEvent e) {
                System.out.println("keyReleased!");
            }

            @Override
            public void keyTyped(KeyEvent e) {
                System.out.println("keyTyped!");
            }
        });
    }
}
ema-pe commented 5 years ago

@hichbra var is just a Java keyword. Anyway the first example doesn't work for me (it runs but it won't print any output), I'm using 1.3 version, which version are you using?

hichbra commented 5 years ago

Ok it's java 10+ my bad, but still it works, I don't have any issue with this code under graphstream 1.3.

ema-pe commented 5 years ago

@hichbra it is really strange. If on your machine it works correctly, maybe is my machine, my java version or other.