Java Swing – 将透明度应用于透明JPanel上的组件
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Java Swing – 将透明度应用于透明JPanel上的组件,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含5714字,纯文字阅读大概需要9分钟。
内容图文
![Java Swing – 将透明度应用于透明JPanel上的组件](/upload/InfoBanner/zyjiaocheng/789/b443d24b9d644abea406653409a36863.jpg)
我正在创建一个支持透明度的JPanel,并且遇到了我不确定如何将相同级别的透明度应用于添加到此面板的所有组件的问题.我的代码到目前为止:
package de.uebertreiberman.project.swing;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import javax.swing.JPanel;
@SuppressWarnings("serial")
public class JTransparancyPanel extends JPanel {
float opacity = 1.0f;
/**Constructor for JTransparentPanel
*/
public JTransparancyPanel()
{
super();
this.setOpaque(false);
}
/**Getter for opacity value of panel
*
* @return float containing opacity value of frame (0-1)
*/
public float getOpacity()
{
return opacity;
}
/**Setter for opacity value of panel
*
* @param value as float for opacity of frame (0-1)
*/
public void setOpacity(float value)
{
opacity = value;
repaint();
}
/**Converts opacity value (0-1) to opacity color (0-255)
*
* @param opacity as float opacity value (0-1)
* @return integer containing converted opacity value (0-255)
*/
public static int getOpacityColor(float opacity)
{
return (int)(opacity * 255);
}
/**Converts opacity color (0-255) to opacity value (0-1)
*
* @param opacity as integer value (0-255)
* @return float containing converted opacity value (0-1)
*/
public static float getOpacityValue(int opacity)
{
//Returns more or less the correct, capped value
//Just ignore it, it works, leave it :D
return capFloat((3.9216f*opacity)/1000f, 0.0f, 1.0f);
}
/**Returns float capped between minimum and maximum value
*
* @param value as original value
* @param min as minimum cap value
* @param max as maximum cap value
* @return float containing capped value
*/
public static float capFloat(float value, float min, float max)
{
if(value < min) value = min;
else if(value > max) value = max;
return value;
}
/**Merges color and opacity to new color
*
* @param bg as color for old color, only RGB will be used from that
* @return color with RGB from bg and A from opacity of frame
*/
Color getTransparencyColor(Color bg)
{
return new Color(getOpacityValue(bg.getRed()), getOpacityValue(bg.getGreen()), getOpacityValue(bg.getBlue()), opacity);
}
@Override
public void paintComponent(Graphics g)
{
//Draw transparent background before painting other Components
g.setColor(getTransparencyColor(getBackground()));
Rectangle r = g.getClipBounds();
g.fillRect(r.x, r.y, r.width, r.height);
//Paint other components
super.paintComponent(g);
}
}
重要的部分基本上是我覆盖paintComponent(Graphics g)方法的结尾.
我只是采用backgroundcolor,将透明度应用于它并进行设置.
现在我想让这个面板的所有Component子项也变得透明,我不太确定这样做的最有效方法是什么.
你会建议什么?
解决方法:
我找到了一个解决方案 – 基本上我在评论中已经提到过:面板并没有真正画在屏幕上.而是将其绘制成图像,并使用适当的AlphaComposite绘制此图像.
(滑块可用于设置面板的不透明度)
虽然这个解决方案很简单,通用,并且应该基本上适用于所有子组件,但有一点我不喜欢它:调整RepaintManager的必要性.为了确保应用面板的不透明度(并且子组件未独立绘制,并且具有完全不透明度),重绘管理器必须在重新绘制子组件时触发整个组件的重绘.我认为应该有没有这种解决方法的解决方案(例如,这可能是在面板上覆盖getGaphics可能是合适的极少数情况之一),但无济于事.也许通常的嫌疑人(camickr,气垫船等)找到一个更优雅和简洁的解决方案.
在此之前,这里的代码是MCVE:
import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JTree;
import javax.swing.RepaintManager;
import javax.swing.SwingUtilities;
public class TransparencyPanelTest
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(() -> createAndShowGui());
}
private static void createAndShowGui()
{
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().setLayout(new BorderLayout());
OpacityPanel opacityPanel = new OpacityPanel();
opacityPanel.setLayout(new BorderLayout());
opacityPanel.add(new JLabel("Label"), BorderLayout.NORTH);
opacityPanel.add(new JTree(), BorderLayout.CENTER);
opacityPanel.add(new JButton("Button"), BorderLayout.SOUTH);
f.getContentPane().add(opacityPanel, BorderLayout.CENTER);
JSlider slider = new JSlider(0, 100, 50);
slider.addChangeListener(e ->
opacityPanel.setOpacity(slider.getValue() / 100.0f));
f.getContentPane().add(slider, BorderLayout.SOUTH);
f.setSize(500,500);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
class OpacityPanel extends JPanel
{
static
{
RepaintManager.setCurrentManager(new RepaintManager()
{
@Override
public void addDirtyRegion(
JComponent c, int x, int y, int w, int h)
{
Component cc = c;
while (cc != null)
{
if (cc instanceof OpacityPanel)
{
OpacityPanel p = (OpacityPanel)cc;
super.addDirtyRegion(
p, 0, 0, p.getWidth(), p.getHeight());
}
cc = cc.getParent();
}
super.addDirtyRegion(c, x, y, w, h);
}
});
}
private float opacity = 0.5f;
private BufferedImage image;
public OpacityPanel()
{
setOpaque(false);
}
public void setOpacity(float opacity)
{
this.opacity = Math.max(0.0f, Math.min(1.0f, opacity));
repaint();
}
private void updateImage()
{
int w = Math.min(1, getWidth());
int h = Math.min(1, getHeight());
if (image == null || image.getWidth() != w || image.getHeight() != h)
{
image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
}
Graphics2D g = image.createGraphics();
g.setColor(new Color(0,0,0,0));
g.setComposite(AlphaComposite.SrcOver);
g.fillRect(0, 0, w, h);
g.dispose();
}
@Override
protected void paintComponent(Graphics gr)
{
updateImage();
Graphics2D imageGraphics = image.createGraphics();
super.paintComponent(imageGraphics);
imageGraphics.dispose();
Graphics2D g = (Graphics2D) gr;
g.setComposite(AlphaComposite.getInstance(
AlphaComposite.SRC_OVER, opacity));
g.drawImage(image, 0, 0, null);
}
}
内容总结
以上是互联网集市为您收集整理的Java Swing – 将透明度应用于透明JPanel上的组件全部内容,希望文章能够帮你解决Java Swing – 将透明度应用于透明JPanel上的组件所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。