2014-09-14 4 views
0

Итак, я пытаюсь выяснить, как я могу создать пользовательский MouseListener для всех моих кнопок, которые не требуют перечисления ни одного из них в обработчике, потому что у меня их много. Вот код, который у меня есть в моем Слушателе на данный момент:Проблемы с пользовательской кнопкой Java (не JButton)

package com.dinobuilding.handler;

import java.awt.Graphics; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 

import com.BLANK.BLANKScreen; 
import com.BLANK.BLANKWindow; 
import com.BLANK.menufeature.Button; 

public class ButtonHandler implements MouseListener { 

public BLANKWindow dbw; 
public BLANK Screen dbs; 

static Button button = new Button(); 

public int buttonX = button.x; 
public int buttonY = button.y; 
public int buttonSizeX = button.xSize; 
public int buttonSizeY = button.ySize; 

public ButtonHandler(BLANKWindow dbw, BLANKScreen dbs) { 
    this.dbw = dbw; 
    this.dbs = dbs; 
} 

public static void setButton(Button b) { 
    button = b; 
} 

public int mouseEventX; 
public int mouseEventY; 

Graphics g; 

public void mouseClicked(MouseEvent e) { 
    mouseEventX = e.getLocationOnScreen().x; 
    mouseEventY = e.getLocationOnScreen().y; 

    if(mouseEventX <= buttonX && mouseEventX >= buttonX + buttonSizeX) { 
     if(mouseEventY <= buttonY && mouseEventY >= buttonY + buttonSizeY) { 
      button.onClicked(dbs, dbw, g); 
     } 
    } 
} 

public void mousePressed(MouseEvent e) { 

} 

public void mouseReleased(MouseEvent e) { 

} 

public void mouseEntered(MouseEvent e) { 

} 

public void mouseExited(MouseEvent e) { 

} 

А вот код в первой кнопке, которую я пытаюсь выполнить:

package com.BLANK.menus; 

import java.awt.Color; 
import java.awt.Graphics; 

import com.BLANK.BLANKScreen; 
import com.BLANK.BLANKWindow; 
import com.BLANK.handler.ButtonHandler; 
import com.BLANK.menufeature.Button; 

public class MainMenuPlayButton extends Button { 

public static int x; 
public static int y; 
public static int xSize; 
public static int ySize; 
public static String s; 
public static Graphics g; 

public MainMenuPlayButton(int x, int y, int xSize, int ySize, String s, Graphics g) { 
    super(x, y, xSize, ySize, s, g); 
    this.x = x; 
    this.y = y; 
    this.xSize = xSize; 
    this.ySize = ySize; 
    this.s = s; 
    this.g = g; 
    setColor(new Color(0, 226, 26)); 
    draw(); 
} 

public MainMenuPlayButton() { 

} 

public static void draw() { 
    drawButton(x, y, xSize, ySize, g, s); 
    ButtonHandler.setButton(new MainMenuPlayButton()); 
} 

public void onClicked(BLANKScreen dbs, BLANKWindow dbw, Graphics g) { 
    setColor(new Color(216, 0, 0)); 
} 

Я думаю, что моя основная проблема заключается в том, что код в ButtonHandler вызывается перед кодом в Баттона и поэтому ButtonHandler использует сам класс Button, а не класс MainMenuPlayButton. Если вам нужен класс Button, просто скажите мне, однако я не могу себе представить, почему. Заранее спасибо!


Редактировать

Ok, после отладки некоторых, я обнаружил, что я на самом деле имеют противоположную проблему. Кнопка никогда не будет нажата. Метод getSource() мог бы работать, однако я действительно не знаю, как его использовать, и я не думаю, что я мог бы использовать это без жесткого кодирования каждой отдельной кнопки, чего я действительно не хочу делать.

EDIT 1: Как вы думаете, может быть, я мог бы использовать MouseEvent-х getX или getXOnScreen? Кстати, я зарегистрировал ButtonHandler с помощью frame.addMouseListener на моей JFrame, так что ...

EDIT 2: Казалось бы, что метод getX не работает. Если бы вы могли мне помочь, я бы очень признателен этому.

+0

Каждый конкретный класс кнопки будет иметь свой собственный объект Handler, добавленный к нему. Например, если это была программа калькулятора, я бы сделал один обработчик для числовых кнопок, а другой для кнопок математических операций и, возможно, третий для функций графического интерфейса, например для выхода. Кроме того, вы можете получить исходный объект для нажатия мыши с помощью метода 'getSource()' MouseEvent. –

+0

@HovercraftFullOfEels У меня есть класс супер Button, который я хочу, чтобы все кнопки использовались, и ButtonHandler использует это. Кроме того, сама мышь не является моей проблемой, моя проблема в том, что я не могу заставить ButtonHandler изменять метод Button onClicked, или, более конкретно, я не могу заставить метод setButton работать. – 2014-09-14 18:22:59

+0

Возможно, вам потребуется выполнить дополнительную отладку, чтобы увидеть, что именно и где ее не удается. –

ответ

2

Если вы хотите получить объект, который был нажат и сработал MouseListener, используйте метод getSource() MouseEvent. Например, это мощь работы:

public void mouseClicked(MouseEvent e) { 
    (YourButton) button = (YourButton) e.getSource(); 
    button.onClicked(...); 

} 

Другие биты:

