java - 当我们在 JPanel 或 GlassPane 外部单击时退出它
问题描述
几天前,我请求帮助将 JPanel 放在其他 CardLayout 面板的顶部,在其中一个用户的帮助下,我使用 GlassPane 实现了它,所以感谢他,但现在我想在我点击外部时关闭它(在应用程序或组件的其他窗口)因为它卡在那里直到我单击设置按钮,我该如何实现?我尝试过失去和获得焦点,但这不适用于面板所以我应该做什么,这是我的一段代码..
JPanel settingsPanel = new JPanel();
settingsPanel.setLayout(null);
settingsPanel.setPreferredSize(
new Dimension(180, 260));
JLabel lblSettingsTitle = new JLabel("Settings");
lblSettingsTitle.setFont(new Font("SansSerif", Font.BOLD |
Font.ITALIC, 18));
lblSettingsTitle.setBounds(5, 8, 200, 35);
settingsPanel.add(lblSettingsTitle);
JSeparator settingsSep = new JSeparator();
settingsSep.setForeground(Color.DARK_GRAY);
settingsSep.setBounds(0, 48, 160, 2);
settingsPanel.add(settingsSep);
JPanel panelLanguage = new JPanel();
panelLanguage.setBounds(0, 61, 200, 30);
settingsPanel.add(panelLanguage);
panelLanguage.setLayout(null);
JPanel pnlLanguage = new JPanel();
pnlLanguage.setBounds(0, 0, 200, 30);
panelLanguage.add(pnlLanguage);
pnlLanguage.setLayout(null);
JLabel lblLanguageIcon = new JLabel("");
lblLanguageIcon.setIcon(new
ImageIcon(frmMain.class.getResource("/image/Language_20px.png")));
lblLanguageIcon.setBounds(5, 5, 20, 20);
pnlLanguage.add(lblLanguageIcon);
JLabel lblLanguage = new JLabel("Choose Language");
lblLanguage.setFont(new Font("SansSerif", Font.ITALIC, 15));
lblLanguage.setBounds(30, 0, 170, 30);
pnlLanguage.add(lblLanguage);
JPanel pnlAlbanian = new JPanel();
pnlAlbanian.setBounds(0, 30, 200, 30);
panelLanguage.add(pnlAlbanian);
pnlAlbanian.setLayout(null);
JLabel lblAlbIcon = new JLabel("");
lblAlbIcon.setIcon(new
ImageIcon(frmMain.class.getResource("/image/albanian.png")));
lblAlbIcon.setBounds(20, 0, 30, 30);
pnlAlbanian.add(lblAlbIcon);
JLabel lblAlbanian = new JLabel("Albanian");
lblAlbanian.setBounds(50, 0, 150, 30);
pnlAlbanian.add(lblAlbanian);
JPanel pnlEnglish = new JPanel();
pnlEnglish.setBounds(0, 60, 200, 30);
panelLanguage.add(pnlEnglish);
pnlEnglish.setLayout(null);
JLabel lblEngIcon = new JLabel("");
lblEngIcon.setIcon(new
ImageIcon(frmMain.class.getResource("/image/britain.png")));
lblEngIcon.setBounds(20, 0, 30, 30);
pnlEnglish.add(lblEngIcon);
JLabel lblEnglish = new JLabel("English");
lblEnglish.setBounds(50, 0, 150, 30);
pnlEnglish.add(lblEnglish);
JPanel pnlAboutUs = new JPanel();
pnlAboutUs.setBounds(0, 120, 200, 30);
settingsPanel.add(pnlAboutUs);
pnlAboutUs.setLayout(null);
JLabel lblAboutIcon = new JLabel("");
lblAboutIcon.setIcon(new
ImageIcon(frmMain.class.getResource("/image/About_20px.png")));
lblAboutIcon.setBounds(5, 5, 20, 20);
pnlAboutUs.add(lblAboutIcon);
JLabel lblAboutUs = new JLabel("About Us");
lblAboutUs.setFont(new Font("SansSerif", Font.ITALIC, 15));
lblAboutUs.setBounds(35, 0, 165, 30);
pnlAboutUs.add(lblAboutUs);
JPanel pnlHelp = new JPanel();
pnlHelp.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent arg0) {
Help obj=new Help();
getGlassPane().setVisible(false);
obj.setVisible(true);
obj.setLocationRelativeTo(null);
}
});
pnlHelp.setLayout(null);
pnlHelp.setBounds(0, 91, 200, 30);
settingsPanel.add(pnlHelp);
JLabel lblHelpIcon = new JLabel("");
lblHelpIcon.setIcon(new
ImageIcon(frmMain.class.getResource("/image/Help_20px.png")));
lblHelpIcon.setBounds(5, 5, 20, 20);
pnlHelp.add(lblHelpIcon);
JLabel lblHelp = new JLabel("Help");
lblHelp.setFont(new Font("SansSerif", Font.ITALIC, 15));
lblHelp.setBounds(35, 0, 165, 30);
pnlHelp.add(lblHelp);
((JComponent) getGlassPane()).setLayout(new
FlowLayout(FlowLayout.LEFT, 260, 390));
((JComponent) getGlassPane()).add(settingsPanel, BorderLayout.EAST);
JLabel lblSettings = new JLabel("");
lblSettings.setHorizontalAlignment(SwingConstants.CENTER);
lblSettings.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent arg0) {
getGlassPane().setVisible(!getGlassPane().isVisible());
}
});
lblSettings.setToolTipText("Settings");
lblSettings.setIcon(new
ImageIcon(frmMain.class.getResource("/image/Settings_24px.png")));
lblSettings.setBounds(210, 600, 50, 50);
menuPanel.add(lblSettings);
解决方案
我稍微修改了我之前的示例,因此设置面板在单击它外部时关闭。
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
public class RightSidePanel implements Runnable {
@Override
public void run() {
JFrame frm = new JFrame("Right side panel");
frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
// next two lines are not required
JPanel contentPanel = new JPanel(new BorderLayout());
frm.setContentPane(contentPanel);
JPanel mainPanel = new JPanel(new CardLayout());
mainPanel.add(new JLabel("It's the first card panel"), "first");
mainPanel.add(new JLabel("It's the second card panel"), "second");
// add some components to provide some width and height for the panel.
mainPanel.add(Box.createHorizontalStrut(600));
mainPanel.add(Box.createVerticalStrut(300));
mainPanel.setBackground(Color.CYAN);
JPanel settingsPanel = new JPanel(new GridLayout(1, 1));
settingsPanel.add(new JLabel("Here is the settings panel!"));
settingsPanel.setPreferredSize(new Dimension(settingsPanel.getPreferredSize().width, 300));
JButton settingsButton = new JButton("Show settings"); // move this line up
((JComponent) frm.getGlassPane()).setLayout(new FlowLayout(FlowLayout.RIGHT, 0, 0));
((JComponent) frm.getGlassPane()).add(settingsPanel);
// added code here
frm.getGlassPane().addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
// check whether the click on the glass pane.
Component c = SwingUtilities.getDeepestComponentAt(frm.getGlassPane(), e.getX(), e.getY());
if (e.getComponent().equals(c)) {
updateButton(frm, settingsButton);
}
}
});
// end of the added code
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 10, 10));
settingsButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// move the method content to a separate method
updateButton(frm, settingsButton);
}
});
JButton switchButton = new JButton("Show second");
switchButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
CardLayout cl = (CardLayout) mainPanel.getLayout();
if (mainPanel.getComponent(0).isVisible()) {
cl.show(mainPanel, "second");
switchButton.setText("Show first");
} else {
cl.show(mainPanel, "first");
switchButton.setText("Show second");
}
}
});
buttonPanel.add(switchButton);
buttonPanel.add(settingsButton);
frm.add(mainPanel, BorderLayout.CENTER);
frm.add(buttonPanel, BorderLayout.SOUTH);
frm.pack();
frm.setLocationRelativeTo(null);
frm.setVisible(true);
}
private void updateButton(JFrame frm, JButton settingsButton) {
frm.getGlassPane().setVisible(!frm.getGlassPane().isVisible());
if (frm.getGlassPane().isVisible()) {
settingsButton.setText("Hide settings");
} else {
settingsButton.setText("Show settings");
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new RightSidePanel());
}
}
推荐阅读
- json - JSON模式验证数组的头部和尾部
- firebase - 如何从 Firebase 获取随机孩子
- sql-server - 如何记录存储过程执行运行时间
- unit-testing - Mockito - Kotlin 测试在尝试捕获 Pageable 参数时抛出空指针异常
- sql - 如何在 postgresql 中使用带有数组列的 GIN 索引?
- javascript - React - 通过链接到浏览器页面时如何更改样式
- reactjs - React 索引保持相同的值 (0)
- javascript - 获取 TypeError:尝试设置 props.children 时 props.children 不是函数
- java - com.google.firebase.database.DatabaseException:无法将 java.lang.String 类型的对象转换为 com.example.gatewayrestaurant.model1 类型
- appium - 错误:Appium iOS 真机上超过 1000ms 的超时