在桌面上绘制线条,可点击线条

时间:2013-11-21 10:20:23

标签: java swing draw

我想创建一个程序,在桌面上使用此属性绘制线条,用户可以单击该线条附近的桌面图标。 我创建样本。我创建透明框架并在此上绘制jWindow。在MouseReleased事件中配置主框架然后保留所有创建的jwindows。我的代码创建了许多jwindow,这非常糟糕。对于绘制线30cm程序创建超过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();
        }
    }
}

1 个答案:

答案 0 :(得分: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);
  }
}