0

I am building the test application to improve later. I have a Java Graphic Element drawn on a canvas using a Game Loop (update,render). It is a red ball that changes its color when the mouse is placed on top of it.

I am trying to figure out a method to create a JPanel when the mouse is on top of the ball,to show some sort of "Hidden Information" inside the ball. My original idea is to display a histogram made with JFreeChart API as the "Hiden information, so I believe that if I create this JPanel I can later add the histogram to the JPanel created. Similar to this http://www.bitjuice.com.au/research/#hierarchicalclassificationexample. In the link, whenever you put the mouse on top of the rectangles, you display extra information.

So far I've got this code:

*Window.java * (The JFrame)

public class Window extends JFrame {

 JLabel title_label = new JLabel();

public Window(int width, int height, String title, Animation animation){

    setTitle(title);
    setPreferredSize(new Dimension(width,height));
    setMaximumSize(new Dimension(width,height));
    setMinimumSize(new Dimension(width,height));        
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setResizable(false);
    setLocationRelativeTo(null);
    add(animation);
    add(title_label, BorderLayout.SOUTH);
    setVisible(true);
    animation.start();
}

public void update(){
    title_label.setText(Animation.mouseX + " " + Animation.mouseY);
}
}

Animation.java(The game Loop)

public class Animation extends Canvas implements Runnable {

public static final int WIDTH = 1024, HEIGHT =  WIDTH/12*9 ;
private Thread thread;
private boolean running = false;
public static int mouseX,mouseY;
public Window window;
Button button = new Button();
public Animation(){
     window = new Window(WIDTH, HEIGHT,"Test", this);   
     addMouseMotionListener(new Handler(window));
     addMouseListener(new Handler(window));
}

public void run() {             
    this.requestFocus();
    long lastTime = System.nanoTime();
    double  amountOfTicks = 60.0;
    double ns = 1000000000/amountOfTicks;
    double delta = 0;
    long timer = System.currentTimeMillis();
    int frames = 0;


    while(running){         
        long now = System.nanoTime(); 
        delta += (now-lastTime) / ns;
        lastTime = now;         
        while(delta >= 1){
            update();               
            delta--;
        }
        if(running) 
            render();
        frames++;           
        if(System.currentTimeMillis() - timer >1000){   
            //System.out.println(frames);
            timer += 1000;
            frames = 0;
        }
    }
    stop();
}

public synchronized void start(){   
        thread = new Thread(this);
        thread.start();
        running = true;
    }

public synchronized void stop(){            
        try{
            thread.join();
            running = false;                
        }catch(Exception e){
            e.printStackTrace();
        }
    }



public static int getMouseX(){
    return mouseX;
}

public static int getMouseY(){
    return mouseY;
}

public static void setMouseX(int x){
    mouseX = x;
}

public static void setMouseY(int y){
    mouseY = y;
}

private void update(){      
    window.update();
    button.update();
}

private void render(){
    BufferStrategy bs = this.getBufferStrategy();
    if(bs == null){
        this.createBufferStrategy(4);
        return;
    }       
    RenderingHints rh = new RenderingHints(
            RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
    rh.put(RenderingHints.KEY_RENDERING,
            RenderingHints.VALUE_RENDER_QUALITY);
    Graphics g = bs.getDrawGraphics();
    Graphics2D g2d = (Graphics2D)g;
    g2d.setRenderingHints(rh);
    g2d.setColor(Color.white);
    g2d.fillRect(0, 0, WIDTH, HEIGHT);      
    button.render(g);
    g.dispose();
    g2d.dispose();
    bs.show();
}

public static void main(String args[]){
    new Animation(); 
 }

}

Handler.java

public class Handler extends MouseAdapter {

int x,y; 

private Window window;
public Handler(Window window){
    this.window = window;
}

 public void mouseMoved(MouseEvent e){
     Animation.setMouseX(e.getX());
     Animation.setMouseY(e.getY());

 }
}

Button.java

public class Button {

Ellipse2D mask;
boolean mouseIsOn = false;

public Button(){
    mask = new Ellipse2D.Double(500,350,50,50);
}
public void update(){
    if(mask.contains(Animation.mouseX,Animation.mouseY)){
        mouseIsOn = true;
    }else
        mouseIsOn = false;
}

public void render(Graphics g){

    if(mouseIsOn)
        g.setColor(Color.green);
    else
        g.setColor(Color.red);
    g.fillOval(500,350, 50, 50);
}
}

I appreciate the help.

1 Answers1

0

Heavy weight and light weight components don't mix. JPanel is a lightweight component and Canvas is heavyweight. Heavyweight components always get drawn on top of lightweight ones.

What you may want to do instead is just draw the mouseover portion directly to your canvas. You can use FontMetrics for drawing Strings if that is what you need.

markbernard
  • 1,412
  • 9
  • 18
  • Thanks, but I don't want to use just strings. I want to display a chart from JFreeChart ( http://i1-scripts.softpedia-static.com/screenshots/JFreeChart--17035.png ) What if I open another JFrame by clicking on the element ? – Hugo Gayoso Jul 18 '16 at 15:50
  • Yes. You could add a CharPanel to a JFrame and then show the JFrame. You could even hide the JFrame once the cursor moves off the area that opened it as long as your new chart JFrame does not overlap the area where the cursor is. – markbernard Jul 18 '16 at 17:45
  • Ok , I'll try that. Thank you! – Hugo Gayoso Jul 20 '16 at 14:26