我目前正在开发一个应用程序,需要select屏幕区域的function。 我想出了创build一个透明的,未修饰的全屏JFrame,并在其中添加一个半透明,不透明的JPanel,其中半透明的深色背景以及所选内容都被绘制。
虽然这个想法(和代码)在Windows上运行良好,但它在linux上并不是一回事,在调用repaint()的时候,JPanel的背景似乎没有被清除(尽pipe我通过各种方法告诉它) – 每种重绘方法,背景和组件变得越来越黑暗,等等。
这是MVCE:
import javax.swing.*; import java.awt.*; import java.awt.event.*; public class ExampleFrame extends JFrame{ private ExamplePanel selectionPane; public ExampleFrame(){ this.addKeyListener(new KeyListener() { @Override public void keyTyped(KeyEvent e) { } @Override public void keypressed(KeyEvent e) { } @Override public void keyreleased(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { ExampleFrame.this.dispatchEvent(new WindowEvent(ExampleFrame.this,WindowEvent.WINDOW_CLOSING)); } } }); this.setExtendedState(JFrame.MAXIMIZED_BOTH); Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); this.setSize(screenSize); this.setUndecorated(true); this.setBackground(new Color(255,255,0)); populate(); this.setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE); this.setType(Window.Type.UTILITY); this.setVisible(true); } private void populate(){ this.selectionPane = new ExamplePanel(); this.setContentPane(selectionPane); } public static void main(String[] args){ SwingUtilities.invokelater(new Runnable() { @Override public void run() { new ExampleFrame(); } }); } public static class ExamplePanel extends JPanel{ private static Color bg = new Color(0,0.5f); private int sx = -1,sy = -1,ex = -1,ey = -1; public ExamplePanel(){ MouseAdapter mouseAdapter = new MouseAdapter() { @Override public void mousepressed(MouseEvent e) { sx = sy = ex = ey = -1; sx = e.getX(); sy = e.getY(); repaint(); } @Override public void mouseReleased(MouseEvent e) { ex = e.getX(); ey = e.getY(); repaint(); } @Override public void mouseDragged(MouseEvent e) { ex = e.getX(); ey = e.getY(); repaint(); } }; this.addMouseListener(mouseAdapter); this.addMouseMotionListener(mouseAdapter); this.setDoubleBuffered(false); this.setopaque(false); this.setBackground(bg); } @Override public void paintComponent(Graphics g){ Graphics2D g2 = (Graphics2D)g.create(); g2.setComposite(AlphaComposite.Clear); g2.setBackground(new Color(255,0)); g2.fillRect(0,getWidth(),getHeight()); //g2.clearRect(0,getHeight()); //neither of them work g2.setComposite(AlphaComposite.Src.derive(.5f)); g2.setPaint(getBackground()); g2.fillRect(0,getHeight()); g2.setComposite(AlphaComposite.Src.derive(1f)); g2.setPaint(Color.WHITE); g2.drawString("Press Escape to exit",10,20); if(!(sx == -1 || sy == -1 || ex == -1 || ey == -1)){ int asx = Math.min(sx,ex); int asy = Math.min(sy,ey); int w = Math.abs(ex - sx); int h = Math.abs(ey - sy); g2.setComposite(AlphaComposite.Src); g2.setPaint(new Color(255,0)); g2.fillRect(asx,asy,w,h); g2.setPaint(new Color(0,1)); g2.fillRect(asx,h); g2.setComposite(AlphaComposite.SrcOver); g2.setstroke(new Basicstroke(2)); g2.setPaint(new Color(1,1,0.15f)); g2.drawRect(asx-1,asy-1,w+2,h+2); } } } }
任何想法可能会导致这个? 或者,也许这是在Linux上的Java错误? 我已经在Windows 10下testing了这个,Ubuntu 14.04 LTS以及运行KDE gui的Arch Linux的未知版本(由朋友testing)
NameNode:java.net.BindException
Android扫雷algorithm
如何通过Java不断从Linux获取信息,如果目录中有变化?
从IntelliJ IDEA推入Git授予权限被拒绝(公钥)
PhantomJS 2.5.0-beta for Selenium WebDriver不能在Linux中工作
编辑 :也在OSX(优胜美地和埃尔capitan)testing,都工作正常。
将域映射到Tomcat应用程序
数组长度在openjdk中改变
把它们都包装好! Perl,python,java for naive用户(在windows中)
this.setBackground(new Color(255,0));
如果你想要一个完全透明的组件,那就使用:
component.setopaque( false );
这告诉Swing寻找父组件,并首先绘制它,所以你不会得到绘画工件。
private static Color bg = new Color(0,0.5f);
如果你想要半透明的背景,那么需要做自定义编码,因为Swing不支持这个。
JPanel panel = new JPanel() { protected void paintComponent(Graphics g) { g.setColor( getBackground() ); g.fillRect(0,getHeight()); super.paintComponent(g); } };
另一种解决方案是可重复使用的类,可以与任何组件一起使用,因此您不需要自定义每个组件。 panel.setopaque(假); //父项的背景将被首先绘制panel.setBackground(new Color(255,0,0,20)); frame.add(面板);
如果不能复制问题的确切原因是很难的。 代码中有许多关注的领域
不通过调用super.paintComponent不尊重油漆调用链
使用setDoubleBuffered(false)
使用this.setBackground(bg); 在JPanel传递一个基于alpha的颜色
AlphaComposite的广泛使用和它的一丝不苟的使用,试图清除Graphics上下文
基本的行动方针是简化绘画过程,直到你可以确定导致问题的动作或动作的组合。
或者采取另一种方法。 而不是使用不同的AlphaComposite设置的组合,你可能会考虑只是使用一个Area并减去你想要暴露的区域….
import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.Toolkit; import java.awt.Window; import java.awt.event.KeyEvent; import java.awt.event.Keylistner; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.WindowEvent; import java.awt.geom.Area; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.SwingUtilities; public class ExampleFrame extends JFrame { private ExamplePanel selectionPane; public ExampleFrame() { this.addKeylistner(new Keylistner() { @Override public void keyTyped(KeyEvent e) { } @Override public void keypressed(KeyEvent e) { } @Override public void keyreleased(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { ExampleFrame.this.dispatchEvent(new WindowEvent(ExampleFrame.this,0)); populate(); this.setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE); this.setType(Window.Type.UTILITY); this.setVisible(true); } private void populate() { this.selectionPane = new ExamplePanel(); this.setContentPane(selectionPane); } public static void main(String[] args) { SwingUtilities.invokelater(new Runnable() { @Override public void run() { new ExampleFrame(); } }); } public static class ExamplePanel extends JPanel { private static Color bg = new Color(0,0); private int sx = -1,ey = -1; public ExamplePanel() { MouseAdapter mouseAdapter = new MouseAdapter() { @Override public void mousepressed(MouseEvent e) { sx = sy = ex = ey = -1; sx = e.getX(); sy = e.getY(); repaint(); } @Override public void mouseReleased(MouseEvent e) { ex = e.getX(); ey = e.getY(); repaint(); } @Override public void mouseDragged(MouseEvent e) { ex = e.getX(); ey = e.getY(); repaint(); } }; this.addMouselistner(mouseAdapter); this.addMouseMotionlistner(mouseAdapter); this.setopaque(false); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2 = (Graphics2D) g.create(); Area area = new Area(new Rectangle(0,getHeight())); if (!(sx == -1 || sy == -1 || ex == -1 || ey == -1)) { int asx = Math.min(sx,ey); int w = Math.abs(ex - sx); int h = Math.abs(ey - sy); area.subtract(new Area(new Rectangle(asx - 1,asy - 1,w + 2,h + 2))); } g2.setComposite(AlphaComposite.Src.derive(.25f)); g2.setPaint(bg); g2.fill(area); g2.setComposite(AlphaComposite.Src.derive(1f)); g2.setPaint(Color.WHITE); g2.drawString("Press Escape to exit",20); g2.dispose(); } } }
如果你想清除背景,一定要调用super.paintComponent() 。
@Override public void paintComponent(Graphics g){ super.paintComponent(g); Graphics2D g2 = (Graphics2D)g.create();
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。