8

I am working on a program which takes a user input and generates an output as a map projection plot. The easiest map projection library that I have found is matplotlib-basemap, written in python a language I am not much familier with (I work on Java ).I have written the user interface in Java. Currently I am executing the python code and sending command arrays with data using Runtime and exec() command calling the ".py" file. This exectues the command and shows the plot as a separate window.

My Question is this: Is it possible to embed this basemap (Interactive with Zoom features) on a Jpanel? Or on a python GUI which can then be embedded on a JPanel? I know I can save the image generated by matplotlib as a file which can be fixed on a panel, but then it won't be interactive, The Zoom features won't be available then. Or is using a Java based tool rather than basemap is more appropriate?(I haven't found any as good)

----Edit on 22nd May 2013------

Jython is not a solution as matplotlib is incompatible with it. Doing the whole thing in python I agree will be optimum but this is what I have to work with.

JACOB Jar: I wasn't able to find an example code showing how to embed a seperate application(basemap) on a JPanel or JFrame.

Currently I am planning on embedding the basemap into a wxpython GUI and then use sockets to communicate between the two languages.

TCP/IP Socket with Server Java and Client Python.

javaEd
  • 158
  • 2
  • 10
  • Related: http://stackoverflow.com/questions/309158/embedding-an-application-inside-another-application – hyde Apr 22 '13 at 08:39
  • Please provide some of your code to experiment with. – utapyngo May 09 '13 at 14:09
  • Not a cross-platform solution but on Windows this should help: [SetParent function](http://msdn.microsoft.com/en-us/library/windows/desktop/ms633541%28v=vs.85%29.aspx) – utapyngo May 09 '13 at 15:28
  • 1
    I can't help but ask but could using Jython help you here? – dc5553 May 13 '13 at 12:02
  • I'm not too familiar with Java, but would it be possible to return the map projection plot from the Python script and then have your GUI be all Java? It seems like you're going to have some issues embedding one GUI within another, but I could be wrong. And dc5553, I don't believe that's going to help, you can compile Jython into a .jar, but that doesn't help much, and I think it would be significantly harder to basically crack into the Java interpreter and pull things from it. – Seth Curry May 13 '13 at 13:04
  • Is writing a GUI in Python to any relevance? i have a couple of 50 examples of simple GUI code laying around in Python.. Usually mixing two high-level languages with different engines/processors are generally a bad and taxing idea even tho it is doable. Stick to either one of the languages and find the library functions you need in one language instead of mixing them up even tho one has an easy fix for one solution and the other language has a easy fix for the other, combining them is not as easy as just making hard work in one language, if you get the idea. – Torxed May 14 '13 at 06:09
  • Did you find a solution to this? We have a similar requirement. Does this look like a potential solution: [backend_swing](https://github.com/LeeKamentsky/backend_swing)? – Gabriel Jan 20 '16 at 16:45
  • Hi. No we didnt. We just called the python UI from Java using a bat file (Runtime.exec) and let it be done. On reading the info, backend_swing does seem to be a potential solution,. Please let know if it works. :) – javaEd Feb 16 '16 at 10:52

2 Answers2

2

This is if you're open to new ideas and learning new things.
It's not a solution on your specific problem that you want to join two languages, this is a replacement for that idea to incorporate everything in Python.

#!/usr/bin/python
import pyglet
from time import time, sleep

class Window(pyglet.window.Window):
    def __init__(self):
        super(Window, self).__init__(vsync = False)
        self.alive = 1

        self.click = None
        self.drag = False

        with open('map.png', 'rb') as fh:
            self.geodata_image = pyglet.image.load('map.png', file=fh)
            self.geo_info = self.geodata_image.width, self.geodata_image.height

    def on_draw(self):
        self.render()

    def on_mouse_press(self, x, y, button, modifiers):
        self.click = x,y

    def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
        if self.click:
            self.drag = True
            print 'Drag offset:',(dx,dy)

    def on_mouse_release(self, x, y, button, modifiers):
        if not self.drag and self.click:
            print 'You clicked here', self.click, 'Relese point:',(x,y)
            ## Do work on corindate
        else:
            print 'You draged from', self.click, 'to:',(x,y)
            ## Move or link two points, or w/e you want to do.
        self.click = None
        self.drag = False

    def render(self):
        self.clear()
        ## An alternative to only getting a region if you only want to show a specific part of
        ## the image:
        # subimage = self.geodata_image.get_region(0, 0, self.geo_info[0], self.geo_info[1])
        self.geodata_image.blit(0, 0, 0) # x, y, z from the bottom left corner
        self.flip()

    def on_close(self):
        self.alive = 0

    def run(self):
        while self.alive:
            self.render()

            ## self.dispatch_events() must be in the main loop
            ## or any loop that you want to "render" something
            ## Because it is what lets Pyglet continue with the next frame.
            event = self.dispatch_events()
            sleep(1.0/25) # 25FPS limit

win = Window()
win.run()

All you need is:


Python mockup of running as a submodule to Javav

import sys
for line in sys.stdin.readline():
    if line == 'plot':
        pass # create image here

For instance.

Torxed
  • 22,866
  • 14
  • 82
  • 131
  • Thanks @Torxed. While I agree that this is a solution (i.e. throw away the whole Java component), I'm keen to see a *Java* implementation which calls out to a Python subprocess and renders matplotlib figures (in this case a Basemap plot) which can be interacted with. – pelson May 14 '13 at 10:16
  • Yw, i added a small mockup of how you can run a Python script as a subprocess under Java and listen for "live" input giving you the option to interact and re-render bitmaps/basemaps. – Torxed May 14 '13 at 10:24
  • @Torxed Yes I understand that doing the whole thing in Python would be optimum, but Java-Python interfacing is what I have to work with(work /client related stuff). Python purely because of the interactive features of Matplotlib-basemap. I tried fixing the png image on Jpanel, but its not interactive.Thanks all the same. – javaEd May 22 '13 at 09:12
0

You can certainly embed your GUI in Jython, a Java implementation of Python. Unfortunately it doesn't support matplotlib, as it relies on native code. You could try and use execnet to invoke Python from Jython.

Nicola Musatti
  • 17,834
  • 2
  • 46
  • 55