Получение информации об определенном объекте, нажав на определенное изображение
Я сделал следующий класс, который содержит информацию о пользователях - имя, возраст фото.
public class User{
private int age;
private String name;
ImageIcon icon;
JLabel image;
public int getAge() {
return age;
}
public String getName() {
return name;
}
public User(){
this.age = 0;
this.name = "";
}
public User(int age, String name){
this.age = age;
this.name = name;
icon = new ImageIcon(name + ".jpg");
image = new JLabel(icon, JLabel.Center);
}
}
Я хочу создать набор изображений с лицами пользователей на JPanel. Я хочу получить информацию о каждом пользователе после нажатия на его фотографию. Поэтому я поместил этот код в основной класс:
MouseListener myClick = new MouseListener(){
@Override
public void mouseClicked(MouseEvent e)
{
User selected = new User();
selected.image = (JLabel) e.getComponent();
System.out.println(selected.getAge() + " " + selected.getName());
}
};
а также
User[] users = new User[32];
for (int i = 0; i < 32; i++)
{
panel.add(users[i].image);
users[i].image.addMouseListener(myClick);
}
Я знаю - это совершенно неправильно. Я не могу получить данные об определенном пользователе, потому что я получаю значения из "selected", который содержит только JLabel с изображением (без значений для возраста или имени). Что я должен сделать, чтобы получить имя и возраст определенного пользователя?
3 ответа
Есть несколько способов достижения того, что вы хотите сделать. (Я не совсем уверен, что это такое, но я уверен, что есть несколько способов;-)).
Один интересный вопрос может заключаться в том, кто определяет границы изображений / меток. Они помещены в панель с определенной раскладкой? Когда они, например, содержатся в панели с GridLayout
тогда вы можете просто вычислить индекс изображения на основе "ячейки сетки", которая соответствует определенной позиции мыши на панели. Если они расположены свободно (на панели с null
макет), то вы можете создать простую карту, как
class ImageMap<T>
{
private final Map<Rectangle2D, T> map;
ImageMap()
{
map = new LinkedHashMap<Rectangle2D, T>();
}
public T get(double x, double y)
{
for (Entry<Rectangle2D, T> entry : map.entrySet())
{
Rectangle2D key = entry.getKey();
if (key.contains(new Point2D.Double(x,y)))
{
return entry.getValue();
}
}
return null;
}
void setBounds(T t, Rectangle2D r)
{
Rectangle2D copy = new Rectangle2D.Double(
r.getX(), r.getY(), r.getWidth(), r.getHeight());
map.put(copy, t);
}
}
Затем вы можете заполнить эту карту информацией от пользователей:
ImageMap<User> map = new ImageMap<User>();
List<User> users = ...;
for (User user : users)
{
map.setBounds(user, user.getImage().getBounds());
}
И когда вы получаете событие мыши, вы можете запросить это
MouseEvent e = ...;
User user = map.get(e.getX(), e.getY());
Но действительно ли это уместно, зависит от вашего варианта использования. Возможно, JList с соответствующим CellRenderer лучше подойдет вашим потребностям.
Не ответ на вопрос, но:
Конструктор класса, по соглашению, определяется перед методами класса.
Почему вы создали класс User с методами
getName()
а такжеgetAge()
но вы не определилиgetImage()
метод? Быть последовательным! Вы не должны обращаться к переменным напрямую и должны определять метод "получения", когда хотите получить доступ к данным из класса.
Учитесь на примерах и не устанавливайте свои собственные стандарты.
Чтобы прокомментировать комментарий Эндрю, вы должны создать собственный рендерер для отображения Icon из класса User в JList. Прочитайте раздел учебника Swing по написанию пользовательского средства визуализации ячеек для получения дополнительной информации и примера отображения значка. В примере используется JComboBox, но концепция для JList та же.
Затем вы можете использовать ListSelectionListener для обработки выбора изображения. Это лучший подход, потому что он будет работать, когда пользователь использует мышь или клавиатуру.
У меня была похожая проблема с игрой, над которой я работаю, и я создал класс tilePane. Класс TilePane расширяет JPanel и имеет поля для имени, возраста, фотографии и т. Д. (Или просто содержит поле пользователя). Когда фотография нажата, возьмите родительский tilePane, а затем получите соответствующее поле tilePane. Вот фрагмент моего кода:
public void mouseClick(MouseEvent e) {
...
} else if (e.getSource() instanceof TilePane) {
TilePane clickPane = (TilePane) e.getSource();
...