Java-在悬停状态的JButton中添加和删除带下划线的文本

时间:2018-09-25 23:37:06

标签: java swing mouseevent jbutton

当用户将鼠标悬停在JButton上时,我正在使用以下代码成功地使带有下划线的文本具有悬停效果。这按预期工作。

单击时,JButton只是从屏幕上删除当前的JPanel,并向其中添加一个新的JPanel。这也可以。

问题在于,当实际单击时,带下划线的文本的悬停效果会永久保留在JButton上,并且在移动鼠标时不会消失。

我尝试实现mouseClicked(),以使其在单击按钮时删除带有下划线的效果,但这没有效果。在通过动作侦听器添加新的JPanel时,如果要保留下划线效果,可以使用一些专家建议。

摘要:

class MyAcctListener implements ActionListener
{
    public void actionPerformed(ActionEvent e) 
    {
        totalGUI.removeAll();
        totalGUI.add(headerPanel, BorderLayout.NORTH);
        totalGUI.add(myAcctPanel, BorderLayout.CENTER);
        repaint();
        revalidate();
    }
}

@SuppressWarnings("unchecked")
class HeaderMouseListener extends MouseAdapter
{
    Font original;

    @Override
    public void mouseEntered(MouseEvent evt) {
        original = evt.getComponent().getFont();
        Map attributes = original. getAttributes();
        attributes.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
        evt.getComponent().setFont(original.deriveFont(attributes));
    }

    @Override
    public void mouseExited(MouseEvent evt){
        evt.getComponent().setFont(original);   
    }

    @Override
    public void mouseClicked(MouseEvent evt) {
        evt.getComponent().setFont(original); 
    }
}


private void createComponents() {
    MouseListener headerMouseListener = new HeaderMouseListener();
    acctButton = new JButton("My Account");
    acctButton.setFont(buttonFont);
    acctButton.setForeground(Color.BLUE);
    acctButton.setBorderPainted(false);
    acctButton.setContentAreaFilled(false);
    acctButton.addMouseListener(headerMouseListener);
    ActionListener myacctListener = new MyAcctListener();
    acctButton.addActionListener(myacctListener);
}

2 个答案:

答案 0 :(得分:1)

根据MadProgrammer的建议,一种可能的解决方案是将ChangeListener添加到按钮的模型,并在该侦听器中检查model.isRollover()并相应地执行操作。

例如:

button.getModel().addChangeListener(evt -> {
    ButtonModel model = (ButtonModel) evt.getSource();
    Font btnFont = button.getFont();
    Map attributes = btnFont.getAttributes();

    if (model.isRollover()) {
        attributes.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
    } else {
        attributes.put(TextAttribute.UNDERLINE, null);
    }
    btnFont = btnFont.deriveFont(attributes);
    button.setFont(btnFont);
});

但这有点“笨拙”,因为它从模型侦听器内部更改了按钮的状态。

答案 1 :(得分:0)

  

在通过动作侦听器添加新的JPanel时,如何保留下划线效果,同时删除下划线效果,我可以使用一些专家建议

为什么要通过ActionListener删除它?该按钮仍处于活动状态。用户没有理由无法再次单击该按钮。

无论如何,您的原始逻辑是合理的,您只需要在mouseExited和/或mouseClicked事件中删除下划线属性。您应该从Hovercraft的答案中学到的关键部分是如何从字体中删除underline属性。

  

我想在多个按钮上重用它而不重复代码。

如果您遵循自己的原始解决方案,则可以共享MouseListener,因为事件的来源将是按钮:

MouseListener ml = new MouseAdapter()
{
    @Override
    public void mouseEntered(MouseEvent evt) {
        Component button = evt.getComponent();
        Font font = button.getFont();
        Map attributes = font.getAttributes();
        attributes.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
        button.setFont(font.deriveFont(attributes));
    }

    @Override
    public void mouseExited(MouseEvent evt){
    System.out.println("Exited");
        Component button = evt.getComponent();
        Font font = button.getFont();
        Map attributes = font.getAttributes();
        attributes.put(TextAttribute.UNDERLINE, null);
        button.setFont(font.deriveFont(attributes));
    }
    /*
    @Override
    public void mouseClicked(MouseEvent evt) {
        Component button = evt.getComponent();
        Font font = button.getFont();
        Map attributes = font.getAttributes();
        attributes.put(TextAttribute.UNDERLINE, null);
        button.setFont(font.deriveFont(attributes));
    }
    */
};

JButton button1 = new JButton("Button 1");
add( button1 );
button1.addMouseListener( ml );

JButton button2 = new JButton("Button 2");
add( button2 );
button2.addMouseListener( ml );