2009-07-12 3 views
2

У меня есть моя программа, которая может рисовать прямоугольники. У меня две проблемы, которые я не могу решить. После того, как я нарисую прямоугольник, он не останется. Единственный код, который у меня есть, который очищает холст под краской, перерисовывается только при перетаскивании мышью. Почему, когда мышь или мышь перемещается, мой холст очищается. Во-вторых, это не такая уж большая проблема, но я не могу понять, когда высота или ширина моего прямоугольника отрицательна, прямоугольник заполнен черным.Как нарисовать прямоугольник на java-апплете с помощью события перетаскивания мышью и сделать его неподвижным

package pracpapp2; 


import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 

public class MouseTracker4July extends JFrame 
    implements MouseListener, MouseMotionListener { 


    private static final long serialVersionUID = 1L; 
    private JLabel mousePosition; 
    int x, y; 
    int x1, x2, y1, y2; 
    int w, h; 
    private JLabel recStart; 
    private JLabel recStop; 
    private JLabel cords; 
    // set up GUI and register mouse event handlers 
    public MouseTracker4July() 
    { 
     super("Rectangle Drawer"); 

     mousePosition = new JLabel(); 
     mousePosition.setHorizontalAlignment(SwingConstants.CENTER); 
     getContentPane().add(mousePosition, BorderLayout.CENTER); 


     JLabel text1 = new JLabel(); 
     text1.setText("At the center the mouse pointer's coordinates will be displayed."); 
     getContentPane().add(text1, BorderLayout.SOUTH); 

     recStart = new JLabel(); 
     getContentPane().add(recStart, BorderLayout.WEST); 

     recStop = new JLabel(); 
     getContentPane().add(recStop, BorderLayout.EAST); 

     cords = new JLabel(); 
     getContentPane().add(cords, BorderLayout.NORTH); 


     addMouseListener(this);  // listens for own mouse and 
     addMouseMotionListener(this); // mouse-motion events 

     setSize(800, 600); 
     setVisible(true); 
    } 

    // MouseListener event handlers 
    // handle event when mouse released immediately after press 
    public void mouseClicked(MouseEvent event) 
    { 
     mousePosition.setText("Clicked at [" + event.getX() + 
     ", " + event.getY() + "]"); 
    } 

    // handle event when mouse pressed 
    public void mousePressed(MouseEvent event) 
    { 

     mousePosition.setText("Pressed at [" +(x1 = event.getX()) + 
     ", " + (y1 = event.getY()) + "]"); 

     recStart.setText("Start: [" + x1 + 
     ", " + y1 + "]"); 
    } 

    // handle event when mouse released after dragging 
    public void mouseReleased(MouseEvent event) 
    { 
    mousePosition.setText("Released at [" +(x2 = event.getX()) + 
     ", " + (y2 = event.getY()) + "]"); 

    recStop.setText("End: [" + x2 + 
     ", " + y2 + "]"); 

    } 

    // handle event when mouse enters area 
    public void mouseEntered(MouseEvent event) 
    { 
     mousePosition.setText("Mouse entered at [" + event.getX() + 
     ", " + event.getY() + "]"); 
    } 

    // handle event when mouse exits area 
    public void mouseExited(MouseEvent event) 
    { 
     mousePosition.setText("Mouse outside window"); 
    } 

    // MouseMotionListener event handlers 
    // handle event when user drags mouse with button pressed 
    public void mouseDragged(MouseEvent event) 
    { 
     mousePosition.setText("Dragged at [" + (x = event.getX()) + 
     ", " + (y = event.getY()) + "]"); 
     // call repaint which calls paint 
     repaint(); 

    } 

    // handle event when user moves mouse 
    public void mouseMoved(MouseEvent event) 
    { 
     mousePosition.setText("Moved at [" + event.getX() + 
     ", " + event.getY() + "]"); 
    } 

    public void paint(Graphics g) 
    { 
     super.paint(g); // clear the frame surface 
     g.drawString("Start Rec Here", x1, y1); 
     g.drawString("End Rec Here", x, y); 

     w = x1 - x; 
     h = y1 - y; 
     w = w * -1; 
     h = h * -1; 

     g.drawRect(x1, y1, w, h); 

     cords.setText("w = " + w + ", h = " + h); 
    } 

    public static void main(String args[]) 
    { 
     MouseTracker4July application = new MouseTracker4July(); 
     application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    } 

} // end class MouseTracker 