  • Переименовать класс от кнопки к чему-то еще, так как имя кнопки столкновений с классом java.awt.Button, и это может привести к отладке ошибок.
  • Я съеживаю любое время, когда вижу поле графики, объявленное в классе, так как это предполагает возможную неприемлемую окраску. Убедитесь, что вы действительно знаете, что вы делаете, если используете один из них в качестве поля, так как легко получить потерю изображения или исключение NullPointerException, если оно не используется правильно, поскольку объект Graphics часто изменяется Java, и это изменение полностью из вашего (программиста) контроля. Не говорите, что вас не предупредили.

Редактировать
Что касается ваших комментариев:

Да, я знаю, что я делаю с полем графика, однако, если это заставляет Вас чувствовать себя лучше, знайте, что это только временно, и я буду менять его на что-то еще позже.

ОК, я только что был сожжен на этом раньше. Пока вы получаете его из BufferedImage и не пытаетесь получить его, вызвав getGraphics() на компоненте или вытащив его из метода paint или paintComponent, тогда вы можете быть в порядке.


Кроме того, я уверен, что я получаю объект это правильно щелкнуло, но я не могу получить его, чтобы получить доступ правильного подкласса кнопки. Это только сам класс Button, а не MainMenuPlayButton.

Извините, но это не имеет смысла, поскольку вы не получаете «классы», когда получаете ссылку, объект чистый и простой, и на самом деле вы получите тот же объект, что и ButtonListener добавлен, и это сработало слушателем, и класс этой ссылки будет любым классом вашей кнопки. Я предполагаю, что вы добавляете свой MouseListener прямо к объекту «Button», правильно? Опять же, время для некоторой отладки.


Edit 2
Что касается последнего редактирования на ваш вопрос:

Ok, после отладки некоторых, я обнаружил, что я на самом деле имеют противоположную проблему. Кнопка никогда не будет нажата. Метод getSource() мог бы работать, однако я не знаю, как его использовать, и я не думаю, что я мог бы использовать это без жесткого кодирования каждой отдельной кнопки, чего я действительно не хочу делать.

Нет, не нужно жестко закодировать каждую кнопку, поверьте мне. Вот и вся причина использования слушателей, которые добавляются к кнопкам.

EDIT 1: Как вы думаете, может быть, я смогу использовать getX или getXOnScreen MouseEvent? Кстати, я зарегистрировал ButtonHandler, используя frame.addMouseListener на моем JFrame, поэтому ...

Есть одна из ваших проблем. Если вы хотите слушать свои кнопки, вам захочется зарегистрироваться на самой кнопке. Если у вас есть массив или их коллекция, регистрация слушателей очень проста. И нет, я не рекомендую использовать x и y на экране, так как делает вашу программу чрезвычайно хрупкой. Если вы это сделаете, любые изменения в структуре вашего графического интерфейса потребуют последующих изменений жесткого кода для вашей обработки x и y. Тьфу.

Это вызывает вопрос о том, зачем создавать свой собственный класс Button и почему вместо этого использовать JButtons или подкласс JButtons. Вы, кажется, заново изобретаете колесо, но (извините, чтобы быть тупым), создавая квадрат.


Редактировать 3

Но вы привести переменную к кнопке, а это означает, что если у меня есть несколько кнопок, я должен бросить каждый и каждый из них в другую вещь.

Совершенно не так, как здесь должно работать магия полиморфизма. Но это объекты одного типа, нет? Или у вас много разных подклассов вашего класса Button? И независимо от того, внутри метода mouseClicked(...), вы, похоже, хотите вызвать только один метод на вашей кнопке, onClicked(...), который, я полагаю, должен быть объектом суперкласса, не так ли? Поэтому, вызывая этот метод на текущей кнопке, он должен вызывать свой собственный правильный код.

Проблема с JButton заключается в том, что они уже существуют. Я не могу их редактировать, и я не могу их настроить, ...

Это явно не соответствует действительности. Вы можете изменить их внешний вид и поведение многими способами, в том числе путем подклассификации или методом создания фабрики. Кроме того, они уже оснащены механизмом для регистрации слушателей и реагирования на действия мыши.

... Также мне нужно было бы зарегистрировать/сделать новый обработчик для каждой из кнопок?

Опять же, вы, кажется, забываете, что полиморфизм должен позаботиться обо всем этом. Один обработчик должен делать, в зависимости от того, насколько хорошо ваш код.

У меня будет много кнопок, и я не думаю, что это было бы жизнеспособным решением. Если бы не getX, как бы я мог заставить его что-то делать, когда нажимали на эту вещь?

Я дал вам рекомендации, кроме как иногда лучше переписывать разделы кода, если дизайн может быть улучшен, а это значит, что вы снова захотите рассмотреть возможность переопределения кода для использования JButtons.

+0

Да, я знаю, что я делаю с полем «Графика», однако, если это заставляет вас чувствовать себя лучше, знайте, что это только временно, и я буду менять его на что-то другое позже. – 2014-09-14 18:32:10

+0

Кроме того, я уверен, что я получаю объект, на который он щелкнул правильно, но я не могу получить доступ к соответствующему подклассу Button. Это только сам класс Button, а не MainMenuPlayButton. – 2014-09-14 18:34:50

+0

Но вы переводите переменную на кнопку, а это означает, что если у меня есть несколько кнопок, я должен отбросить каждую из них на другую. Проблема с JButton заключается в том, что они уже существуют. Я не могу их редактировать, и я не могу их настроить, поэтому я не хочу их использовать. Кроме того, должен ли я регистрировать/создавать новый обработчик для каждой из кнопок? У меня будет много кнопок, и я не думаю, что это было бы жизнеспособным решением. Если бы не getX, как бы я мог заставить его что-то делать, когда нажимали на эту вещь? – 2014-09-14 20:43:40

Смежные вопросы