开发者

Java repainting a component at mouse-over.

I am attempting to make my first properly customised GUI, but I am having difficulty changing the image which has been painted for a component. Basically, for my exitButton (a JMenu) I overwrite the paint method, and then add a Mouse listener, but I am not sure how to repaint the image within the mouseListener interface in the Mouse entered method and again in the mouse exited method. Essentially I am looking for a way to repaint the image, but I am lost as to what I can do. Any help would be greatly appreciated.

Here is the relevant code snippet:

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) {
 开发者_JAVA百科           //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("mouse exited"); // The imageicon for the origianl image } @Override public void mouseReleased(MouseEvent me) { } });


I am attempting to make my first properly customised GUI

You should start by reading the Swing tutorial. I'm not really sure what you are trying to do but your approach sure seems wrong.

You can start with How to Use Menus which shows how to use an ActionListener to handle a mouse click. Mouse clicks are generally handled on a menu item, not a menu. You would generally have something like a "File" menu that wouuld contain an "Exit" menu item.

Then I would also look at the JMenu API for various methods that allow you to change the Icon when you mouse over or select a menu. Maybe setRolloverEnabled(), setRolloverIcon() is what you are looking for.

If you still have problems, then post a SSCCE that demonstrates the problem.

Update:

As mentioned by Hovercraft, rollover support does not work for menus or menu items. There are two problems. First of all a different MouseListener is used by these components. The listener does NOT listen for mouseEntered and mouseExited events. The second problem is that the UI for the two components has been customized and the custom Icon painting code does not take into account the rollover state of the button.

Adding a MouseListener is easy. Customizing the UI (which is the proper solution) to properly support rollovers is more involved.

For a simple hack that seems to work, I just update the Icon in the MouseListener rather than having the UI determine which Icon to paint. I advise you to forget about this requirement and use a normal UI which does not change Icons for menus and menu items. Use the following at your own risk:

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);
    }
}


RollOver for a button works with swapping Icons, but I can't get it to work for a 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();
         }
      });
   }
}


Bunch of different ways. The dirtiest would be to have a global boolean isMouseHovering that you flip between true and false with the mouseEntered and mouseExited. In both of these mouse events, call repaint(); In your repaint method, draw the image based on the value of that boolean.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