Java Swing - 从鼠标侦听器更改 JComponent 不透明度
Posted
技术标签:
【中文标题】Java Swing - 从鼠标侦听器更改 JComponent 不透明度【英文标题】:Java Swing - Change JComponent opacity from mouse listener 【发布时间】:2011-10-15 14:02:07 【问题描述】:很像标题所说的 - 我有一个 JPanel,如果不活动,我希望它的不透明度为 90%,如果鼠标悬停,则为完全不透明度。
我已经让单独的组件正常工作 - 鼠标悬停是可以的,我可以通过覆盖 paintComponent
方法来更改不透明度,但我想我在 MouseAdapter
和paintComponent
。
似乎有一种非常简单的方法可以做到这一点 - 任何提示?
(顺便说一句,抱歉把代码留在家里了,所以暂时没有例子:(除非它不能很快解决,否则我明天会抛出一些代码。)
【问题讨论】:
【参考方案1】:如果您已经重写了paintComponent 方法,我建议您将MouseAdapter 设为Panel 的匿名内部类,并让它操作一个私有布尔标志。
public class FadingPanel extends JPanel
private boolean active;
public FadingPanel()
createMouseAdapter();
private void createMouseAdapter()
this.addMouseListener(new MouseAdapter()
// your mouseadapter code here toggling the active flag
@Override
public boolean paintComponent(Graphics g)
if(active)
super.paintComponent(g);
else
// your semitransparent painting code here
【讨论】:
+1 这也是一个可行的解决方案,根据情况可能更有效 +1 为答案,但这是少数几个可能优先于 paintComponent 的情况之一,尤其是当组件涉及子元素和边框(例如 JButton)时。 @Hovercraft - 实际上,它确实有几个孩子,其中一个确实是 JButton。我不太清楚你的意思 - 你是说,如果孩子们然后覆盖paint
?相关:paint
也画孩子吗?
真的,解决这个问题的最佳方法是跑到您的在线商店购买 Haase 和 Guy 的 Filthy Rich Clients。它是解决此类问题的最佳资源。【参考方案2】:
如果您要覆盖paintComponent
方法,您应该能够将不透明度变量添加到JPanel
扩展。在 MouseAdapter
中修改它(使用 mutators)。然后在被覆盖的paintComponent
方法中引用这个变量来决定如何绘制。
【讨论】:
+1 在这种情况下,我希望面板类是自包含的,而不是公开不必要的公共接口,因为每个信息本质上都存在于类本身中。但这可能是一个品味问题。 同意。我不确定代码最初是如何构造的,所以我给出了更一般的解释。你的例子是我通常会如何实现这样的事情(为了清楚起见,它应该如何实现)。 虽然这两个答案很相似,但我还是选择了这个答案,因为我认为这个组件的子组件需要访问同一个变量(稍后会测试)。【参考方案3】:Shoot,我没有 Haase 和 Guy 的书,我不记得他们推荐的为半透明组件编码的方式,但我猜想覆盖 paint 或 paintComponent 工作,除了覆盖 paint 会显示从一开始就对子组件产生影响。例如:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class OpaqueJPanels
private static void createAndShowUI()
JPanel mainPanel = new JPanel(new GridLayout(1, 0));
mainPanel.add(new OpaqueJPanel(false, "Override paintComponent"));
mainPanel.add(new OpaqueJPanel(true, "Override paint"));
JFrame frame = new JFrame("Opaque JPanels");
frame.getContentPane().add(mainPanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
public static void main(String[] args)
java.awt.EventQueue.invokeLater(new Runnable()
public void run()
createAndShowUI();
);
class OpaqueJPanel extends JPanel
private static final int OJP_WIDTH = 250;
private static final int OJP_HEIGHT = OJP_WIDTH;
private static final Composite TRANSLUSCENT_COMPOSITE = AlphaComposite
.getInstance(AlphaComposite.SRC_OVER, 0.4f);
private static final Composite NON_TRANSLUSCENT_COMPOSITE = AlphaComposite
.getInstance(AlphaComposite.SRC_OVER, 1.0f);
private boolean overridePaint;
private boolean transluscent = true;
public OpaqueJPanel(boolean overridePaint, String title)
add(new JButton("Button"));
setBorder(BorderFactory.createTitledBorder(title));
addMouseListener(new MouseAdapter()
@Override
public void mouseEntered(MouseEvent e)
transluscent = false;
getParent().repaint();
@Override
public void mouseExited(MouseEvent e)
if (!OpaqueJPanel.this.contains(e.getPoint()))
transluscent = true;
getParent().repaint();
);
@Override
public Dimension getPreferredSize()
return new Dimension(OJP_WIDTH, OJP_HEIGHT);
@Override
public void paint(Graphics g)
if (!overridePaint)
super.paint(g);
return;
Graphics2D g2 = (Graphics2D) g;
Composite composite = transluscent ? TRANSLUSCENT_COMPOSITE
: NON_TRANSLUSCENT_COMPOSITE;
g2.setComposite(composite);
super.paint(g);
@Override
protected void paintComponent(Graphics g)
if (overridePaint)
super.paintComponent(g);
return;
Graphics2D g2 = (Graphics2D) g;
Composite composite = transluscent ? TRANSLUSCENT_COMPOSITE
: NON_TRANSLUSCENT_COMPOSITE;
g2.setComposite(composite);
super.paintComponent(g);
我还发现重新绘制 JPanel 的父组件而不是 JPanel 本身会更好。
【讨论】:
以上是关于Java Swing - 从鼠标侦听器更改 JComponent 不透明度的主要内容,如果未能解决你的问题,请参考以下文章
Swing JTextField 文本更改侦听器 DocumentListener 无限循环