闪烁的白色图形Java

时间:2015-05-06 01:00:47

标签: java swing

如何在不使屏幕闪烁白色的情况下从JFrame中清除单个形状。

import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Random;`

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;


public class Frame extends JFrame {
static Shape s;
Graphics2D g2D;
/**
 * 
 */
private static final long serialVersionUID = 7764273188525543212L;
private JPanel contentPane;
public Point startDrag = null, endDrag = null;
HashMap<Shape, Color> shapes = new HashMap<Shape, Color>();
/**
 * Launch the application.
 */
public static void main(String[] args) {
    Frame f = new Frame();
    f.setVisible(true);
}
/**
 * Create the frame.
 */
public Frame() {

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 450, 300);
    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    contentPane.setLayout(new BorderLayout(0, 0));
    setContentPane(contentPane);
    addMouseListener(new MouseAdapter() {

        @Override
        public void mousePressed(MouseEvent e) {
            startDrag = new Point(e.getX(), e.getY());
            endDrag = startDrag;
            repaint();
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            Shape s = makeRectangle(startDrag.x, startDrag.y, e.getX(),
                    e.getY());
            Color[] colors = {Color.MAGENTA, Color.CYAN, Color.RED,
                    Color.BLUE, Color.PINK, Color.yellow};
            Random r = new Random();
            int i = r.nextInt(colors.length - 1);
            shapes.put(s, colors[i]);
            endDrag = null;
            startDrag = null;
            repaint();
        }

    });
    addMouseMotionListener(new MouseMotionAdapter() {



        @Override
        public void mouseDragged(MouseEvent e) {
            endDrag = new Point(e.getX(), e.getY());
            repaint();

        }
    });
}
public void paint(Graphics g) {
    Graphics2D g2 = (Graphics2D) g;
    paintBackground(g2);
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
    g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
            0.50f));
    g2.setStroke(new BasicStroke(2));
    for (Entry<Shape, Color> s : shapes.entrySet()) {

        g2.setPaint(Color.BLACK);
        g2.draw(s.getKey());
        g2.setPaint(s.getValue());
        g2.fill(s.getKey());
    }
    if (startDrag != null) {
        if (endDrag != null) {

            g2.setStroke(new BasicStroke(5.0f));
            g2.setColor(Color.darkGray);

            s = makeRectangle(startDrag.x, startDrag.y, endDrag.x,
                    endDrag.y);
            g2.draw(s);
        }

    }
}
private Rectangle2D.Float makeRectangle(int x1, int y1, int x2, int y2) {
    return new Rectangle2D.Float(Math.min(x1, x2), Math.min(y1, y2),
            Math.abs(x1 - x2), Math.abs(y1 - y2));
}
private void paintBackground(Graphics2D g2) {
    clear(g2);
    g2.setPaint(Color.red);
    g2.setStroke(new BasicStroke(0.4f));
    for (int i = 0; i < getSize().width; i += 10) {
        Shape line = new Line2D.Float(i, 0, i, getSize().height);
        g2.draw(line);
    }

    for (int i = 0; i < getSize().height; i += 10) {
        Shape line = new Line2D.Float(0, i, getSize().width, i);
        g2.draw(line);
    }

}

private void clear(Graphics g) {
    g.clearRect(0, 0, getWidth(), getHeight());

}

}

// If you try this code, just drag and let go to make a rectangle.

但是当我拖动时,屏幕闪烁白光,所以我很难看到我在做什么。反正有没有以同样的方式使这项工作,但这比你看到的更快地清除JFrame?

1 个答案:

答案 0 :(得分:2)

不要直接在JFrame中绘制。而是在JPanel的func createLaser()->SKSpriteNode { let laserBeam = SKSpriteNode(imageNamed: "laserBeam") laserBeam.name = "laserBeam" laserBeam.position.x = shipNode.position.x laserBeam.position.y = shipNode.position.y laserBeam.physicsBody = SKPhysicsBody(circleOfRadius: 10.0) laserBeam.physicsBody?.dynamic = true laserBeam.physicsBody?.affectedByGravity = false laserBeam.zRotation = shipNode.zRotation laserBeam.physicsBody?.mass = 1.0 laserBeam.physicsBody?.velocity.dx = kLaserSpeed * sin(shipNode.zRotation ) * -1 //TODO apply an impulse instead? laserBeam.physicsBody?.velocity.dy = kLaserSpeed * cos(shipNode.zRotation) * 1 println("in create Laser ship rotation = \(shipNode.zRotation), dx = \(laserBeam.physicsBody?.velocity.dx), dy = \(laserBeam.physicsBody?.velocity.dy)") return laserBeam } 方法中绘制。请务必在覆盖范围内调用paintComponent(Graphics g)。这将默认为您提供双缓冲,并可能有助于闪烁。

如,

super.paintComponent(g)

请注意,我扩展了JPanel以便我可以使用它的paintComponent方法,并且我调用了super方法。我还使用了LinkedHashMap,以便保持Map的输入顺序。