ответ

5

Ok, после перечитывая свой вопрос, кажется, вы могли бы заботиться меньше иметь несколько прямоугольников :)

Вот решение лишь один, в то время (что близко к тому, что вы должны были начать с) :

import java.awt.BorderLayout; 
import java.awt.Graphics; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 
import java.awt.event.MouseMotionListener; 

import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.SwingConstants; 

public class MouseTracker4July extends JFrame implements MouseListener, MouseMotionListener { 

    private static final long serialVersionUID = 1L; 
    private final JLabel mousePosition; 
    int x1, x2, y1, y2; 
    int x, y, w, h; 
    private final JLabel recStart; 
    private final JLabel recStop; 
    private final JLabel cords; // set up GUI and register mouse event handlers 
    boolean isNewRect = true; 

    public MouseTracker4July() { 
     super("Rectangle Drawer"); 

     this.mousePosition = new JLabel(); 
     this.mousePosition.setHorizontalAlignment(SwingConstants.CENTER); 
     getContentPane().add(this.mousePosition, BorderLayout.CENTER); 

     JLabel text1 = new JLabel(); 
     text1.setText("At the center the mouse pointer's coordinates will be displayed."); 
     getContentPane().add(text1, BorderLayout.SOUTH); 

     this.recStart = new JLabel(); 
     getContentPane().add(this.recStart, BorderLayout.WEST); 

     this.recStop = new JLabel(); 
     getContentPane().add(this.recStop, BorderLayout.EAST); 

     this.cords = new JLabel(); 
     getContentPane().add(this.cords, BorderLayout.NORTH); 

     addMouseListener(this); // listens for own mouse and 
     addMouseMotionListener(this); // mouse-motion events 

     setSize(800, 600); 
     setVisible(true); 

    } 

// MouseListener event handlers // handle event when mouse released immediately after press 
    public void mouseClicked(final MouseEvent event) { 
     this.mousePosition.setText("Clicked at [" + event.getX() + ", " + event.getY() + "]"); 

     repaint(); 
    } 

// handle event when mouse pressed 
    public void mousePressed(final MouseEvent event) { 

     this.mousePosition.setText("Pressed at [" + (this.x1 = event.getX()) + ", " + (this.y1 = event.getY()) + "]"); 

     this.recStart.setText("Start: [" + this.x1 + ", " + this.y1 + "]"); 

     this.isNewRect = true; 

     repaint(); 
    } 

// handle event when mouse released after dragging 
    public void mouseReleased(final MouseEvent event) { 
     this.mousePosition.setText("Released at [" + (this.x2 = event.getX()) + ", " + (this.y2 = event.getY()) + "]"); 

     this.recStop.setText("End: [" + this.x2 + ", " + this.y2 + "]"); 

     repaint(); 
    } 

// handle event when mouse enters area 
    public void mouseEntered(final MouseEvent event) { 
     this.mousePosition.setText("Mouse entered at [" + event.getX() + ", " + event.getY() + "]"); 
     repaint(); 
    } 

// handle event when mouse exits area 
    public void mouseExited(final MouseEvent event) { 
     this.mousePosition.setText("Mouse outside window"); 
     repaint(); 
    } 

// MouseMotionListener event handlers // handle event when user drags mouse with button pressed 
    public void mouseDragged(final MouseEvent event) { 
     this.mousePosition.setText("Dragged at [" + (this.x2 = event.getX()) + ", " + (this.y2 = event.getY()) + "]"); // call repaint which calls paint repaint(); 

     this.isNewRect = false; 

     repaint(); 
    } 

// handle event when user moves mouse 
    public void mouseMoved(final MouseEvent event) { 
     this.mousePosition.setText("Moved at [" + event.getX() + ", " + event.getY() + "]"); 
     repaint(); 
    } 

    @Override 
    public void paint(final Graphics g) { 
     super.paint(g); // clear the frame surface 
     g.drawString("Start Rec Here", this.x1, this.y1); 
     g.drawString("End Rec Here", this.x2, this.y2); 

     int width = this.x1 - this.x2; 
     int height = this.y1 - this.y2; 

     this.w = Math.abs(width); 
     this.h = Math.abs(height); 
     this.x = width < 0 ? this.x1 
      : this.x2; 
     this.y = height < 0 ? this.y1 
      : this.y2; 

     if (!this.isNewRect) { 
      g.drawRect(this.x, this.y, this.w, this.h); 
     } 

     this.cords.setText("w = " + this.w + ", h = " + this.h); 

    } 

