2013-11-21 75 views
2

我想要創建一個程序,在桌面上用此屬性繪製線條,用戶可以點擊線條旁邊的桌面圖標。 我創建樣本。我創建透明框架並在此上繪製jWindow。在MouseReleased事件中配置主框架,然後保留所有創建的jwindows。我的代碼創建了許多jwindow,這非常糟糕。對於畫線30釐米程序創建超過400 jwindow,這會導致os非常重。 可以幫助我嗎? (恕我醜的英語)在桌面上畫一條線,點擊可以在線左右

package PKHMain; 

    import java.awt.Color; 
    import java.awt.Dimension; 
    import java.awt.Graphics; 
    import java.awt.Graphics2D; 

import java.awt.GridBagLayout; 
import java.awt.RenderingHints; 
import java.awt.Toolkit; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 
import java.awt.event.MouseMotionListener; 
import java.awt.geom.Ellipse2D; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JWindow; 

public class FRMMain extends JFrame implements MouseListener, MouseMotionListener { 

    public FRMMain() { 
     this.setUndecorated(true); 
     this.setSize(Toolkit.getDefaultToolkit().getScreenSize().width, Toolkit.getDefaultToolkit().getScreenSize().height); 
     this.setDefaultCloseOperation(DISPOSE_ON_CLOSE); 
     this.setLayout(null); 
     this.setBackground(new Color(0, 0, 0, 0)); 
     this.setVisible(true); 
     addMouseListener(this); 
     addMouseMotionListener(this); 
    } 

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

    @Override 
    public void mousePressed(MouseEvent event) { 
    } 

    @Override 
    public void paint(Graphics g) { 
     repaint(); 
    } 

    @Override 
    public void mouseClicked(MouseEvent event) { 
    } 

    @Override 
    public void mouseEntered(MouseEvent event) { 
    } 

    @Override 
    public void mouseExited(MouseEvent event) { 
    } 

    @Override 
    public void mouseReleased(MouseEvent event) { 
     this.dispose(); 
    } 

    @Override 
    public void mouseDragged(MouseEvent event) { 
     int x = event.getX(); 
     int y = event.getY(); 
     JWindow frame = new JWindow(); 
     frame.setBackground(new Color(0, 0, 0, 0)); 
     frame.setContentPane(new ShapedPane(x, y)); 
     frame.pack(); 
     frame.setLocation(x, y); 
     frame.setAlwaysOnTop(true); 
     frame.setVisible(true); 
    } 

    public void mouseMoved(MouseEvent event) { 
    } 

    public class ShapedPane extends JPanel { 

     public int x1; 
     public int y1; 

     public ShapedPane(int x, int y) { 
      setOpaque(false); 
      setLayout(new GridBagLayout()); 
      x1 = x; 
      y1 = y; 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(5, 5); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2 = (Graphics2D) g.create(); 
      RenderingHints hints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
      g2.setRenderingHints(hints); 
      g2.setColor(Color.red); 
      g2.fill(new Ellipse2D.Double(0, 0, getWidth(), getHeight())); 
      g2.dispose(); 
     } 
    } 
} 
+0

我的問題,很重要的是你是爲什麼原因是油漆()與重繪繪畫(),它可以導致高度處理器消耗或無限循環 – mKorbel

+0

我刪除了paint()方法,並沒有改變任何東西。 –

+0

將形狀列表放到FRMMain類中,並在FRMMain框架的paint方法內繪製這些形狀,並且不要創建任何新窗口。 – Holger

回答

2

你與你的程序,例如觸摸系統的特定行爲在我的機器上,程序將不會收到任何鼠標事件,因爲背景顏色的alpha值爲零。將其設置爲至少一個使其可以接受點擊和拖動。因此,這是一種控制所需點擊行爲的方式,但它可能不適用於您。

這是因爲它在我的機器(的Java 7和Windows 7)上運行的程序:

import java.awt.*; 
import java.awt.event.MouseEvent; 
import java.awt.geom.Ellipse2D; 
import java.util.ArrayList; 
import java.util.List; 

import javax.swing.JFrame; 

public class FRMMain extends JFrame { 
    private final List<Shape> list=new ArrayList<>(); 
    private boolean paintPhase=true; 

    public FRMMain() { 
     this.setUndecorated(true); 
     final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); 
     this.setSize(screenSize.width, screenSize.height); 
     this.setDefaultCloseOperation(DISPOSE_ON_CLOSE); 
     this.setBackground(new Color(0, 0, 0, 1)); 
     this.setOpacity(1f); 
     this.setAlwaysOnTop(true); 
     this.setVisible(true); 
     enableEvents(AWTEvent.MOUSE_EVENT_MASK|AWTEvent.MOUSE_MOTION_EVENT_MASK); 
    } 
    @Override 
    protected void processMouseEvent(MouseEvent e) { 
    if(paintPhase && e.getID()==MouseEvent.MOUSE_RELEASED) { 
     paintPhase = false; 
     // on my machine the following line is enough to enable click-through 
     setBackground(new Color(0, 0, 0, 0)); 
     // but if this doesn’t work, the following should do: 
     Area area=new Area(); 
     BasicStroke b=new BasicStroke(2f); 
     for(Shape s:list) area.add(new Area(b.createStrokedShape(s))); 
     setShape(area); 
    } 
    super.processMouseEvent(e); 
    } 
    @Override 
    protected void processMouseMotionEvent(MouseEvent event) 
    { 
    if(paintPhase && event.getID()==MouseEvent.MOUSE_DRAGGED) { 
     int x = event.getX(); 
     int y = event.getY(); 
     list.add(new Ellipse2D.Float(x, y, 8, 8)); 
     repaint(); 
    } 
    super.processMouseMotionEvent(event); 
    } 
    @Override 
    public boolean contains(int x, int y) { 
    return paintPhase; 
    } 

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

    @Override 
    public void paint(Graphics g) { 
    Graphics2D gfx=(Graphics2D)g; 
    gfx.setColor(Color.RED); 
    for(Shape s:list) gfx.draw(s); 
    } 
} 
+0

嗨Holger。感謝您的重播。 –

+0

嗨Holger。感謝您的重播。我可以畫鼠標事件。我需要程序,我可以在屏幕上繪製線條,畫線後屏幕上的所有對象都將可用(圖標,文本...)。在你的程序中透明層留在屏幕上!我需要在畫線後單獨留在桌面上。 –

+0

如上所述,在我的機器上,它的工作原理與在鼠標釋放時將背景alpha設置爲零一樣,將啓用點擊透明度。如果這樣做對你不起作用,你可以嘗試在窗口中使用'setShape',並使用列表中所有形狀的複合形狀。好吧,我更新了答案,以說明如何做到這一點。看看'processMouseEvent'方法... – Holger