У меня возникла проблема в Java с использованием созданного мной класса «холст», который является расширенным JPanel
, для рисования анимированной кольцевой диаграммы. Эта диаграмма использует MouseListener
для получения событий кликов.
Проблема в том, что положение мыши не кажется точным, то есть оно не похоже на «холст», а вместо этого относительно окна (в левом верхнем углу я получил около 30 пикселей для координаты y).
Это мой код:
Я создал класс, который расширяет JPanel и имеет BufferedImage в качестве члена.
public class Canvas extends JPanel {
public BufferedImage buf;
private RingChart _parent;
public Canvas(int width, int height, RingChart parent){
buf = new BufferedImage(width, height, 1);
...
В методе компонента рисования я просто рисую буферизованное изображение, поэтому я могу рисовать на холсте «снаружи», рисуя на буферизованном изображении, которое общедоступно.
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.drawImage(buf, null, 0, 0);
}
Теперь есть класс RingChart, который содержит «холст»:
public class RingChart extends JFrame{
public Canvas c;
...
И я создаю Graphics2D из буферизованного изображения в классе холста. Этот g2d используется для рисования:
public RingChart(){
c = new Canvas(1500,980,this);
add(c);
setSize(1500, 1000);
setTitle("Hans");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
g2d = (Graphics2D)c.buf.createGraphics();
...
Чего я сейчас пытался добиться, так это прослушивателя мыши, который прослушивал события мыши, происходящие на холсте. Поэтому, когда пользователь нажимает на холст, я могу получить позицию, на которую он нажал на холсте, через переменную события.
Итак, я создал прослушиватель мыши:
class MouseHandler implements MouseListener {
@Override
public void mouseClicked(MouseEvent e){
RingChart r = ((Canvas)e.getSource()).getParent();
r.mouseClick(e);
}
...
... и добавил этот прослушиватель мыши на холст класса RingChart (myChart является экземпляром RingChart, а c - это холст, который он содержит):
...
MouseHandler mouse = new MouseHandler();
myChart.c.addMouseListener(mouse);
...
Но, как я упоминал выше, позиция мыши, возвращаемая при вызове события щелчка, кажется неточной. Я думаю, что ошибка должна быть как-то связана с тем, как я создал этот mouseListener или, возможно, назначил его не тому элементу или что-то в этом роде. Но я пробовал довольно много вещей, и это не изменилось. Может быть, кто-нибудь подскажет, что я сделал не так?
ОБНОВИТЬ:
Код функции «mouseClick», которая является членом RingChart и вызывается в прослушивателе мыши:
public void mouseClick(MouseEvent evt){
//evt = SwingUtilities.convertMouseEvent(this, evt, c);
if(evt.getButton() == MouseEvent.BUTTON1 && animation == null){
for(Element e : elements){
if(e.getShape() != null && e.getShape().contains(evt.getPoint())){
//do some stuff
}
}
}
}
Опять же, иерархия моих классов: RingChart --содержит --> Canvas -- получил --> MouseListener. Фигуры в этой функции — это фигуры, которые были нарисованы на холсте c. Теперь я хочу проверить, нажал ли пользователь на один из них. Итак, как я и думал, фигуры должны быть в координатах холста, а положение события должно быть в координатах холста, и все должно совпадать. Но это не так. Теперь пользователь MadProgrammer сказал мне использовать функцию ConvertMouseEvent. Но в настоящее время я не вижу, как именно я должен использовать это разумно.
ОБНОВИТЬ:
Я нашел решение: все, что мне нужно было сделать, это добавить холст не напрямую к JFrame
, а к ContentPane
вместо JFrame
:
Итак, вместо этого:
public RingChart(){
c = new Canvas(1500,980,this);
add(c);
...
I do:
public RingChart(){
c = new Canvas(1500,980,this);
getContentPane().add(c);
...
Затем я даю MouseListener
ContentPane
.
getContentPane().addMouseListener(new MouseHandler());
getContentPane().addMouseMotionListener(new MouseMoveHandler());
Я не знаю, элегантное ли это решение, но оно работает.
e.getSource().getMousePosition()
должен обеспечивать правильное относительное положение мыши. - person obataku   schedule 17.09.2012g2d.drawLine((int)c.getMousePosition().getX() - 5, (int)c.getMousePosition().getY(), (int)c.getMousePosition().getX() + 5, (int)c.getMousePosition().getY());
иg2d.drawLine((int)c.getMousePosition().getX(), (int)c.getMousePosition().getY() - 5, (int)c.getMousePosition().getX(), (int)c.getMousePosition().getY() + 5);
, чтобы было легче увидеть, где происходит событие мыши. - person Bobulous   schedule 18.09.2012