Могу ли я разделить стеклянную панель на две части и добавить к каждой из них отдельный лист мыши?
У меня есть код с двумя изображениями под стеклянной панелью. Я хочу сделать так, чтобы каждое изображение находилось под своей стеклянной панелью, и каждая стеклянная панель сигнализировала о своем собственном мышином прослушивателе. В настоящее время я сделал оба из них под одной стеклянной панелью, с одним MouseListener для всей стеклянной панели. Оба изображения располагаются в виде сетки рядом, поэтому не должно быть слишком сложно разделить стеклянную панель пополам. Вот код только одной стеклянной панели, но обратите внимание, что я пытаюсь создать две стеклянные панели и два отдельных класса слушателя мыши для каждого изображения. Это всего лишь код с одним * слушателем мыши для ** обоих изображений:
package Buttons;
import java.awt.GridLayout;
import java.awt.event.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Giraffewindow extends JDialog {
public Giraffewindow() {
JDialog giraffewindow = new JDialog();
Icon giraffe = new ImageIcon(getClass().getResource("giraffe.png"));
Icon windows = new ImageIcon(getClass().getResource("windows.png"));
giraffewindow.setLayout(new GridLayout(1, 2, 0, 0));
giraffewindow.add(new JLabel(windows));
giraffewindow.add(new JLabel(giraffe));
giraffewindow.pack();
giraffewindow.setTitle("GIRAFFE!");
giraffewindow.setVisible(true);
giraffewindow.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
JPanel glass = ((JPanel) giraffewindow.getGlassPane());
glass.setVisible(true);
status = new JLabel("I can change");
glass.add(status);
glass.setLayout(null);
giraffemousehandler giraffemouse = new giraffemousehandler();
glass.addMouseListener(giraffemouse);
glass.addMouseMotionListener(giraffemouse); //Can I add mouse motion listener to a picture
// setLayout(null);
}
JLabel status = null;
class giraffemousehandler extends MouseAdapter implements MouseListener, MouseMotionListener { //MouseAdapter makes it so that you don't have to have all 7 implemented mouse listener methods
@Override
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
status.setBounds(e.getX(), e.getY(), 50, 60); //Makes JLabel follow mouse
}
@Override
public void mouseEntered(MouseEvent e) {
status.setText("Enter);
}
@Override
public void mouseExited(MouseEvent e) {
status.setText("Exit");
// status.setBounds(e.getX(), e.getY(), 5, 6);
}
}
}
Вот код по запросу Camickr, обратите внимание, что есть два отдельных слушателя мыши, я хотел бы знать, как сделать это в противном случае. Когда JLabel следует за мышью, 1) он очень далеко от мыши, 2) он не показывает полный JLabel и 3) он не изменяется после одного выхода / ввода. Я действительно ценю помощь, и вот код, основанный на совете camickrs:
import java.awt.GridLayout;
import java.awt.event.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
class SSCCE extends JDialog {
public SSCCE() {
JDialog giraffewindow = new JDialog();
Icon giraffe = new ImageIcon(getClass().getResource("giraffe.png"));
Icon windows = new ImageIcon(getClass().getResource("windows.png"));
giraffewindow.setLayout(new GridLayout(1, 2, 0, 0));
JLabel giraffelabel = new JLabel();
JLabel windowlabel = new JLabel();
windowlabel.setIcon(windows);
giraffelabel.setIcon(giraffe);
giraffewindow.add(windowlabel);
giraffewindow.add(giraffelabel);
giraffewindow.setTitle("Title!");
giraffewindow.setSize(1100, 600);
giraffewindow.setVisible(true);
giraffewindow.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
JPanel glass = ((JPanel) giraffewindow.getGlassPane()); //Glasspane
glass.setVisible(true);
status = new JLabel("I can change"); //This is the JLabel which should follow my mouse
glass.add(status);
glass.setLayout(null);
giraffemousehandler giraffemouse = new giraffemousehandler();
windowmousehandler windowmouse = new windowmousehandler();
windowlabel.addMouseListener(windowmouse);
giraffelabel.addMouseMotionListener(giraffemouse); //Can I add mouse motion listener to a picture
// setLayout(null);
}
JLabel status = null;
class giraffemousehandler extends MouseAdapter implements MouseListener, MouseMotionListener { //MouseAdapter makes it so that you don't have to have all 7 implemented mouse listener methods
@Override
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
status.setBounds(e.getX(), e.getY(), 50, 60); //Makes JLabel follow mouse
}
@Override
public void mouseEntered(MouseEvent e) {
status.setText("Mouse is on giraffe");
}
@Override
public void mouseExited(MouseEvent e) {
status.setText("Mouse has left giraffe");
// status.setBounds(e.getX(), e.getY(), 5, 6);
}
}
class windowmousehandler extends MouseAdapter implements MouseListener, MouseMotionListener {
public void mouseMoved(MouseEvent event) {
// TODO Auto-generated method stub
status.setBounds(event.getX(), event.getY(), 50, 60); //Makes JLabel follow mouse
}
public void mouseEntered(MouseEvent event) {
status.setText("Mouse is on window");
}
@Override
public void mouseExited(MouseEvent event) {
status.setText("Mouse has left window");
// status.setBounds(e.getX(), e.getY(), 5, 6);
}
}
}
public class Icallsscce {
public static void main(String [] args) {
SSCCE object = new SSCCE();
}
}
2 ответа
Почти каждая проблема может быть продемонстрирована в 10-50 строках кода, если вы действительно понимаете, чего пытаетесь достичь.
Нет. Компонент - это компонент, вы не можете разделить его на две части.
У вас есть несколько вариантов:
Если вы добавите MouseListener в GlassPane, вам нужно будет использовать точку мыши из события и использовать
Container.getComponentAt(...)
чтобы определить, на каком компоненте находится мышь в данный момент. Обратите внимание, что GlassPane покрывает весь фрейм, поэтому точка мыши находится относительно фрейма, который включает в себя границы, поэтому вам сначала нужно будет использоватьSwingUtilities.convertPoint(...)
метод преобразования точки мыши в точку относительно панели, к которой вы добавили метки.Если вы добавите отдельные MouseListeners к каждой метке, то точка мыши будет относительно метки, поэтому вам нужно будет добавить значение "x" метки к точке на стеклянной панели при перемещении всплывающей метки. Я думаю, что такой подход проще. Обратите внимание, что при таком подходе вы можете использовать одного и того же слушателя, вам просто нужно использовать
getSource()
метод MouseEvent для получения метки.
Редактировать:
Как я могу добавить метод getSource() для моего mouseevent?
На это уже отвечали 10 дней назад: Ролловер на JLabel, который состоит из изображения в сетке?,
Это раздражает, когда вы даже не смотрите на код, потому что это не полная программа. Мы здесь не для того, чтобы писать код для вас. Когда кто-то находит время, чтобы ответить на вопрос, по крайней мере, вы можете сделать это, чтобы понять предложение.
1) это чрезвычайно далеко от мыши,
Я уже ответил, что в этом вопросе. Я заявил you will need to add the "x" value of the label..
, Вы должны сделать это, потому что события мыши генерируются относительно компонента, к которому добавлен слушатель.
Таким образом, для метки жирафа значение x будет начинаться с 0 и увеличиваться при перемещении мыши вправо. Однако жираф начинается в центре стеклянной панели, поэтому вы не можете использовать 0 в качестве местоположения всплывающей метки. Вы также должны указать местоположение жирафа.
Итак, основной код должен быть:
popupLabel.setLocation(e.getX() + giraffe.getLocation().x, e.getY());
Конечно, вы должны использовать объект "источник" (а не метку жирафа) MouseEvent, как показано в ответе выше. Когда вы используете исходный объект, код будет работать для обеих меток.
2) не показывает полный JLabel
потому что вы используете "магические числа" в вашем методе setBounds(). Почему вы использовали число, например, "60" для ширины этикетки? Не используйте жесткие коды. Вместо этого, когда вы изменяете текст метки, вы можете сделать:
label.setText(....);
label.setSize(label.getPreferredSize());
Теперь метка будет иметь правильную ширину / высоту. Затем, когда вы перемещаете метку на стеклянной панели, вы просто используете setLocation(...)
метод позиционирования этикетки.
Не меняется после одного входа / выхода
Вы реализуете MouseListener и MouseMotionListener, поэтому вам нужно добавить оба этих слушателя в каждый компонент. Итак, вам нужно:
giraffe.addMouseListener (...); giraffe.addMouseMotionListener (...); window.addMouseListener (...); window.addMouseMotionListener (...);
Опять же, помните, что вам нужен только один класс для реализации MouseListener и MouseMotionListener, как продемонстрировано 10 дней назад. Один и тот же экземпляр слушателя может быть добавлен к обоим компонентам, что поможет очистить ваш код.
Я действительно думаю, что у вас будут проблемы с использованием MouseListener
на glassPane
, так как это будет потреблять события мыши, а это означает, что любой из других компонентов на самом деле не будет уведомлен.
Вместо этого, я бы использовал стекло и следил за движением мыши над ним, чтобы найти компоненты, через которые он проходит, а затем соответственно изменял "метку наведения".
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRootPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import static javax.swing.WindowConstants.DISPOSE_ON_CLOSE;
public class Giraffewindow {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
new Giraffewindow();
}
});
}
public Giraffewindow() {
JDialog giraffewindow = new JDialog();
try {
Icon giraffe = new ImageIcon(ImageIO.read(new File("...")));
Icon windows = new ImageIcon(ImageIO.read(new File("...")));
JLabel left = new JLabel(windows);
JLabel right = new JLabel(giraffe);
giraffewindow.setLayout(new GridBagLayout());
giraffewindow.add(left);
giraffewindow.add(right);
giraffewindow.pack();
giraffewindow.setLocationRelativeTo(null);
giraffewindow.setTitle("GIRAFFE!");
giraffewindow.setVisible(true);
giraffewindow.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
JPanel glass = ((JPanel) giraffewindow.getGlassPane());
glass.setVisible(true);
status = new JLabel("I can change");
status.setForeground(Color.WHITE);
status.setBackground(Color.RED);
status.setOpaque(true);
glass.add(status);
glass.setLayout(null);
giraffemousehandler giraffemouse = new giraffemousehandler();
glass.addMouseMotionListener(giraffemouse);
// setLayout(null);
} catch (IOException exp) {
exp.printStackTrace();
}
}
JLabel status = null;
class giraffemousehandler extends MouseAdapter implements MouseListener, MouseMotionListener { //MouseAdapter makes it so that you don't have to have all 7 implemented mouse listener methods
private Component last = null;
@Override
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
Point p = e.getPoint();
JRootPane rootPane = SwingUtilities.getRootPane(e.getComponent());
Container contentPane = rootPane.getContentPane();
Component comp = contentPane.getComponentAt(p);
if (comp != last) {
if (last != null) {
mouseExited(last);
}
if (comp != null) {
if (comp != contentPane) {
last = comp;
mouseEntered(comp);
} else {
last = null;
}
}
}
status.setSize(status.getPreferredSize());
status.setLocation(p.x, p.y);
}
protected void mouseExited(Component comp) {
System.out.println("Exited");
status.setText("Exited");
}
protected void mouseEntered(Component comp) {
status.setText("Entered");
}
}
}
Интересно, будет ли подсказки проще...