2011-06-19 25 views
3

我正在尝试使我的第一个正确定制的GUI,但我很难更改已被绘制的组件的图像。基本上,对于我的exitButton(一个JMenu),我重写了paint方法,然后添加了一个Mouse侦听器,但我不确定如何重新绘制鼠标输入方法中mouseListener接口中的图像,以及鼠标退出方法中的图像。基本上我正在寻找一种重新绘制图像的方式,但我失去了我能做的事情。任何帮助将不胜感激。Java在鼠标悬停时重绘组件。

下面是相关的代码片断:

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( “鼠标离开”); //原始图片的图片图片 } @Override public void mouseReleased(MouseEvent me){ } });

回答

1

一堆不同的方法。最肮脏的是要有一个全局布尔isMouseHovering,你用鼠标输入和鼠标退出在true和false之间切换。在这两个鼠标事件中,调用repaint();在重绘方法中,根据该布尔值的值绘制图像。

+1

-1,侧翻支持内置到AbstractButton组件中。不要重新发明轮子。 – camickr

+0

好点,我已经摆脱了摇摆的世界了一下。 – Bryan

+1

@camickr:但它不能在JMenu对象上工作,即使它们从AbstractButton继承。为了证明这一点,在JMenu对象或其模型上放置ChangeListener,您将看不到鼠标悬停的响应。 –

5

我试图让我的第一个正确定制GUI

你应该开始通过阅读Swing指南。我不确定你想要做什么,但你的方法肯定是错误的。

您可以从How to Use Menus开始,它显示了如何使用ActionListener来处理鼠标单击。鼠标点击通常在菜单项上处理,而不是在菜单上处理。您通常会拥有一个类似于“文件”菜单的菜单,该菜单包含一个“退出”菜单项。

然后,我还会查看各种方法的JMenu API,以便您在鼠标悬停或选择菜单时更改图标。也许setRolloverEnabled(),setRolloverIcon()是你正在寻找的。

如果您仍然有问题,然后发布SSCCE,说明问题。

更新:

正如气垫船提到,侧翻的支持不会为菜单或菜单项工作。有两个问题。首先,这些组件使用不同的MouseListener。侦听器不侦听mouseEntered和mouseExited事件。第二个问题是这两个组件的用户界面已经被自定义,并且自定义的图标绘制代码没有考虑按钮的滚动状态。

添加MouseListener很容易。定制用户界面(这是正确的解决方案)以更好地支持滚动更为复杂。

对于一个简单的黑客来说,我只是更新MouseListener中的图标,而不是让UI确定要绘制哪个图标。我建议你忘记这个要求,并使用不改变菜单和菜单项的图标的普通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); 
    } 
} 
+0

对我来说太复杂了,从ComponentUI中提取MouseListener为+1,使用SwingUtilities .. – mKorbel

+0

嗨,非常感谢您的帮助,我设法让您的方法正常工作,但它创造了一些其他问题,例如何时调整它的大小代替了所有按钮的图像,因为当鼠标被按住时,它难以隔离按钮。尽管如此,您的方法为我提供了创建自己的方法所需的想法。谢谢 –

+0

我认为JMenuItem,mouseentered和mouseexited都被监听。我刚测试过。 – FaithReaper

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(); 
     } 
     }); 
    } 
} 
+0

这将是很好,如果这是记录:)。看到我的更新为黑客。 – camickr

+0

@camickr:很酷,并感谢您的更新!我会投票赞成,但我已经做了一段时间,不能做两次相同的答案。 –