- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
是否有可能在执行操作的方法中有一个关键事件,因为我正在为 gui 使用操作监听器,但我想在某个按键按下时关闭我的应用程序
最佳答案
您可以使用 AbstractAction,它就像类固醇的 ActionListener,然后通过按钮的 setAction(...)
方法将它分配给您的 JButton,因为它是 Action。然后我会使用 Key Bindings ,而不是 KeyListener,因为这将使我们能够轻松解决 KeyListener 组件焦点问题,并使用键绑定(bind)将完全相同的 AbstractAction 绑定(bind)到您的按键。
请注意,如果您正确设置了 JButton 或 AbstractAction 的助记符,则 alt 组合键将自动在按下按钮时起作用。
下面的这个对你来说可能有点过头了,但它允许在键绑定(bind)、JButton 或 JMenuItem 中使用相同的操作,这有点棘手。
// class of mine to allow disposing of a window
// It's a little complex to allow it to work with either a JButton
// or a JMenuItem
@SuppressWarnings("serial")
class ExitAction extends AbstractAction {
public ExitAction() {
super("Exit");
putValue(MNEMONIC_KEY, KeyEvent.VK_X);
}
@Override
public void actionPerformed(ActionEvent e) {
// get the button that caused this action
Object source = e.getSource();
Window topWindow = null;
if (source instanceof AbstractButton) {
AbstractButton exitButton = (AbstractButton) source;
// get the parent top level window
topWindow = SwingUtilities.getWindowAncestor(exitButton);
if (topWindow == null) { // if null, then likely in a JMenuItem
// so we have to get its jpopupmenu parent
Container parent = exitButton.getParent();
if (parent instanceof JPopupMenu) {
JPopupMenu popupMenu = (JPopupMenu) parent;
// get the invoker for the pop up menu
Component invoker = popupMenu.getInvoker();
if (invoker != null) {
// and get *its* top level window
topWindow = SwingUtilities.getWindowAncestor(invoker);
}
}
}
} else if (source instanceof Component) {
// if in key bindings
topWindow = SwingUtilities.getWindowAncestor((Component) source);
}
if (topWindow != null) {
// dispose of the top-level window
topWindow.dispose();
}
}
}
这是我为 another StackOverflow question 创建的演示程序.这是完整的代码。它还演示了 CardLayout 的使用:
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.AbstractButton;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.BorderFactory;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
/**
* https://stackoverflow.com/questions/30288947
* /accessing-jcombobox-data-from-separate-jform
*
* @author Pete
*
*/
public class SimpleMultPanels {
private static void createAndShowGui() {
// create JFrame
JFrame frame = new JFrame("SimpleMultPanels");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
// add our MainPanel to the JFrame
frame.getContentPane().add(new MainPanel());
frame.pack(); // pack it
frame.setLocationByPlatform(true);
frame.setVisible(true); // show it
}
public static void main(String[] args) {
// this is for starting our Swing app on the event thread
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
@SuppressWarnings("serial")
class MainPanel extends JPanel {
private static final KeyStroke EXIT_KEY_STROKE = KeyStroke.getKeyStroke(
KeyEvent.VK_Z, KeyEvent.CTRL_DOWN_MASK);;
private CardLayout cardLayout = new CardLayout();
// the three "card" JPanels that this JPanel displays:
private MenuPanel menuPanel = new MenuPanel();
private HoldsComboBoxPanel holdsComboBoxPanel = new HoldsComboBoxPanel();
private ShowSelectionPanel showSelectionPanel = new ShowSelectionPanel();
// Actions for our JButtons
private ExitAction exitAction = new ExitAction();
private ShowAction backToMenuAction = new ShowAction(this, "Back to Menu",
MenuPanel.NAME, KeyEvent.VK_B);
private ShowAction toHoldsComboAction = new ShowAction(this, "Combo Panel",
HoldsComboBoxPanel.NAME, KeyEvent.VK_C);
private ShowAction toShowSelectionAction = new ShowAction(this,
"Show Selection", ShowSelectionPanel.NAME, KeyEvent.VK_S);
public MainPanel() {
// add an ActionListener to the JComboBox
holdsComboBoxPanel.addComboBoxListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// get the combo's selected String
String selection = holdsComboBoxPanel.getComboSelection();
if (selection != null) {
// push it into showSelection
showSelectionPanel.setDisplayText(selection);
}
}
});
// add Actions to class to allow swapping of cards and
holdsComboBoxPanel.addButtonAction(backToMenuAction);
holdsComboBoxPanel.addButtonAction(toShowSelectionAction);
holdsComboBoxPanel.addButtonAction(exitAction); // and to exit gui
showSelectionPanel.addButtonAction(backToMenuAction);
showSelectionPanel.addButtonAction(toHoldsComboAction);
showSelectionPanel.addButtonAction(exitAction);
menuPanel.addButtonAction(toHoldsComboAction);
menuPanel.addButtonAction(toShowSelectionAction);
menuPanel.addButtonAction(exitAction);
setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
// set our layout
setLayout(cardLayout);
// and add our "card" JPanels
add(menuPanel, MenuPanel.NAME);
add(holdsComboBoxPanel, HoldsComboBoxPanel.NAME);
add(showSelectionPanel, ShowSelectionPanel.NAME);
setExitOnKeyStroke(EXIT_KEY_STROKE); // added 9/27/15
}
private void setExitOnKeyStroke(KeyStroke keyStroke) {
// do your key bindings
// first get ActionMap and InputMap
InputMap inputMap = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap actionMap = getActionMap();
// then the keystroke
String key = keyStroke.toString();
inputMap.put(keyStroke, key); // map the keystroke to a String key
actionMap.put(key, exitAction); // map the same String key to the Action
}
// method that allows outside classes to swap views
public void showCard(String key) {
cardLayout.show(this, key);
}
}
@SuppressWarnings("serial")
class HoldsComboBoxPanel extends JPanel {
// constant String that will be used by the CardLayout
public static final String NAME = "holds combobox panel";
// sample data
private static final String[] DATA = { "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday" };
private JComboBox<String> comboBox = new JComboBox<>(DATA);
// JPanel to hold buttons to allow moving between cards
private JPanel buttonPanel = new JPanel(new GridLayout(1, 0, 5, 0));
public HoldsComboBoxPanel() {
comboBox.setSelectedIndex(-1);
JPanel centerPanel = new JPanel();
centerPanel.add(comboBox);
setLayout(new BorderLayout());
add(centerPanel, BorderLayout.CENTER);
add(buttonPanel, BorderLayout.SOUTH);
}
// method to add a listener
public void addComboBoxListener(ActionListener listener) {
comboBox.addActionListener(listener);
}
// getter method
public String getComboSelection() {
return (String) comboBox.getSelectedItem();
}
// create a new JButton with an Action and add to buttonPanel
public void addButtonAction(Action action) {
buttonPanel.add(new JButton(action));
}
}
@SuppressWarnings("serial")
class ShowSelectionPanel extends JPanel {
public static final String NAME = "show selection panel";
private static final int PREF_W = 300;
private static final int PREF_H = PREF_W;
private JTextField displayField = new JTextField(10);
private JPanel buttonPanel = new JPanel(new GridLayout(1, 0, 5, 0));
public ShowSelectionPanel() {
displayField.setFocusable(false);
JPanel centerPanel = new JPanel();
centerPanel.add(displayField);
setLayout(new BorderLayout());
add(centerPanel, BorderLayout.CENTER);
add(buttonPanel, BorderLayout.SOUTH);
}
// code to make our GUI a little larger
@Override
public Dimension getPreferredSize() {
Dimension superSz = super.getPreferredSize();
if (isPreferredSizeSet()) {
return superSz;
}
int prefW = Math.max(superSz.width, PREF_W);
int prefH = Math.max(superSz.height, PREF_H);
return new Dimension(prefW, prefH);
}
// setter method
public void setDisplayText(String text) {
displayField.setText(text);
// or do whatever else you want to do with the selection
}
public void addButtonAction(Action action) {
buttonPanel.add(new JButton(action));
}
}
@SuppressWarnings("serial")
class MenuPanel extends JPanel {
public static final String NAME = "menu panel";
private JPanel buttonPanel = new JPanel(new GridLayout(0, 1, 0, 5));
public MenuPanel() {
setLayout(new GridBagLayout());
add(buttonPanel);
}
public void addButtonAction(Action action) {
buttonPanel.add(new JButton(action));
}
}
@SuppressWarnings("serial")
class ShowAction extends AbstractAction {
private MainPanel mainPanel;
private String key;
/**
* Abstract Action used by JButtons
*
* @param mainPanel
* : the JPanel that uses the CardLayout
* @param name
* : The name displayed by the button
* @param key
* : The key used in the CardLayout#show(String key) mehtod
* @param mnemonic
* : the JButton's mnemonic char
*/
public ShowAction(MainPanel mainPanel, String name, String key, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
this.mainPanel = mainPanel;
this.key = key;
}
@Override
public void actionPerformed(ActionEvent e) {
// tell the mainPanel to show the card associated with the key
mainPanel.showCard(key);
}
}
// class of mine to allow disposing of a window
// It's a little complex to allow it to work with either a JButton
// or a JMenuItem
@SuppressWarnings("serial")
class ExitAction extends AbstractAction {
public ExitAction() {
super("Exit");
putValue(MNEMONIC_KEY, KeyEvent.VK_X);
}
@Override
public void actionPerformed(ActionEvent e) {
// get the button that caused this action
Object source = e.getSource();
Window topWindow = null;
if (source instanceof AbstractButton) {
AbstractButton exitButton = (AbstractButton) source;
// get the parent top level window
topWindow = SwingUtilities.getWindowAncestor(exitButton);
if (topWindow == null) { // if null, then likely in a JMenuItem
// so we have to get its jpopupmenu parent
Container parent = exitButton.getParent();
if (parent instanceof JPopupMenu) {
JPopupMenu popupMenu = (JPopupMenu) parent;
// get the invoker for the pop up menu
Component invoker = popupMenu.getInvoker();
if (invoker != null) {
// and get *its* top level window
topWindow = SwingUtilities.getWindowAncestor(invoker);
}
}
}
} else if (source instanceof Component) {
// if in key bindings
topWindow = SwingUtilities.getWindowAncestor((Component) source);
}
if (topWindow != null) {
// dispose of the top-level window
topWindow.dispose();
}
}
}
如果您在 MainPanel 类中添加此方法并在 MainPanel 的构造函数中调用它,您会将退出操作绑定(bind)到所选的击键:
private void setExitOnKeyStroke(KeyStroke keyStroke) {
// do your key bindings
// first get ActionMap and InputMap
InputMap inputMap = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap actionMap = getActionMap();
// then the keystroke
String key = keyStroke.toString();
inputMap.put(keyStroke, key); // map the keystroke to a String key
actionMap.put(key, exitAction); // map the same String key to the Action
}
// method that allows outside classes to swap views
public void showCard(String key) {
cardLayout.show(this, key);
}
}
关于java - 主要听众和执行的操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32813251/
我正在努力做到这一点 在我的操作中从数据库获取对象列表(确定) 在 JSP 上打印(确定) 此列表作为 JSP 中的可编辑表出现。我想修改然后将其提交回同一操作以将其保存在我的数据库中(失败。当我使用
我有以下形式的 Linq to Entities 查询: var x = from a in SomeData where ... some conditions ... select
我有以下查询。 var query = Repository.Query() .Where(p => !p.IsDeleted && p.Article.ArticleSections.Cou
我正在编写一个应用程序包,其中包含一个主类,其中主方法与GUI类分开,GUI类包含一个带有jtabbedpane的jframe,它有两个选项卡,第一个选项卡包含一个jtable,称为jtable1,第
以下代码产生错误 The nested query is not supported. Operation1='Case' Operation2='Collect' 问题是我做错了什么?我该如何解决?
我已经为 HA redis 集群(2 个副本、1 个主节点、3 个哨兵)设置了本地 docker 环境。只有哨兵暴露端口(10021、10022、10023)。 我使用的是 stackexchange
我正在 Desk.com 中构建一个“集成 URL”,它使用 Shopify Liquid 模板过滤器语法。对于开始日期为 7 天前而结束日期为现在的查询,此 URL 需要包含“开始日期”和“结束日期
你一定想过。然而情况却不理想,python中只能使用类似于 i++/i--等操作。 python中的自增操作 下面代码几乎是所有程序员在python中进行自增(减)操作的常用
我需要在每个使用 github 操作的手动构建中显示分支。例如:https://gyazo.com/2131bf83b0df1e2157480e5be842d4fb 我应该显示分支而不是一个。 最佳答
我有一个关于 Perl qr 运算符的问题: #!/usr/bin/perl -w &mysplit("a:b:c", /:/); sub mysplit { my($str, $patt
我已经使用 ArgoUML 创建了一个 ERD(实体关系图),我希望在一个类中创建两个操作,它们都具有 void 返回类型。但是,我只能创建一个返回 void 类型的操作。 例如: 我能够将 book
Github 操作仍处于测试阶段并且很新,但我希望有人可以提供帮助。我认为可以在主分支和拉取请求上运行 github 操作,如下所示: on: pull_request push: b
我正在尝试创建一个 Twilio 工作流来调用电话并记录用户所说的内容。为此,我正在使用 Record,但我不确定要在 action 参数中放置什么。 尽管我知道 Twilio 会发送有关调用该 UR
我不确定这是否可行,但值得一试。我正在使用模板缓冲区来减少使用此算法的延迟渲染器中光体积的过度绘制(当相机位于体积之外时): 使用廉价的着色器,将深度测试设置为 LEQUAL 绘制背面,将它们标记在模
有没有聪明的方法来复制 和 重命名 文件通过 GitHub 操作? 我想将一些自述文件复制到 /docs文件夹(:= 同一个 repo,不是远程的!),它们将根据它们的 frontmatter 重命名
我有一个 .csv 文件,其中第一列包含用户名。它们采用 FirstName LastName 的形式。我想获取 FirstName 并将 LastName 的第一个字符添加到它上面,然后删除空格。然
Sitecore 根据 Sitecore 树中定义的项目名称生成 URL, http://samplewebsite/Pages/Sample Page 但我们的客户有兴趣降低所有 URL(页面/示例
我正在尝试进行一些计算,但是一旦我输入金额,它就会完成。我只是希望通过单击按钮而不是自动发生这种情况。 到目前为止我做了什么: Angular JS - programming-fr
我的公司创建了一种在环境之间移动文件的复杂方法,现在我们希望将某些构建的 JS 文件(已转换和缩小)从一个 github 存储库移动到另一个。使用 github 操作可以实现这一点吗? 最佳答案 最简
在我的代码中,我创建了一个 JSONArray 对象。并向 JSONArray 对象添加了两个 JSONObject。我使用的是 json-simple-1.1.jar。我的代码是 package j
我是一名优秀的程序员,十分优秀!