【问题标题】:Button cursor doesn't display right按钮光标不正确显示
【发布时间】:2015-08-02 07:07:15
【问题描述】:

我有带有 2 个 jpanels 的 jframe。我在第一个 jpanel 上有一些组件,在第二个上有按钮。当我单击第一个面板上的 jbuton(调用方法 removeAll)时,它会删除该 jpanel 中的所有组件(我调用方法 revalidate()、repaint()),然后我显示带有组件的第二个面板。长话短说,我删除第一个 jpanel 显示第二个,第二个显示在 jframe 上,... 在 jpanel 之间切换工作正常,当我切换回第一个 jpanel 光标手型时按钮不显示,而是出现正常光标。手形光标类型的工作第一次很好,但是当我切换回第一个 jpanel 时,它又恢复为默认值...

按钮的实现:

        button = new JButton(icon);
        button.setText("OK");
        button.setHorizontalTextPosition(SwingConstants.LEFT);
        button.setFocusPainted(false);
        button.setCursor(new Cursor(Cursor.HAND_CURSOR));

当我切换到第二个 jpanel 然后回到第一个 jpanel 时,按钮上的光标当然不会出现(“手形光标”)。

当我在框架上的 jpanels 之间切换时,我希望该按钮保持手型光标...

【问题讨论】:

  • @dic19 听起来很丑陋。
  • 我不确定您是否需要 MouseListener。请写一个minimal example program,我们可以对其进行测试和修改,以向我们显示您的问题。请注意,如果这是我的程序,我只需使用 CardLayout 交换 JPanel。
  • 我将鼠标监听器应用到按钮,但它没有将光标设置为手型...
  • 你能给我一些很好的例子,如何实现卡片布局以在 jpanel 之间切换吗?我正在使用 MigLayout ...
  • 我想当我通过删除组件在 jpanel 之间切换时会发生一些奇怪的事情......我认为我通过删除组件在 jpanel 之间切换的方法是不正确的......

标签: java swing button cursor


【解决方案1】:

关于与 CardLayout 交换的最佳示例,请查看 CardLayout tutorial,但此示例显示交换 JPanel 后按钮的光标没有问题:

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import javax.swing.*;

@SuppressWarnings("serial")
public class TestHandCursor extends JPanel {
   private static final int PREF_W = 400;
   private static final int PREF_H = 300;

   // the cardlayout:
   private CardLayout cardLayout = new CardLayout();

   // the cardlayout using JPanel
   private JPanel cardHolderPanel = new JPanel(cardLayout);

   // the action that a button uses to swap cards
   private SwapCardAction swapCardAction = new SwapCardAction("Swap View");
   private JButton swapButton = new JButton(swapCardAction);

   public TestHandCursor() {
      // set up button's cursor
      swapButton.setFocusPainted(false);
      swapButton.setCursor(new Cursor(Cursor.HAND_CURSOR));

      // dummy JPanels to add to the CardLayout-using JPanel
      JPanel panel1 = new JPanel();
      panel1.add(new JLabel("Panel 1"));
      panel1.add(new JButton("Button 1"));

      String[] items = { "Stormy Monday", "Tuesday's Just as Bad",
            "Wednesday's Worse", "Thursday's Oh So Sad" };
      JPanel panel2 = new JPanel();
      panel2.add(new JLabel("Panel 2"));
      panel2.add(new JComboBox<String>(items));

      JPanel panel3 = new JPanel();
      panel3.add(new JLabel("Panel 3"));

      // add above JPanels to the cardHolderPanel:
      cardHolderPanel.add(panel1, "panel 1");
      cardHolderPanel.add(panel2, "panel 2");
      cardHolderPanel.add(panel3, "panel 3");

      // panel to hold JButton
      JPanel bottomPanel = new JPanel();
      bottomPanel.add(swapButton);

      // add all to the main JPanel
      setLayout(new BorderLayout());
      add(cardHolderPanel, BorderLayout.CENTER);
      add(bottomPanel, BorderLayout.PAGE_END);
   }

   // let's make our GUI a little bigger
   @Override
   public Dimension getPreferredSize() {
      Dimension superSize = super.getPreferredSize();
      if (isPreferredSizeSet()) {
         return superSize;
      }

      int prefW = Math.max(superSize.width, PREF_W);
      int prefH = Math.max(superSize.height, PREF_H);
      return new Dimension(prefW, prefH);
   }

   // button Action to swap "cards" in our CardLayout
   private class SwapCardAction extends AbstractAction {
      public SwapCardAction(String name) {
         super(name);
         int mnemonic = (int) name.charAt(0);
         putValue(MNEMONIC_KEY, mnemonic);
      }

      @Override
      public void actionPerformed(ActionEvent e) {
         cardLayout.next(cardHolderPanel);
      }
   }

   private static void createAndShowGui() {
      JFrame frame = new JFrame("TestHandCursor");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(new TestHandCursor());
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

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

【讨论】:

  • 我会尝试在我的程序中实现这种方法。
  • @slodevelepor:去吧。我的示例非常简单,仅在 CardLayout 对象上调用 next(...),但您可能会调用其他方法,包括 show(...)
  • @slodevelepor:我最近的另一个例子显示了对 CardLayout 的使用更加复杂,可以找到here
  • Tnx 你非常,非常,非常!我在我的项目中包含了这个布局,现在我对那个东西没有任何问题!
猜你喜欢
  • 1970-01-01
  • 2014-04-08
  • 2021-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多