0

StackOverflow!

I'm working on a project, in regards to making a navigation system, and we're in the beginning stages, working with drawing the map and navigating it itself. We have a function, where you should be able to draw a square on top of the current data having been drawn already. I want to avoid having to repaint all of the data for the roads all over again, with each mouseDragged action event. To do this, I found that using a glass pane would be the optimal choice.

The problem recides with the dimensions of the glasspane and the coordinates it reads. When I click on a certain spot on our JPanel (which we use to draw on), it knows how and where to zoom in properly, but when I draw my square, it is being drawn a specific amount of pixels above my mouse's position. This seems to be due to the fact that my glass pane dimension does not correspond to my JPanel dimensions. The glass pane seems to also cover my menubar, whereas the JPanel itself does not read clicks which occur on the menubar.

I want to somehow fit a glasspane to my JPanel, and I've tried a few different things. One thing I tried, was to draw on a JRootPane instead of a JPanel, but that doesn't seem to be possible. Then I tried to just retrieve the "MyGlassPane" class from my JPanel (which also has its own class), and call it's repaint method, but that's where the issue originated from. Most lately, I've retrieved the JRootPane which the JPanel itself uses or is part of, and then retrieved the glasspane of this JRootPane, but it seems that my menubar, added to the JFrame, is also part of this JRootPane, meaning that the glasspane covers the menubar as well.

Here is some very simplified code, which covers the issue, but not the mouse-listening nor data-drawing aspects. It does however show off the fact that it's annoying that the rectangle is being drawn on top of the menubar.

import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.*;

public class TestForRootPaneStuff {
    JFrame frame = new JFrame();
    JRootPane root;
    JPanel panel = new JPanel();
    JLabel label = new JLabel("Hello there!");

    public void rootPanePls()
    {
        frame.add(panel);
        panel.add(label);

        root = panel.getRootPane();

        JMenuBar menubar = new JMenuBar();
        JMenu prettyMenu = new JMenu("Pretty");
        menubar.add(prettyMenu);
        frame.setJMenuBar(menubar);

        MyGlassPane gp = new MyGlassPane();
        root.setGlassPane(gp);

        gp.setVisible(true);
        gp.setEnabled(true);
        gp.repaint();


        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setPreferredSize(new Dimension(250, 250));

        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        TestForRootPaneStuff derp = new TestForRootPaneStuff();
        derp.rootPanePls();
    }

    private class MyGlassPane extends JComponent implements ItemListener
    {
        //React to change button clicks.
        @Override
        public void itemStateChanged(ItemEvent e) {
            setVisible(e.getStateChange() == ItemEvent.SELECTED);
        }

        //Draw the square for zoomToSquare
        @Override
        protected void paintComponent(Graphics g) {
            g.setColor(Color.BLUE);
            g.drawRect(10, 10, 100, 100);
        }
    }
}

And this is a corresponding screenshot, as a result of running this code. (I can't post direct images, due to lack of activity on here)

I hope my explaination makes at least a bit of sense. I'm aware that my explaination is perhaps a bit too in-depth as for actually resolving the issue, but I felt like it was necessary to invelop you guys a little bit more into my situation, and my reason for needing a solution for this.

TL;DR: I need a way to make a glassPane (retrieved/set from somewhere) completely fit the dimensions of a specific JPanel, so that I can receive the same mouse event coordinates for both the JPanel and the glasspane. See code above for visualization of the issue. Is there a smart way to go about this? Setting the RootPane glasspane was my final idea...

Thanks in advance, if anyone has any insight to bring!

Kirluu~

mKorbel
  • 109,525
  • 20
  • 134
  • 319
Kirluu
  • 13
  • 1
  • 6

1 Answers1

2

not an asnwer longer comment, just guessing based on wrong/uncomplete code posted here

  1. use JLabel instead of JComponent, JComponent hasn't any LayoutManager in API, sure JLabel too, but it to be container very simple like as contianer, is transparent, anything in paintComponent can be (semi) transparent

  2. your code is incompleted why is there ItemListener, don't put JComponents to JComponent as contianer, use JPanel instead, or mentioned opaque JLabel is easiests of ways for GlassPane, 1st code line should be super.paintComponent in paintComponent, dispose() all custom painting for anything placed/laid in GlassPane

  3. JLabel can has easilly to copy the coordinates from JPanel, use ComponentListener added to JPanel, with delaing (350-600) events from ComponentListener (one event per one pixel) by using Swing Timer, EDIT if resize continue call timer.restart() </EDIT, if resize ended then Swing Action/ActionListener will fire setBounds for JLabel (whatever) placed in GlassPane

  4. search for simple RepaintManager (just by covering JLabels bounds in GlassPane) for animation in GlassPane

mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • For one thing, the code you looked at is not part of my project, it's just a very short example displaying my problem which I described above the code... 1. Using a JLabel instead, makes it so that only the rectangle is drawn, with the menubar and JLabel getting hidden under the "GlassPane", because the GlassPane being a JLabel makes it block everything behind it, AKA, not transparent. 2. Refer to comment before "1." 3. I don't think you've read what my problem is, and I don't exactly understand what you are saying/suggesting here. 4. Will get to it. Thanks for your reply :) – Kirluu Mar 24 '14 at 13:46
  • @Kirluu 1. `he code you looked at is not part of my project,` == your bad, 2. `it's just a very short example displaying my problem which I described above the code...` == again are wrong, tempts to guessing, 3. points 1-3 are about minimum ( could be based on some research here), 4. `because the GlassPane being a JLabel makes it block everything behind it` == wrong usage of GlassPane, 5. note GlassPane protect only against MouseEvents, KeyEvents are dispatched – mKorbel Mar 24 '14 at 14:33