Reputation: 376
I am using the following code to successfully have a hover effect of underlined text when the user mouses over a JButton. This is working as intended.
When clicked, the JButton simply removes the current JPanel from the screen, and adds a new one to it. This also works.
The problem is that when actually clicked, the hover effect of underlined text remains permanently on the JButton and does not go away when the mouse is moved.
I tried implementing mouseClicked()
to have it remove the underlined effect when the button is clicked but this has no effect. I could use some expert advice on how to keep the underlining effect in place, while removing it when the new JPanel is added through an action listener.
Snippet:
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);
}
Upvotes: 0
Views: 1941
Reputation: 324157
I could use some expert advice on how to keep the underlining effect in place, while removing it when the new JPanel is added through an action listener
Why would you remove it via the ActionListener? The button is still active. There is no reason the user couldn't click on the button again.
In any case your original logic is reasonable you just need to remove the underline attribute in the mouseExited
and/or mouseClicked
events. The key part you should have learned from Hovercraft's answer was how to remove the underline
attribute from the font.
I'd like to reuse it on multiple buttons without repeating code.
If you follow your own original solution then you can share the MouseListener
because the source of the event will be the button:
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 );
Upvotes: 0
Reputation: 285405
As per MadProgrammer's suggestion, one possible solution is to add a ChangeListener to the button's model, and check for model.isRollover()
within that listener and behave accordingly.
For example:
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);
});
But this is somewhat "kludgy" as it changes the state of the button from within its model listener.
Upvotes: 1