    public static void main(final String args[]) { 
     MouseTracker4July application = new MouseTracker4July(); 
     application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    } 

} // end class MouseTracker 
+0

Это именно то, что мне нужно, я знал, что близко, я просто не мог понять, как закончить дело. Math.abs классный, потому что он сохраняет мою ширину и высоту положительным. Благодаря тонну. Еще один вопрос, все это «это». хорошей форме или личным предпочтениям? Мне просто интересно, потому что, поскольку я использую только один JFrame, разве это не избыточно? Еще раз спасибо. – Tyler

+0

Когда я перетаскиваю мышь, возникает много мерцания, вызванное переопределением метода paint() кадра, как я предложил ранее. – camickr

+0

Лично я бы сказал, что «это» использование немного предпочтительнее - есть и другие, которые бы вольно не соглашались. Рад помочь. – javamonkey79

4

Вам необходимо сохранить ваши нарисованные элементы в некоторой структуре данных и убедиться, что каждый элемент в структуре окрашен в холст при перекраске.

Кроме того, вам нужно добавить перерисовку к каждому из событий мыши.

Нравится это: (предполагается, что вы хотите сохранить ALL rect) - вы можете пойти с одним прямоугольником, исключив арреалиста и заменив его единственным прямым экземпляром.

import java.awt.BorderLayout; 
import java.awt.Graphics; 
import java.awt.Rectangle; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 
import java.awt.event.MouseMotionListener; 
import java.util.ArrayList; 

import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.SwingConstants; 

public class MouseTracker4July extends JFrame implements MouseListener, MouseMotionListener { 

    private static final long serialVersionUID = 1L; 
    private final JLabel mousePosition; 
    int x1, x2, y1, y2; 
    int w, h; 
    private final JLabel recStart; 
    private final JLabel recStop; 
    private final JLabel cords; // set up GUI and register mouse event handlers 
    private final ArrayList<Rectangle> rectangles = new ArrayList<Rectangle>(); 
    private boolean isNewRect = true; 

    public MouseTracker4July() { 
     super("Rectangle Drawer"); 

     this.mousePosition = new JLabel(); 
     this.mousePosition.setHorizontalAlignment(SwingConstants.CENTER); 
     getContentPane().add(this.mousePosition, BorderLayout.CENTER); 

     JLabel text1 = new JLabel(); 
     text1.setText("At the center the mouse pointer's coordinates will be displayed."); 
     getContentPane().add(text1, BorderLayout.SOUTH); 

     this.recStart = new JLabel(); 
     getContentPane().add(this.recStart, BorderLayout.WEST); 

     this.recStop = new JLabel(); 
     getContentPane().add(this.recStop, BorderLayout.EAST); 

     this.cords = new JLabel(); 
     getContentPane().add(this.cords, BorderLayout.NORTH); 

     addMouseListener(this); // listens for own mouse and 
     addMouseMotionListener(this); // mouse-motion events 

     setSize(800, 600); 
     setVisible(true); 

    } 

// MouseListener event handlers // handle event when mouse released immediately after press 
    public void mouseClicked(final MouseEvent event) { 
     this.mousePosition.setText("Clicked at [" + event.getX() + ", " + event.getY() + "]"); 

     repaint(); 
    } 

// handle event when mouse pressed 
    public void mousePressed(final MouseEvent event) { 

     this.mousePosition.setText("Pressed at [" + (this.x1 = event.getX()) + ", " + (this.y1 = event.getY()) + "]"); 

     this.recStart.setText("Start: [" + this.x1 + ", " + this.y1 + "]"); 

     repaint(); 
    } 

// handle event when mouse released after dragging 
    public void mouseReleased(final MouseEvent event) { 
     this.mousePosition.setText("Released at [" + (this.x2 = event.getX()) + ", " + (this.y2 = event.getY()) + "]"); 

     this.recStop.setText("End: [" + this.x2 + ", " + this.y2 + "]"); 

     Rectangle rectangle = getRectangleFromPoints(); 

     this.rectangles.add(rectangle); 

     this.w = this.h = this.x1 = this.y1 = this.x2 = this.y2 = 0; 
     this.isNewRect = true; 

     repaint(); 
    } 

    private Rectangle getRectangleFromPoints() { 
     int width = this.x1 - this.x2; 
     int height = this.y1 - this.y2; 
     Rectangle rectangle = new Rectangle(width < 0 ? this.x1 
      : this.x2, height < 0 ? this.y1 
      : this.y2, Math.abs(width), Math.abs(height)); 

     return rectangle; 
    } 

// handle event when mouse enters area 
    public void mouseEntered(final MouseEvent event) { 
     this.mousePosition.setText("Mouse entered at [" + event.getX() + ", " + event.getY() + "]"); 
     repaint(); 
    } 

// handle event when mouse exits area 
    public void mouseExited(final MouseEvent event) { 
     this.mousePosition.setText("Mouse outside window"); 
     repaint(); 
    } 

// MouseMotionListener event handlers // handle event when user drags mouse with button pressed 
    public void mouseDragged(final MouseEvent event) { 
     this.mousePosition.setText("Dragged at [" + (this.x2 = event.getX()) + ", " + (this.y2 = event.getY()) + "]"); // call repaint which calls paint repaint(); 

     this.isNewRect = false; 

     repaint(); 
    } 

// handle event when user moves mouse 
    public void mouseMoved(final MouseEvent event) { 
     this.mousePosition.setText("Moved at [" + event.getX() + ", " + event.getY() + "]"); 
     repaint(); 
    } 

    @Override 
    public void paint(final Graphics g) { 
     super.paint(g); // clear the frame surface 
     g.drawString("Start Rec Here", this.x1, this.y1); 
     g.drawString("End Rec Here", this.x2, this.y2); 

     Rectangle newRectangle = getRectangleFromPoints(); 
     if (!this.isNewRect) { 
      g.drawRect(newRectangle.x, newRectangle.y, newRectangle.width, newRectangle.height); 
     } 

     for(Rectangle rectangle : this.rectangles) { 
      g.drawRect(rectangle.x, rectangle.y, rectangle.width, rectangle.height); 
     } 

     this.cords.setText("w = " + this.w + ", h = " + this.h); 

    } 

    public static void main(final String args[]) { 
     MouseTracker4July application = new MouseTracker4July(); 
     application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    } 

} // end class MouseTracker 
+0

Это мое первое программирование на графике. Как я могу сохранить весь прямоугольник. У меня уже есть прямоугольные части (x, y, w, h), которые хранятся как int, тогда рисуется прямоугольник, но это мои целые числа постоянно обновляются, я не уверен, как их хранить на что-то статичное, которое может быть проведено на холсте. – Tyler

+0

Пользовательская покраска должна выполняться на JPanel или JComponent, а не на фактическом JFrame, и метод paintComponent() должен быть переопределен, а не метод paint(). – camickr

+0

@camickr - Я согласен, но ради понимания проблемы я не знаю, что это поможет Тайлеру в этом состоянии (в конечном счете, да). – javamonkey79

1

Читайте об этих двух Custom Painting Approaches. Один из подходов описан выше, а второй подход показывает, как использовать BufferedImage. Пример, используемый для обоих подходов, позволяет добавлять в рамку несколько прямоугольников.

0

Если вы не заботитесь информацию дисплея, просто удалите каждый «mousePosition.setText (...)» в слушателях мыши, они приведут к ненужной перерисовки() призваний.

Затем добавьте два поля: «ИНТ ге, гу,» добавить/изменить несколько методов, как показано ниже:

 public void mouseDragged(MouseEvent event) { 
//  mousePosition.setText("Dragged at [" + (x = event.getX()) + ", " 
//    + (y = event.getY()) + "]"); 
     // call repaint which calls paint 
     x = event.getX(); 
     y = event.getY(); 

     compRectPos(); 
     repaint(); 
    } 

    private void compRectPos() 
    { 
     rx = x1; 
     ry = y1; 

     w = x - x1; 
     h = y - y1; 

     if (w < 0) 
      rx += w; 
     if (h < 0) 
      ry += h; 

     w = Math.abs(w); 
     h = Math.abs(h); 

    } 

    public void paint(Graphics g) { 
     super.paint(g); // clear the frame surface 
     g.drawString("Start Rec Here", x1, y1); 
     g.drawString("End Rec Here", x, y); 

     g.drawRect(rx, ry, w, h); 

     cords.setText("w = " + w + ", h = " + h); 
    } 

Единственная проблема, которую я нашел в том, что прямоугольник не появляется, когда первым обращается ,