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);
});
但这有点 "kludgy" 因为它从其模型侦听器中更改了按钮的状态。
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
为什么要通过 ActionListener 删除它?该按钮仍然有效。用户没有理由不能再次点击按钮。
无论如何你原来的逻辑是合理的你只需要删除 mouseExited
and/or mouseClicked
事件中的下划线属性。您应该从 Hovercraft 的回答中学到的关键部分是如何从字体中删除 underline
属性。
I'd like to reuse it on multiple buttons without repeating code.
如果您遵循自己的原始解决方案,那么您可以分享 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 );
当用户将鼠标悬停在 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);
});
但这有点 "kludgy" 因为它从其模型侦听器中更改了按钮的状态。
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
为什么要通过 ActionListener 删除它?该按钮仍然有效。用户没有理由不能再次点击按钮。
无论如何你原来的逻辑是合理的你只需要删除 mouseExited
and/or mouseClicked
事件中的下划线属性。您应该从 Hovercraft 的回答中学到的关键部分是如何从字体中删除 underline
属性。
I'd like to reuse it on multiple buttons without repeating code.
如果您遵循自己的原始解决方案,那么您可以分享 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 );