如何在将鼠标放在图形元素顶部的画布上添加 JPanel?
Posted
技术标签:
【中文标题】如何在将鼠标放在图形元素顶部的画布上添加 JPanel?【英文标题】:How to add a JPanel on top of a canvas placing the mouse on the top of a Graphic element? 【发布时间】:2016-07-18 15:11:27 【问题描述】:我正在构建测试应用程序以供以后改进。我有一个使用游戏循环(更新、渲染)在画布上绘制的 Java 图形元素。它是一个红色的球,当鼠标放在它上面时会改变它的颜色。
我正在尝试找出一种方法来在鼠标位于球顶部时创建 JPanel,以在球内显示某种“隐藏信息”。我最初的想法是将使用JFreeChart API制作的直方图显示为“隐藏信息,所以我相信如果我创建这个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】:重量和重量轻的组件不会混合。 JPanel 是一个轻量级的组件,而 Canvas 是重量级的。重量级组件总是在轻量级组件之上绘制。
您可能想要做的只是将鼠标悬停部分直接绘制到画布上。如果你需要的话,你可以使用 FontMetrics 来绘制字符串。
【讨论】:
谢谢,但我不想只使用字符串。我想显示来自 JFreeChart (i1-scripts.softpedia-static.com/screenshots/…) 的图表如果我通过单击元素打开另一个 JFrame 怎么办? 是的。您可以将 CharPanel 添加到 JFrame,然后显示 JFrame。只要您的新图表 JFrame 不与光标所在的区域重叠,您甚至可以在光标移出打开它的区域后隐藏 JFrame。 好的,我试试。谢谢!以上是关于如何在将鼠标放在图形元素顶部的画布上添加 JPanel?的主要内容,如果未能解决你的问题,请参考以下文章
canvas 使用 isPointInPath() 判断鼠标位置是否在绘制的元素上
即使水平滚动,如何使放置在fabricjs对象顶部的DOM元素保持在那里