【问题标题】:How to keep a JButton pressed after its JPanel loses focus如何在 JPanel 失去焦点后保持按下 JButton
【发布时间】:2011-09-27 00:39:01
【问题描述】:

我发现了如何使用以下代码将 JButton 保持在按下状态:

JButton[] buttons;
.
.
.
public void actionPerformed(ActionEvent e)
{

    for(int i = 0; i < buttons.length; i++)
    {
        if(e.getSource() == buttons[i])
        {
            buttons[i].getModel().setPressed(true);
        }
        else
        {
            buttons[i].getModel().setPressed(false);
        }

    }
}

此代码捕获单击的按钮,使其保持按下状态,并使面板上的所有其他按钮未按下。这段代码效果很好......直到窗口失去焦点(或者更具体地说,它的父 JPanel 失去焦点)。之后,所有的按钮都返回到非按下状态。

现在关于如何编写 WindowFocusListeners 的教程已经下架。有没有办法让 JButton 的按下状态在失去焦点时保持不变?

【问题讨论】:

  • 选择一个答案小伙伴。你问这个已经快 4 年了

标签: java swing jbutton


【解决方案1】:

为什么不简单地使用一系列 JToggleButtons 并将它们添加到同一个 ButtonGroup 对象?所有艰苦的工作都为您完成,因为切换按钮被构建为在按下时保持按下状态。将其视为看起来像 JButton 的 JRadioButton(因为实际上,JRadioButton 下降自 JToggleButton)。

例如:

import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;

public class BunchOfButtons extends JPanel {
   private static final String[] TEXTS = {"One", "Two", "Three", "Four", "Five"};
   private ButtonGroup btnGroup = new ButtonGroup();
   private JTextField textField = new JTextField(20);

   public BunchOfButtons() {
      JPanel btnPanel = new JPanel(new GridLayout(1, 0, 5, 0));
      BtnListener btnListener = new BtnListener();
      for (String text : TEXTS) {
         JToggleButton toggleBtn = new JToggleButton(text);
         toggleBtn.addActionListener(btnListener);
         toggleBtn.setActionCommand(text);
         btnPanel.add(toggleBtn);
         btnGroup.add(toggleBtn);
      }

      JPanel otherPanel = new JPanel();
      otherPanel.add(textField ); // just to take focus elsewhere

      setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
      setLayout(new GridLayout(0, 1, 0, 15));
      add(btnPanel);
      add(otherPanel);
   }

   private class BtnListener implements ActionListener {
      public void actionPerformed(ActionEvent aEvt) {
         textField.setText(aEvt.getActionCommand());
      }
   }

   private static void createAndShowGui() {
      BunchOfButtons mainPanel = new BunchOfButtons();

      JFrame frame = new JFrame("BunchOfButtons");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

【讨论】:

  • 你一针见血@Hovercraft Full Of Eels +1
  • private class???我以前从未见过这样的事情。你能详细说明(为我)吗?
  • 这是一个私有内部类,仅此而已。它只能在外部类内部使用,就像匿名内部类一样,但与匿名类不同,它可以多次使用。
  • @fireshadow52:澄清一下,从匿名内部类派生的对象可能会被多次使用,但您只能使用它创建一个对象,而对于私有内部类,您可以调用 new MyPrivateInnerClass( ...) 根据需要多次。
  • 我应该把 private class soSo 导入到哪里?在外部类的进口产品的顶部?我想这是有道理的,但不确定
猜你喜欢
  • 1970-01-01
  • 2012-07-19
  • 2023-03-16
  • 1970-01-01
  • 1970-01-01
  • 2012-09-12
  • 2018-03-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多