2016-04-29 48 views
0

當我嘗試重新繪製透明窗口並在其上繪製矩形時,上一個矩形將保留。目標是通過點擊並移動鼠標在屏幕上選擇一個區域。 It'll look like this if you move your mouse for a while透明JFrame不能清除重新繪製

通過刪除透明度,它工作得很好。

我嘗試了一切,我可以找到關於這個主題的堆棧溢出,但我無法讓它在Windows和Linux上都能工作。

主類

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseMotionAdapter; 

public class Main { 
    private JFrame frame; 
    private boolean pressing = false; 
    private boolean selected = false; 
    private ScreenSelectPanel p; 

    public Main() { 
     Dimension dim = Toolkit.getDefaultToolkit().getScreenSize(); 
     frame = new JFrame("ScreenSelection"); 
     frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
     frame.setSize(dim); 
     frame.setUndecorated(true); 

     frame.setContentPane(p = new ScreenSelectPanel()); 
     registerListeners(); 

     frame.getContentPane().setBackground(new Color(255, 255, 255, 0)); 
     frame.setBackground(new Color(255, 255, 255, 0)); 
     frame.setLayout(new BorderLayout()); 

     frame.setAlwaysOnTop(true); 
     frame.setVisible(true); 
    } 

    private void registerListeners() { 
     p.setFocusable(true); 
     p.requestFocusInWindow(); 

     p.addMouseMotionListener(new MouseMotionAdapter() { 
      @Override 
      public void mouseDragged(MouseEvent e) { 
       if (selected) 
        return; 
       setLoc(e); 
       p.repaint(); 

      } 

      @Override 
      public void mouseMoved(MouseEvent e) { 
       if (selected) 
        return; 
       setLoc(e); 
       if (!pressing) 
        setStartLoc(e); 
       p.repaint(); 
      } 
     }); 
     p.addMouseListener(new MouseAdapter() { 
      @Override 
      public void mouseClicked(MouseEvent e) { 
       setLoc(e); 
       setStartLoc(e); 
       p.repaint(); 
      } 

      @Override 
      public void mouseEntered(MouseEvent e) { 
       setLoc(e); 
       setStartLoc(e); 
       p.repaint(); 

      } 
     }); 
    } 

    public void setStartLoc(MouseEvent e) { 
     p.mouseStartX = e.getX(); 
     p.mouseStartY = e.getY(); 
    } 

    public void setLoc(MouseEvent e) { 
     p.mouseX = e.getX(); 
     p.mouseY = e.getY(); 
    } 

    public static void main(String[] args) { 
     new Main(); 
    } 
} 

ScreenSelectPanel類

import javax.swing.*; 
import java.awt.*; 
import java.awt.geom.Point2D; 
import java.awt.image.BufferedImage; 

public class ScreenSelectPanel extends JPanel { 
    public int mouseX = 0; 
    public int mouseY = 0; 
    public int mouseStartX = 0; 
    public int mouseStartY = 0; 

    private Color borderColor; 

    public ScreenSelectPanel() { 
     setOpaque(false); 
     borderColor = Color.BLACK; 
    } 

    public void setBorderColor(Color c) { 
     this.borderColor = c; 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 

     Graphics2D g2d = (Graphics2D) g; 

     g2d.setColor(borderColor); 
     Rectangle rect = new Rectangle(); 
     rect.setFrameFromDiagonal(new Point2D.Float(mouseStartX, mouseStartY), new Point2D.Float(mouseX, mouseY)); 
     Stroke dashed = new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0, new float[]{9}, 0); 
     g2d.setStroke(dashed); 
     g2d.drawRect(rect.x, rect.y, rect.width, rect.height); 

     g2d.dispose(); 
    } 

} 

謝謝:)

回答

1

您不能使用Swing組件的透明度。透明的背景會導致這些類型的繪畫問題。 Swing組件不透明或不透明。

有關此問題的更多信息,請查看Backgrounds With Transparency。但是,在這個原因中,這不是問題,因爲您正試圖在Swing面板上使用完全透明。

當我嘗試重新繪製一個透明窗口並在其上繪製一個矩形時,上一個矩形將保留。

您發佈的代碼執行任何操作(至少在Windows上)。當您將框架設置爲完全透明時,則MouseEvent不再由Swing處理,而是由框架下的應用程序處理。

我做了以下修改你的代碼,它似乎爲我工作:

//frame.getContentPane().setBackground(new Color(255, 255, 255, 0)); 
//frame.setBackground(new Color(255, 255, 255, 0)); 
frame.setBackground(new Color(255, 255, 255, 10));