如何在画布上添加JPanel,将鼠标放在Graphic元素的顶部?

时间:2016-07-18 15:11:27

标签: java canvas jpanel mouselistener game-loop

我正在构建测试应用程序以便以后改进。我有一个使用游戏循环(更新,渲染)在画布上绘制的Java图形元素。它是一个红色的球,当鼠标放在它上面时会改变它的颜色。

我试图找出一种方法,当鼠标位于球的顶部时创建一个JPanel,以显示某种"隐藏信息"在球内。我最初的想法是显示用JFreeChart API制作的直方图作为" Hiden信息,所以我相信如果我创建这个JPanel,我可以稍后将直方图添加到创建的JPanel。与此http://www.bitjuice.com.au/research/#hierarchicalclassificationexample类似。在链接中,只要将鼠标放在矩形的顶部,就会显示额外的信息。

到目前为止,我已经获得了此代码:

* Window.java * (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 (游戏循环)

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);
}
}

我很感激帮助。

1 个答案:

答案 0 :(得分:0)

重量轻,重量轻的组件不能混合。 JPanel是一个轻量级组件,Canvas是重量级的。重量级组件总是在轻量级组件之上绘制。

您可能想要做的只是将鼠标悬停部分直接绘制到画布上。如果您需要,可以使用FontMetrics绘制字符串。