3

最初に適切にカスタマイズされたGUIを作成しようとしていますが、コンポーネント用にペイントされたイメージを変更するのに問題があります。基本的に、exitButton(JMenu)の場合、paintメソッドを上書きしてから、Mouseリスナーを追加しますが、MouseenteredメソッドとmouseexitedメソッドのmouseListenerインターフェイス内で画像を再ペイントする方法がわかりません。基本的に画像を塗り直す方法を探していますが、何ができるのか迷っています。どんな助けでも大歓迎です。

関連するコードスニペットは次のとおりです。

exitBtn = new JMenu(){
       @Override
       protected void paintComponent(Graphics g) {
        super.paintComponent(g);
           ImageIcon exitBtnImg = new ImageIcon("src/images/userInterface/exitBtn.gif");
           g.drawImage(exitBtnImg.getImage(), 0, 5, null);
      }
  };
  exitBtn.setOpaque(false);
  exitBtn.setEnabled(false);
  exitBtn.setPreferredSize(new Dimension(43, 18));
  exitBtn.addMouseListener(new MouseListener() {
        @Override
        public void mousePressed(MouseEvent me) {
        }
        @Override
        public void mouseClicked(MouseEvent me) {
            System.exit(0);
        }
        @Override
        public void mouseEntered(MouseEvent me) {
            //ImageIcon exitBtnImg = new ImageIcon("src/images/exitBtn_hover.gif"); //The ImageIcon for the Image I want to use
            System.out.println("mouse entered");

        }
        @Override
        public void mouseExited(MouseEvent me) {
            // ImageIcon exitBtnImg = new ImageIcon("src/images/exitBtn.gif"); 

System.out.println( "マウスが終了しました"); //元の画像の画像アイコン}@Overridepublic void mouseReleased(MouseEvent me){}});

4

3 に答える 3

6

初めて適切にカスタマイズされた GUI を作成しようとしています

Swing チュートリアルを読むことから始めてください。あなたが何をしようとしているのかはよくわかりませんが、あなたのアプローチは確かに間違っているようです。

ActionListener を使用してマウス クリックを処理する方法を示すメニューの使用方法から始めることができます。マウス クリックは通常、メニューではなくメニュー項目で処理されます。通常、「終了」メニュー項目を含む「ファイル」メニューのようなものがあります。

次に、JMenu API のさまざまなメソッドを調べて、メニューにカーソルを合わせるか選択したときにアイコンを変更できるようにします。おそらく setRolloverEnabled()、setRolloverIcon() が探しているものです。

それでも問題が解決しない場合は、問題を示すSSCCEを投稿してください。

アップデート:

Hovercraft で述べたように、ロールオーバー サポートはメニューまたはメニュー項目では機能しません。2 つの問題があります。まず、これらのコンポーネントによって別の MouseListener が使用されます。リスナーは、mouseEntered および mouseExited イベントをリッスンしません。2 つ目の問題は、2 つのコンポーネントの UI がカスタマイズされており、カスタムのアイコン描画コードがボタンのロールオーバー状態を考慮していないことです。

MouseListener の追加は簡単です。ロールオーバーを適切にサポートするための UI のカスタマイズ (適切なソリューション) は、より複雑です。

うまくいくように見える単純なハックとして、ペイントするアイコンを UI に決定させるのではなく、MouseListener で Icon を更新するだけです。この要件を忘れて、メニューやメニュー項目のアイコンを変更しない通常の UI を使用することをお勧めします。以下は自己責任で使用してください。

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class ButtonRollover extends JFrame
{
    Icon normal;
    Icon rollover;
    Icon selected;

    public ButtonRollover()
    {
        MouseListener ml = new RolloverButtonListener();

        normal = new ColorIcon(Color.GREEN, 10, 10);
        rollover = new ColorIcon(Color.RED, 10, 10);
        selected = new ColorIcon(Color.BLUE, 10, 10);

        setLayout( new FlowLayout() );

        JMenuBar menuBar = new JMenuBar();
        setJMenuBar( menuBar );

        JMenu menu = (JMenu)createButton(new JMenu(), "Menu");
        menu.addMouseListener( ml );
        menuBar.add( menu );

        JMenuItem menuItem = (JMenuItem)createButton(new JMenuItem(), "MenuItem");
        menuItem.addMouseListener( ml );
        menu.add( menuItem );

        JButton button = (JButton)createButton(new JButton(), "Button");
        add( button );

        JCheckBox checkBox = (JCheckBox)createButton(new JCheckBox(), "CheckBox");
        add( checkBox );

        JRadioButton radioButton = (JRadioButton)createButton(new JRadioButton(), "RadioButton");
        add( radioButton );
    }


    public AbstractButton createButton(AbstractButton button, String text)
    {
        button.setText( text );
        button.setIcon( normal );
        button.setSelectedIcon( selected );
        button.setRolloverIcon( rollover );
        button.setRolloverSelectedIcon( rollover );

        System.out.println( text );
        MouseListener[] mls = button.getMouseListeners();

        for (MouseListener ml: mls)
        {
            System.out.println( "\t" + ml);
        }

        return button;
    }

    class RolloverButtonListener extends MouseAdapter
    {
        private Icon normal;

        public void mouseEntered(MouseEvent e)
        {
            AbstractButton b = (AbstractButton) e.getSource();
            ButtonModel model = b.getModel();

            if (b.isRolloverEnabled() && !SwingUtilities.isLeftMouseButton(e))
            {
                normal = b.getIcon();
                b.setIcon(b.getRolloverIcon());
                model.setRollover(true);
            }
        }

        public void mouseExited(MouseEvent e)
        {
            AbstractButton b = (AbstractButton) e.getSource();
            ButtonModel model = b.getModel();

            if(b.isRolloverEnabled())
            {
                b.setIcon( normal );
                model.setRollover(false);
            }
        };

    }

    public class ColorIcon implements Icon
    {
        private Color color;
        private int width;
        private int height;

        public ColorIcon(Color color, int width, int height)
        {
            this.color = color;
            this.width = width;
            this.height = height;
        }

        public int getIconWidth()
        {
            return width;
        }

        public int getIconHeight()
        {
            return height;
        }

        public void paintIcon(Component c, Graphics g, int x, int y)
        {
            g.setColor(color);
            g.fillRect(x, y, width, height);
        }
    }

    public static void main(String[] args)
    {
        try
        {
//          UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        }
        catch (Exception e) { }

        ButtonRollover frame = new ButtonRollover();
        frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
        frame.setSize(400, 200);
        frame.setLocationRelativeTo( null );
        frame.setVisible(true);
    }
}
于 2011-06-19T18:40:20.987 に答える
2

ボタンのロールオーバーはアイコンの交換で機能しますが、JMenu では機能しません。

import java.awt.*;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;

public class SwapMenuIcons {

   private static final String KENAI_1 = "http://duke.kenai.com/iconSized/duke.gif";
   private static final String KENAI_2 = "http://duke.kenai.com/iconSized/penduke-transparent.gif";

   private static void createAndShowUI() {
      try {
         Image duke1 = ImageIO.read(new URL(KENAI_1));
         Image duke2 = ImageIO.read(new URL(KENAI_2));
         ImageIcon icon1 = new ImageIcon(duke1);
         ImageIcon icon2 = new ImageIcon(duke2);

         JMenu myMenu = new JMenu();
         myMenu.setIcon(icon1);
         myMenu.setRolloverIcon(icon2);
         myMenu.setRolloverEnabled(true);

         JButton myButton = new JButton(icon1);
         myButton.setRolloverIcon(icon2);
         JPanel btnPanel = new JPanel();
         btnPanel.add(myButton);

         JMenuBar menuBar = new JMenuBar();
         menuBar.add(myMenu);

         JFrame frame = new JFrame("SwapMenuIcons");
         frame.setJMenuBar(menuBar);
         frame.add(btnPanel, BorderLayout.CENTER);
         frame.setPreferredSize(new Dimension(400, 300));
         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         frame.pack();
         frame.setLocationRelativeTo(null);
         frame.setVisible(true);
      } catch (MalformedURLException e) {
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      }
   }

   public static void main(String[] args) {
      java.awt.EventQueue.invokeLater(new Runnable() {
         public void run() {
            createAndShowUI();
         }
      });
   }
}
于 2011-06-19T18:46:54.107 に答える
1

さまざまな方法の束。最も汚いのは、mouseEntered と mouseExited で true と false を切り替えるグローバルなブール値 isMouseHovering を持つことです。これらのマウス イベントの両方で、repaint() を呼び出します。repaint メソッドで、そのブール値に基づいて画像を描画します。

于 2011-06-19T18:37:48.813 に答える