另一种不中断 Swing 事件链的解决方案是使用 aAWTEventListener
代替。我已经实现了 aBetterGlassPane
来代替常规的JPanel
玻璃窗格,如下所示:
JFrame frame = ...; // any JRootPane will do...
BetterGlassPane glass = new BetterGlassPane(frame);
这也适用于“传统”方式,如您的问题所示:
JPanel glass = new BetterGlassPane();
frame.setGlassPane(glass);
glass.setRootPane(frame);
希望这可以帮助。随意在 GitHub 上克隆项目或使用 Maven 依赖项:
<dependency>
<groupId>lc.kra.swing</groupId>
<artifactId>better-glass-pane</artifactId>
<version>0.1.3</version>
</dependency>
<repositories>
<repository>
<id>better-glass-pane-mvn-repo</id>
<url>https://raw.github.com/kristian/better-glass-pane/mvn-repo/</url>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</snapshots>
</repository>
</repositories>
简短、自包含、正确、示例(SSCCE,没有强制性的 Maven 依赖):
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import lc.kra.swing.BetterGlassPane;
public class TestBetterGlassPane {
public static void main(String[] args) {
final JFrame frame = new JFrame("BetterGlassPane Test");
frame.setLayout(null);
frame.setSize(400,300);
frame.setResizable(false);
frame.setLocationByPlatform(true);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
BetterGlassPane glassPane = new BetterGlassPane(frame.getRootPane()) {
private static final long serialVersionUID = 1L;
@Override protected void paintComponent(Graphics graphics) {
super.paintComponent(graphics);
graphics.setColor(Color.BLACK);
graphics.drawRect(20,160,360,50);
graphics.setFont(graphics.getFont().deriveFont(Font.BOLD));
graphics.drawString("I'm the glass pane, click me!",120,190);
}
};
glassPane.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent event) {
if(new Rectangle(20,180,360,50).contains(event.getPoint()))
JOptionPane.showMessageDialog(frame,"I'm the glass pane!");
}
});
glassPane.setLayout(null);
ActionListener defaultActionListener = new ActionListener() {
public void actionPerformed(ActionEvent event) {
JOptionPane.showMessageDialog(frame,
((JButton)event.getSource()).getText());
}
};
JButton frameButton = new JButton("I'm on the frame!");
frameButton.addActionListener(defaultActionListener);
frameButton.setBounds(20,20,360,50);
frame.add(frameButton);
JButton glassPaneButton = new JButton("I'm on the glass pane!");
glassPaneButton.addActionListener(defaultActionListener);
glassPaneButton.setBounds(20,90,360,50);
glassPane.add(glassPaneButton);
frame.setVisible(true);
}
}