繁体   English   中英

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

[英]Java - Adding and removing underlined text in a JButton on Hover

当用户将鼠标悬停在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);
}

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

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

我可以就如何保持下划线效果使用一些专家建议,同时通过操作侦听器添加新的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 );

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM