如何使用鼠标拖动事件在java小程序上绘制矩形 [英] how to draw rectangle on java applet using mouse drag event

查看:37
本文介绍了如何使用鼠标拖动事件在java小程序上绘制矩形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Java.我想根据 mousedrag 事件绘制矩形.如果用户拖动鼠标,则小程序上的矩形应根据当前鼠标坐标增加或减少.我有以下代码.

i am using java. i want to draw rectangle based on mousedrag event. if user dragging the mouse, then the rectangle on the applet should increase or decrease basing on current mouse coordinates. i have the following code.

在下面的代码中,我使用了 [b]SelectionArea[/b] 类,它扩展了我正在执行绘图操作的画布.我在这个类中使用 [b]image[/b] 变量进行双缓冲以减少闪烁并保存小程序的先前状态(即小程序的绘制内容)

in the following code i am using [b]SelectionArea[/b] class which extends a canvas on which i am performing drawing operation. i am using [b]image[/b] variable in this class for double buffering to reduce flickering and to save the applet's previous state(i.e drawing content of applet)

但是如果我绘制第一个矩形,代码就可以正常工作.如果我开始绘制第二个矩形,之前绘制的矩形就会消失.我希望之前绘制的矩形出现在屏幕上

but the code is working fine if i draw first rectangle. if i start to draw second rectangle the previously drawn rectangle is disappearing. i want the previously drawn rectangle to be on the screen

谁能告诉我如何解决这个问题.

can any one tell me how to solve this.

import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;

/* 
 * This displays a framed area.  When the user drags within
 * the area, this program displays a rectangle extending from
 * where the user first pressed the mouse button to the current
 * cursor location.
 */

public class RectangleDemo extends Applet {
SelectionArea drawingPanel;
Label label;

public void init() {
    GridBagLayout gridBag = new GridBagLayout();
    GridBagConstraints c = new GridBagConstraints();

    setLayout(gridBag);

    drawingPanel = new SelectionArea(this);
    c.fill = GridBagConstraints.BOTH;
    c.weighty = 1.0;
    c.gridwidth = GridBagConstraints.REMAINDER; //end row
    gridBag.setConstraints(drawingPanel, c);
    add(drawingPanel);

    label = new Label("Drag within the framed area.");
    c.fill = GridBagConstraints.HORIZONTAL;
    c.weightx = 1.0;
    c.weighty = 0.0;
    gridBag.setConstraints(label, c);
    add(label);
    drawingPanel.setVisible(true);

    validate();
}

public void paint(Graphics g){
    drawingPanel.repaint();
}

public void update(Graphics g){
    paint(g);
}         

}

class SelectionArea extends Canvas implements ActionListener, MouseListener,    MouseMotionListener{
Rectangle currentRect;
RectangleDemo controller;
//for double buffering
Image image;
Graphics offscreen;
public SelectionArea(RectangleDemo controller) {
    super();
    this.controller = controller;
    addMouseListener(this);
    addMouseMotionListener(this);        
}

public void actionPerformed(ActionEvent ae){
    repaintoffscreen();
}

public void repaintoffscreen(){
    image = createImage(this.getWidth(), this.getHeight());
    offscreen = image.getGraphics();
    Dimension d = getSize();
    if(currentRect != null){
        Rectangle box = getDrawableRect(currentRect, d);            

        //Draw the box outline.
        offscreen.drawRect(box.x, box.y, box.width - 1, box.height - 1);  
        //repaint();
    }
}

public void mouseEntered(MouseEvent me) {}
public void mouseExited(MouseEvent me){ }
public void mouseClicked(MouseEvent me){}
public void mouseMoved(MouseEvent me){}

public void mousePressed(MouseEvent me) {        
    currentRect = new Rectangle(me.getX(), me.getY(), 0, 0);
    repaintoffscreen();        
}

public void mouseDragged(MouseEvent me) {
    System.out.println("here in dragged()");
    currentRect.setSize(me.getX() - currentRect.x, me.getY() - currentRect.y);
    repaintoffscreen();    
    repaint();
}

public void mouseReleased(MouseEvent me) {
    currentRect.setSize(me.getX() - currentRect.x, me.getY() - currentRect.y);
    repaintoffscreen();  
    repaint();
}

public void update(Graphics g){
    paint(g);
}

public void paint(Graphics g) {
    g.drawImage(image, 0, 0, this);
}

Rectangle getDrawableRect(Rectangle originalRect, Dimension drawingArea) {
    int x = originalRect.x;
    int y = originalRect.y;
    int width = originalRect.width;
    int height = originalRect.height;

    //Make sure rectangle width and height are positive.
    if (width < 0) {
        width = 0 - width;
        x = x - width + 1;
        if (x < 0) {
            width += x;
            x = 0;
        }
    }
    if (height < 0) {
        height = 0 - height;
        y = y - height + 1;
        if (y < 0) {
            height += y;
            y = 0;
        }
    }

    //The rectangle shouldn't extend past the drawing area.
    if ((x + width) > drawingArea.width) {
        width = drawingArea.width - x;
    }
    if ((y + height) > drawingArea.height) {
        height = drawingArea.height - y;
    }

    return new Rectangle(x, y, width, height);
}

}

此外,如果我在全屏模式下运行此代码,那么我会看到矩形仅在我松开鼠标后才出现在屏幕上.但我希望在拖动鼠标时将矩形显示在屏幕上,并且它应该根据当前鼠标坐标更改其尺寸.任何人都可以帮助我.

also if i run this code on full screen mode then i am seeing that the rectangle is appering on screen only after i released the mouse. but i want the rectangle to be on the screen while dragging the mouse and it should change it's dimension according to the current mouse coordinates. can any one help me pls.

推荐答案

作业?

基本上你需要做的是:

  1. 在鼠标按下时保持鼠标按下的坐标并重新绘制
  2. 鼠标移动时保持当前鼠标坐标并重新绘制
  3. 在鼠标向上时,取消鼠标向下坐标以指示没有矩形,然后重新绘制.
  4. 在绘画上,绘制背景,然后在 mousedown 和 cur-mouse 坐标之间矩形.

如果你不想保留背景图片,你可以用Graphics xor函数做一个技巧,绘制相同的矩形两次会擦除旧的矩形,所以你可以用它来直接恢复旧的图像图形对象.

if you don't want to keep a background image, you can do a trick with the Graphics xor function, drawing the same rect twice will erase the old rect, so you can use it to restore the old image straight on the graphics object.

代码异或用法示例:

public void paint(Graphics g)
{
   g.setXORMode(Color.black);
   // draw old rect if there is one. this will erase it
   // draw new rect, this will draw xored
   g.setDrawMode(); // restore normal draw mode
}

Xor 有一个有趣的特性:

Xor has the an interesting property:

xor(xor(x)) = x

因此对同一个像素进行两次异或运算可以恢复其原始颜色.

so xoring the same pixel twice restores it's original color.

这篇关于如何使用鼠标拖动事件在java小程序上绘制矩形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