tillnagel / unfolding

A library to create interactive maps and geovisualizations in Processing and Java
http://unfoldingmaps.org
Other
478 stars 244 forks source link

Maps always have black Background with Java2D-Renderer #93

Closed mrieser closed 10 years ago

mrieser commented 10 years ago

The example "Overlaying two maps" from http://unfoldingmaps.org/tutorials/multi-maps.html seems not to work with the latest version (0.9.6). I only get to see the second map, partially dimmed. I observed the behaviour as well when experimenting with custom tile servers that return png-tiles with transparency. Whatever I draw before I call map.draw() is hidden behind a black wall, even if the tiles are all transparent. I tried to first call map.setBackgroundColor(null), but this did not help. It works when I specify that the OpenGL-Renderer should be used by Processing. But I think it would be great to have this also for the Java2D-Renderer if possible.

tillnagel commented 10 years ago

Thanks for the report. The first part of the issue is simply because that map provider used in the example as overlay (a choropleth map showing rent costs) does not work anymore. The other map looks partially dimmed, because it actually is (tint(255, 100);).

The second one is due to the mechanism we are rendering map tiles. You can however, use P2D as renderer (which internally uses OpenGL since P2). Any specific reason you need the Java2D renderer?

tillnagel commented 10 years ago

And maybe this slightly more elaborate example is helpful: MapComparison

mrieser commented 10 years ago

About the non-working map providers, I figured that out as well, but also with others it didn't work – as long as I used the Java renderer. I tried the P2D renderer, but am stuck there on my side... I use Processing integrated into my own application, with other components around, and mixing the OpenGL-heavyweight container with the rest of the Swing-UI is not that easy. This has nothing to do with Unfolding Maps, it was just the reason why I've used the Java renderer fow now, as that one integrates more easily with my rest. But with Processing 2 (my app started with Processing 1.2 originally) I'll might have to invest the time to look into those integration issues sooner or later anyway.

tillnagel commented 10 years ago

Alas, I don't have experience with combining Swing and Unfolding. Maybe this discussion on Swing over Processing applets is a good starter ...

Let me know if you have further questions, or if there is anything I can help you with.

tillnagel commented 10 years ago

Ok, just updated an old sketch from @jeffg2k to Processing 2, and managed to combine it with Unfolding. Find below:

import javax.swing.*;
import processing.opengl.*; 
import java.awt.*;
import javax.swing.event.HyperlinkListener;
import javax.swing.event.HyperlinkEvent;
import java.awt.Insets;
import java.io.*;

import de.fhpotsdam.unfolding.*;
import de.fhpotsdam.unfolding.geo.*;
import de.fhpotsdam.unfolding.utils.*;

HTMLTextArea dg;
UnfoldingMap map;

void setup() {
  size(550, 400, OPENGL);

  map = new UnfoldingMap(this);
 MapUtils.createDefaultEventDispatcher(this, map);

  String myHTMLString = "";
  dg = new HTMLTextArea(frame, 100, 100, 300, 200);

  for (int i=0; i<10; i++) {
    myHTMLString += "<font color=white>This is a test of a JEditPane inside a JScrollPane within Processing using OpenGL.  Click my Hyperlink for </font><font color=#FF8040><a href=\"http://www.google.com\">Google</a></font><br/><br/></font>";
  }
  dg.setText(myHTMLString);
  dg.setVisible(true);
}
void draw() {
  background(100);  
  map.draw();  
}

// An inner class for all GUI elements.
class HTMLTextArea extends JDialog {
  int x, y, w, h;
  String htmlstring = "";
  JScrollPane scroll;
  JEditorPane panel;
  Frame f;
  /** Creates new form GUI */
  public HTMLTextArea(Frame f, int x, int y, int w, int h) {
    super(f, java.awt.Dialog.ModalityType.MODELESS);
    this.f = f;
    Point p = f.getLocation();
    Point winloc = new Point(0, 0);
    this.x = p.x + x + winloc.x;
    this.y = p.y + y + winloc.y;
    this.w = w;
    this.h = h;
    initComponents();
  }
  void setText(String textstring) {
    try {
      InputStream is = new ByteArrayInputStream(textstring.getBytes("UTF-8"));
      panel.read(is, "html");
    }
    catch (Exception e) {
    }
  }
  void initComponents() {
    scroll = new JScrollPane();
    panel = new JEditorPane();
    try {
      Insets iSet = new Insets(5, 5, 5, 5);
      scroll.setBorder(null);
      scroll.setViewportView(panel);
      panel.setContentType("text/html");
      panel.setMargin(iSet);
      panel.addHyperlinkListener(new MyHyperlinkListener());
      panel.setEditable(false);
      panel.setBackground(Color.black);
      panel.setForeground(Color.white);
      //
    }
    catch (Exception e) {
    }
    add(scroll);
    setSize( w, h);
    setResizable(false);
    setLocationRelativeTo(f);
    setLocation(x, y);
    setBackground(Color.black);
    setUndecorated(true);
    JRootPane root =  getRootPane();
    root.putClientProperty( "Window.shadow", Boolean.FALSE );
    KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventPostProcessor(new KeyEventPostProcessor() {
      public boolean postProcessKeyEvent(java.awt.event.KeyEvent e) {
        if (isFocused()) {
          if (e.getID() == java.awt.event.KeyEvent.KEY_PRESSED) {   
            key = e.getKeyChar();
            keyCode = e.getKeyCode();
            keyPressed();
          } else if (e.getID() == java.awt.event.KeyEvent.KEY_RELEASED) {
            key = e.getKeyChar();
            keyCode = e.getKeyCode();
            keyReleased();
          }
          return true;
        }
        return true;
      }
    }
    );
  }
  void repaint() {
    panel.repaint();
  }
  void getlink(String url) {
    link(url);
  }
  class MyHyperlinkListener implements HyperlinkListener {
    public void hyperlinkUpdate(HyperlinkEvent evt) {
      if (evt.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
        getlink(evt.getURL().toString());
      }
    }
  }
}
void keyPressed() {
  //String k = str(key);
  println(key);
}
eljeffeg commented 10 years ago

Nice - glad to see that old post got some use. :) I've since modified the class that the Processing code was based on. Let me know if you want me to paste it.

mrieser commented 10 years ago

thanks, I made some progress as well. Turns out that adding MouseListeners to PApplet only works if its in Swing mode but not when using P2D (OpenGL), so I had to rewrite some parts of my logic to be routed through the processing mouse-handling functionality instead of the Swing listeners (which might actually make sense for processing).

Anyway, I just wanted to raise the point that Unfolding Maps with the Java-based renderer does not offer the same/full functionality as the OpenGL-renderer does. It's okay for me if you decide to consider Java2D to be deprecated and not keeping up feature-parity with the newer OpenGL-renderer, as we all have only limited time to work and maintain software. A short note somewhere in the documentation about this could probably be helpful to prevent other people trying the same things/mistakes I made.

tillnagel commented 10 years ago

Yup, good point. Will clarify in the documentation.

tillnagel commented 9 years ago

See #114