java jbutton 透明_Java Swing – 将透明度应用于透明JPanel上的组件

我正在创建一个支持透明度的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绘制此图像.

3819b80495705a36400685fb48bd1592.png

(滑块可用于设置面板的不透明度)

虽然这个解决方案很简单,通用,并且应该基本上适用于所有子组件,但有一点我不喜欢它:调整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,transparency,swing,jpanel

来源: https://codeday.me/bug/20190627/1308795.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值