Ciao sottovento,
il fatto è che mentre una JLabel estende JComponent, un JTextField estende JTextComponent (il quale a sua volta estende JComponent, ma nel farlo customizza la gestione di certi eventi per i suoi scopi, tra cui anche i mouse event, e nel farlo li consuma).
Una soluzione è estendere JTextComponent giusto per dire che si vuole che gli eventi a cui siamo interessati (mouse events e mouse motion events) non vengano processati al 'solito modo' previsto per i text components ma vengano direttamente notificati al componente superiore della gerarchia (il tuo pannello, in pratica). Per ottenere questo devi sovvrascrivere i metodi processXXXEvent, dove XXX va sostituito con il tipo degli eventi.
Ecco un esempio:
Codice:
package swingexercise;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
/**
* Class MyComponentExample...
*/
public class MyComponentExample
{
public static void main(String[] args) {
MyComponentExample mce = new MyComponentExample();
mce.run();
}
final JFrame FRAME;
final MouseHandler HANDLER;
MyComponentExample() {
FRAME = new JFrame("MyComponentExample");
FRAME.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
FRAME.setLayout(null);
FRAME.setPreferredSize(new Dimension(640, 480));
HANDLER = new MouseHandler();
ValueComponent value1 = new ValueComponent("var_1", "10000");
value1.setSize(100, 30);
addValueAt(value1, 10, 10);
}
void run() {
SwingUtilities.invokeLater(new Runnable() {
@Override public void run() {
FRAME.pack();
FRAME.setLocationRelativeTo(null);
FRAME.setVisible(true);
}
});
}
final void addValueAt(ValueComponent val, int x, int y) {
val.setLocation(x, y);
val.addMouseListener(HANDLER);
val.addMouseMotionListener(HANDLER);
FRAME.add(val);
}
/* Handle mouse events */
class MouseHandler extends MouseAdapter
{
@Override public void mousePressed(MouseEvent e) {
printEvent(e, "pressed on");
}
@Override public void mouseReleased(MouseEvent e) {
printEvent(e, "released on");
}
@Override public void mouseDragged(MouseEvent e) {
printEvent(e, "dragged on");
}
void printEvent(MouseEvent e, String message) {
Class c = e.getSource().getClass();
Point p = e.getPoint();
System.out.println(message + " @[" + p.x + "," + p.y
+ "] in " + c.getSimpleName());
}
}
}
/**
* ValueComponet made of
* - a label [JLabel]
* - a text field [MyTextField]
*/
class ValueComponent extends JPanel
{
/**
* Override mouse event processing behaviour:
* directly dispatch events to the parent Component
*/
class MyTextField extends JTextField
{
private MyTextField(String value) {
super(value);
}
@Override protected void processMouseEvent(MouseEvent e) {
getParent().dispatchEvent(e);
}
@Override protected void processMouseMotionEvent(MouseEvent e) {
getParent().dispatchEvent(e);
}
}
MyTextField value;
JLabel label;
ValueComponent(String label, String value) {
this.label = new JLabel(label);
this.value = new MyTextField(value);
this.value.setEditable(false);
setBackground(Color.gray);
setLayout(new FlowLayout(FlowLayout.LEFT));
add(this.label);
add(this.value);
}
}
Non so se è la soluzione migliore in generale e nel tuo caso specifico, ma questa conosco. Se hai un po' di fortuna il thread verrà letto da PGI, che potrà confermare o smentire, così ci sentiremo più tranquilli