2011-06-19 10 views
3

最初に適切にカスタマイズしたGUIを作成しようとしていますが、コンポーネント用に描画されたイメージを変更するのが難しいです。基本的には、私のexitButton(JMenu)では、paintメソッドを上書きしてマウスリスナーを追加しますが、マウスの入力メソッドの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

異なる方法の束。最も汚いのは、mouseEnteredとmouseExitedで真と偽の間で反転するグローバルブールisMouseHoveringを持つことです。これらのマウスイベントの両方で、repaint()を呼び出します。再描画メソッドでは、そのブール値に基づいてイメージを描画します。

+1

-1、ロールオーバーのサポートが組み込まれていAbstractButtonコンポーネントに追加します。車輪を再構築しないでください。 – camickr

+0

良い点、私は少しのためにスイングの世界から出てきました。 – Bryan

+1

@camickr:ただし、JMenuオブジェクトはAbstractButtonから継承されていても動作しません。これを証明するには、ChangeListenerをJMenuオブジェクトまたはそのモデルに配置します。マウスオーバーの応答は表示されません。 –

5

私はあなたがSwingのチュートリアルを読むことから始めなければならない私の最初適切にカスタマイズされたGUI

を作るしようとしています。私はあなたが何をしようとしているのかは分かりませんが、あなたのアプローチは間違っているようです。

これは、マウスクリックを処理するためにActionListenerを使用する方法を示すHow to Use Menusから始まります。マウスのクリックは、一般にメニューではなくメニューで処理されます。一般的には、「終了」メニュー項目を含む「ファイル」メニューのようなものがあります。

次に、マウスオーバーまたはメニューを選択したときにアイコンを変更できるさまざまなメソッドのJMenu APIも見ていきます。たぶんsetRolloverEnabled()、setRolloverIcon()はあなたが探しているものです。

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

更新:

ホバークラフトで述べたように、ロールオーバーのサポートは、メニューまたはメニュー項目には機能しません。 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); 
    } 
} 
+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:更新していただきありがとうございます!私は後で投票するだろうが、私はもうしばらく前にそれをして、同じ答えのためにそれを2回することはできません。 –

関連する問題