Check out the code below. Save it as DesktopTest.java, compile & run - it's pretty straightforward.
It's a desktop with 3 internal frames. One contains a JButton, while two of them contains a custom JComponent that is a black square which turns blue when the mouse is over it.
The problem is - mouseClicked() isn't caught on the custom component if the JInternalFrame doesn't have focus - but the button does! .. also - mouseEntered() / mouseExited() doesn't care about the focus ..
Can anyone explain this to me? Or maybe show me what I need to do to make the 'squares' respond on first-click ?
Here goes:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class DesktopTest extends JFrame {
public DesktopTest() {
setSize(600,600);
JDesktopPane desktop = new JDesktopPane();
JInternalFrame frame1 = new JInternalFrame();
frame1.setSize(200,200);
frame1.setLocation(100,100);
frame1.setVisible(true);
frame1.getContentPane().add(new SquarePanel("Square 1"));
JInternalFrame frame2 = new JInternalFrame();
frame2.setSize(200,200);
frame2.setLocation(300,400);
frame2.setVisible(true);
JButton button = new JButton("Click me!");
button.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("Button clicked!");
}
});
frame2.getContentPane().add(button);
JInternalFrame frame3 = new JInternalFrame();
frame3.setSize(200,200);
frame3.setLocation(200,300);
frame3.getContentPane().add(new SquarePanel("Square 2"));
frame3.setVisible(true);
desktop.add(frame1);
desktop.add(frame2);
desktop.add(frame3);
Container c = this.getContentPane();
c.add(desktop);
}
class SquarePanel extends JPanel implements MouseListener {
private OneSquare one;
public SquarePanel(String name) {
one = new OneSquare(name);
one.addMouseListener(this);
this.add(one);
}
public void mouseClicked(MouseEvent e) {
System.out.println(one + " clicked!");
}
public void mousePressed(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {
one.setMouseOver(true);
one.repaint();
}
public void mouseExited(MouseEvent e) {
one.setMouseOver(false);
one.repaint();
}
}
class OneSquare extends JComponent {
private String name;
private boolean mouseover = false;
public OneSquare(String name) {
this.name = name;
setPreferredSize(new Dimension(100,100));
}
public void setMouseOver(boolean mouseover) {
this.mouseover = mouseover;
}
public String toString() { return name; }
public void paintComponent(Graphics g) {
super.paintComponent(g);
if(mouseover) {
g.setColor(Color.blue);
} else {
g.setColor(Color.black);
}
g.fillRect(0,0,100,100);
g.setColor(Color.white);
g.drawString(name,10,10);
}
}
public static void main(String args[]) {
DesktopTest t = new DesktopTest();
t.show();
}
}
It's a desktop with 3 internal frames. One contains a JButton, while two of them contains a custom JComponent that is a black square which turns blue when the mouse is over it.
The problem is - mouseClicked() isn't caught on the custom component if the JInternalFrame doesn't have focus - but the button does! .. also - mouseEntered() / mouseExited() doesn't care about the focus ..
Can anyone explain this to me? Or maybe show me what I need to do to make the 'squares' respond on first-click ?
Here goes:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class DesktopTest extends JFrame {
public DesktopTest() {
setSize(600,600);
JDesktopPane desktop = new JDesktopPane();
JInternalFrame frame1 = new JInternalFrame();
frame1.setSize(200,200);
frame1.setLocation(100,100);
frame1.setVisible(true);
frame1.getContentPane().add(new SquarePanel("Square 1"));
JInternalFrame frame2 = new JInternalFrame();
frame2.setSize(200,200);
frame2.setLocation(300,400);
frame2.setVisible(true);
JButton button = new JButton("Click me!");
button.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("Button clicked!");
}
});
frame2.getContentPane().add(button);
JInternalFrame frame3 = new JInternalFrame();
frame3.setSize(200,200);
frame3.setLocation(200,300);
frame3.getContentPane().add(new SquarePanel("Square 2"));
frame3.setVisible(true);
desktop.add(frame1);
desktop.add(frame2);
desktop.add(frame3);
Container c = this.getContentPane();
c.add(desktop);
}
class SquarePanel extends JPanel implements MouseListener {
private OneSquare one;
public SquarePanel(String name) {
one = new OneSquare(name);
one.addMouseListener(this);
this.add(one);
}
public void mouseClicked(MouseEvent e) {
System.out.println(one + " clicked!");
}
public void mousePressed(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {
one.setMouseOver(true);
one.repaint();
}
public void mouseExited(MouseEvent e) {
one.setMouseOver(false);
one.repaint();
}
}
class OneSquare extends JComponent {
private String name;
private boolean mouseover = false;
public OneSquare(String name) {
this.name = name;
setPreferredSize(new Dimension(100,100));
}
public void setMouseOver(boolean mouseover) {
this.mouseover = mouseover;
}
public String toString() { return name; }
public void paintComponent(Graphics g) {
super.paintComponent(g);
if(mouseover) {
g.setColor(Color.blue);
} else {
g.setColor(Color.black);
}
g.fillRect(0,0,100,100);
g.setColor(Color.white);
g.drawString(name,10,10);
}
}
public static void main(String args[]) {
DesktopTest t = new DesktopTest();
t.show();
}
}