<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # 命中測試,移動物體 > 原文: [https://zetcode.com/gfx/java2d/hitmove/](https://zetcode.com/gfx/java2d/hitmove/) 在 Java 2D 編程教程的這一部分中,我們首先討論命中測試。 我們展示了如何確定是否在面板上的某個形狀內單擊。 在第二個示例中,我們創建兩個形狀,可以用鼠標在面板上移動它們,并用鼠標滾輪調整它們的大小。 在最后一個示例中,我們將調整具有兩個控制點的矩形的大小。 ## 命中測試 命中測試確定我們是否已經用鼠標指針單擊了`Shape`內部。 每個`Shape`都有`contains()`方法。 該方法測試指定的`Point2D`是否在`Shape`的邊界內。 `HitTestingEx.java` ```java package com.zetcode; import java.awt.AlphaComposite; import java.awt.Color; import java.awt.EventQueue; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.geom.Ellipse2D; import java.awt.geom.Rectangle2D; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.JFrame; import javax.swing.JPanel; class Surface extends JPanel { private Rectangle2D rect; private Ellipse2D ellipse; private float alpha_rectangle; private float alpha_ellipse; public Surface() { initSurface(); } private void initSurface() { addMouseListener(new HitTestAdapter()); rect = new Rectangle2D.Float(20f, 20f, 80f, 50f); ellipse = new Ellipse2D.Float(120f, 30f, 60f, 60f); alpha_rectangle = 1f; alpha_ellipse = 1f; } private void doDrawing(Graphics g) { Graphics2D g2d = (Graphics2D) g.create(); g2d.setPaint(new Color(50, 50, 50)); RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); rh.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); g2d.setRenderingHints(rh); g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha_rectangle)); g2d.fill(rect); g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha_ellipse)); g2d.fill(ellipse); g2d.dispose(); } @Override public void paintComponent(Graphics g) { super.paintComponent(g); doDrawing(g); } class RectRunnable implements Runnable { private Thread runner; public RectRunnable() { initThread(); } private void initThread() { runner = new Thread(this); runner.start(); } @Override public void run() { while (alpha_rectangle >= 0) { repaint(); alpha_rectangle += -0.01f; if (alpha_rectangle < 0) { alpha_rectangle = 0; } try { Thread.sleep(50); } catch (InterruptedException ex) { Logger.getLogger(Surface.class.getName()).log(Level.SEVERE, null, ex); } } } } class HitTestAdapter extends MouseAdapter implements Runnable { private RectRunnable rectAnimator; private Thread ellipseAnimator; @Override public void mousePressed(MouseEvent e) { int x = e.getX(); int y = e.getY(); if (rect.contains(x, y)) { rectAnimator = new RectRunnable(); } if (ellipse.contains(x, y)) { ellipseAnimator = new Thread(this); ellipseAnimator.start(); } } @Override public void run() { while (alpha_ellipse >= 0) { repaint(); alpha_ellipse += -0.01f; if (alpha_ellipse < 0) { alpha_ellipse = 0; } try { Thread.sleep(50); } catch (InterruptedException ex) { Logger.getLogger(Surface.class.getName()).log(Level.SEVERE, null, ex); } } } } } public class HitTestingEx extends JFrame { public HitTestingEx() { add(new Surface()); setTitle("Hit testing"); setSize(250, 150); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLocationRelativeTo(null); } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { HitTestingEx ex = new HitTestingEx(); ex.setVisible(true); } }); } } ``` 在我們的示例中,我們有兩個`Shapes`:一個矩形和一個圓形。 通過單擊它們,它們逐漸開始消失。 在此示例中,我們使用線程。 ```java private Rectangle2D rect; private Ellipse2D ellipse; ``` 我們使用矩形和橢圓形。 ```java private float alpha_rectangle; private float alpha_ellipse; ``` 這兩個變量控制兩個幾何對象的透明度。 ```java g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha_rectangle)); g2d.fill(rect); ``` 在`doDrawing()`方法內部,我們設置矩形的透明度。 `alpha_rectangle`在專用的`Thread`內部進行計算。 `HitTestAdapter`類負責處理鼠標事件。 它確實實現了`Runnable`接口,這意味著它還創建了第一個線程。 ```java if (ellipse.contains(x, y)) { ellipseAnimator = new Thread(this); ellipseAnimator.start(); } ``` 如果我們在橢圓內按下,將創建一個新的`Thread`。 該線程調用`run()`方法。 在我們的例子中,它是類本身的`run()`方法(`HitTestAdapter`)。 ```java if (rect.contains(x, y)) { rectAnimator = new RectRunnable(); } ``` 對于矩形,我們有一個單獨的內部類-`RectRunnable`類。 此類在構造器中創建自己的線程。 ```java public void run() { while (alpha_ellipse >= 0) { repaint(); alpha_ellipse += -0.01f; ... } ``` 請注意,`run()`方法僅被調用一次。 要實際執行某項操作,我們必須實現一個`while`循環。 `while`循環重新繪制面板并減小`alpha_ellipse`變量。 ![Hit testing](https://img.kancloud.cn/7e/ac/7eac14eb183c8b203abacf92b0ca3472_250x150.jpg) 圖:點擊測試 ## 移動和縮放 在下一部分中,我們將學習如何使用面板上的鼠標移動和縮放圖形對象。 它可用于在我們的應用中移動和縮放圖表,圖表或其他各種對象。 `MovingScalingEx.java` ```java package com.zetcode; import java.awt.Color; import java.awt.EventQueue; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseWheelEvent; import java.awt.event.MouseWheelListener; import java.awt.geom.Ellipse2D; import java.awt.geom.Rectangle2D; import javax.swing.JFrame; import javax.swing.JPanel; class Surface extends JPanel { private ZRectangle zrect; private ZEllipse zell; public Surface() { initUI(); } private void initUI() { MovingAdapter ma = new MovingAdapter(); addMouseMotionListener(ma); addMouseListener(ma); addMouseWheelListener(new ScaleHandler()); zrect = new ZRectangle(50, 50, 50, 50); zell = new ZEllipse(150, 70, 80, 80); } private void doDrawing(Graphics g) { Graphics2D g2d = (Graphics2D) g; Font font = new Font("Serif", Font.BOLD, 40); g2d.setFont(font); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); g2d.setPaint(new Color(0, 0, 200)); g2d.fill(zrect); g2d.setPaint(new Color(0, 200, 0)); g2d.fill(zell); } @Override public void paintComponent(Graphics g) { super.paintComponent(g); doDrawing(g); } class ZEllipse extends Ellipse2D.Float { public ZEllipse(float x, float y, float width, float height) { setFrame(x, y, width, height); } public boolean isHit(float x, float y) { return getBounds2D().contains(x, y); } public void addX(float x) { this.x += x; } public void addY(float y) { this.y += y; } public void addWidth(float w) { this.width += w; } public void addHeight(float h) { this.height += h; } } class ZRectangle extends Rectangle2D.Float { public ZRectangle(float x, float y, float width, float height) { setRect(x, y, width, height); } public boolean isHit(float x, float y) { return getBounds2D().contains(x, y); } public void addX(float x) { this.x += x; } public void addY(float y) { this.y += y; } public void addWidth(float w) { this.width += w; } public void addHeight(float h) { this.height += h; } } class MovingAdapter extends MouseAdapter { private int x; private int y; @Override public void mousePressed(MouseEvent e) { x = e.getX(); y = e.getY(); } @Override public void mouseDragged(MouseEvent e) { doMove(e); } private void doMove(MouseEvent e) { int dx = e.getX() - x; int dy = e.getY() - y; if (zrect.isHit(x, y)) { zrect.addX(dx); zrect.addY(dy); repaint(); } if (zell.isHit(x, y)) { zell.addX(dx); zell.addY(dy); repaint(); } x += dx; y += dy; } } class ScaleHandler implements MouseWheelListener { @Override public void mouseWheelMoved(MouseWheelEvent e) { doScale(e); } private void doScale(MouseWheelEvent e) { int x = e.getX(); int y = e.getY(); if (e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) { if (zrect.isHit(x, y)) { float amount = e.getWheelRotation() * 5f; zrect.addWidth(amount); zrect.addHeight(amount); repaint(); } if (zell.isHit(x, y)) { float amount = e.getWheelRotation() * 5f; zell.addWidth(amount); zell.addHeight(amount); repaint(); } } } } } public class MovingScalingEx extends JFrame { public MovingScalingEx() { initUI(); } private void initUI() { add(new Surface()); setTitle("Moving and scaling"); setSize(300, 300); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLocationRelativeTo(null); } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { MovingScalingEx ex = new MovingScalingEx(); ex.setVisible(true); } }); } } ``` 在我們的代碼示例中,我們有兩個圖形對象:一個矩形和一個圓形。 我們可以通過單擊它們并拖動它們來移動它們。 我們還可以通過將鼠標光標放在對象上并移動鼠標滾輪來放大或縮小它們。 ```java private ZRectangle zrect; private ZEllipse zell; ``` 正如我們已經提到的,面板上有一個矩形和一個橢圓。 這兩個類都擴展了 Java AWT 包中內置類的功能。 ```java addMouseMotionListener(ma); addMouseListener(ma); addMouseWheelListener(new ScaleHandler()); ``` 我們注冊了三個監聽器。 這些監聽器捕獲鼠標按下,鼠標拖動和鼠標滾輪事件。 ```java class ZEllipse extends Ellipse2D.Float { public ZEllipse(float x, float y, float width, float height) { setFrame(x, y, width, height); } public boolean isHit(float x, float y) { return getBounds2D().contains(x, y); } ... } ``` 這段代碼摘錄顯示了`ZEllipse`類。 它擴展了內置的`Ellipse2D.Float`類。 它增加了縮放和移動橢圓的功能。 例如,`isHit()`方法確定鼠標指針是否在橢圓區域內。 `MovingAdapter`類處理鼠標按下和鼠標拖動事件。 ```java @Override public void mousePressed(MouseEvent e) { x = e.getX(); y = e.getY(); } ``` 在`mousePressed()`方法中,我們存儲對象的初始 x 和 y 坐標。 ```java int dx = e.getX() - x; int dy = e.getY() - y; ``` 在`doMove()`方法內部,我們計算拖動對象的距離。 ```java if (zrect.isHit(x, y)) { zrect.addX(dx); zrect.addY(dy); repaint(); } ``` 如果在矩形區域內,則更新矩形的 x 和 y 坐標并重新繪制面板。 ```java x += dx; y += dy; ``` 初始坐標將更新。 `ScaleHandler`類處理對象的縮放。 ```java if (e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) { if (zrect.isHit(x, y)) { float amount = e.getWheelRotation() * 5f; zrect.addWidth(amount); zrect.addHeight(amount); repaint(); } ... } ``` 如果移動鼠標滾輪,并且光標位于矩形區域內,則將調整矩形大小并重新繪制面板。 通過`getWheelRotation()`方法計算縮放比例,該方法返回車輪旋轉量。 ## 調整矩形大小 在下一個示例中,我們顯示如何調整形狀的大小。 我們的形狀是一個矩形。 在矩形上,我們繪制了兩個小的黑色矩形。 通過單擊這些小矩形并拖動它們,我們可以調整主矩形的大小。 `ResizingRectangleEx.java` ```java package com.zetcode; import java.awt.EventQueue; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Point; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import javax.swing.JFrame; import javax.swing.JPanel; class Surface extends JPanel { private Point2D[] points; private final int SIZE = 8; private int pos; public Surface() { initUI(); } private void initUI() { addMouseListener(new ShapeTestAdapter()); addMouseMotionListener(new ShapeTestAdapter()); pos = -1; points = new Point2D[2]; points[0] = new Point2D.Double(50, 50); points[1] = new Point2D.Double(150, 100); } private void doDrawing(Graphics g) { Graphics2D g2 = (Graphics2D) g; for (Point2D point : points) { double x = point.getX() - SIZE / 2; double y = point.getY() - SIZE / 2; g2.fill(new Rectangle2D.Double(x, y, SIZE, SIZE)); } Rectangle2D r = new Rectangle2D.Double(); r.setFrameFromDiagonal(points[0], points[1]); g2.draw(r); } @Override public void paintComponent(Graphics g) { super.paintComponent(g); doDrawing(g); } private class ShapeTestAdapter extends MouseAdapter { @Override public void mousePressed(MouseEvent event) { Point p = event.getPoint(); for (int i = 0; i < points.length; i++) { double x = points[i].getX() - SIZE / 2; double y = points[i].getY() - SIZE / 2; Rectangle2D r = new Rectangle2D.Double(x, y, SIZE, SIZE); if (r.contains(p)) { pos = i; return; } } } @Override public void mouseReleased(MouseEvent event) { pos = -1; } @Override public void mouseDragged(MouseEvent event) { if (pos == -1) { return; } points[pos] = event.getPoint(); repaint(); } } } public class ResizingRectangleEx extends JFrame { public ResizingRectangleEx() { initUI(); } private void initUI() { add(new Surface()); setTitle("Resize rectangle"); setSize(300, 300); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLocationRelativeTo(null); } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { ResizingRectangleEx ex = new ResizingRectangleEx(); ex.setVisible(true); } }); } } ``` 有兩種創建矩形的方法。 一種方法是提供左上角點的 x 和 y 坐標以及矩形的寬度和高度。 另一種方法是提供左上角和右下角點。 在我們的代碼示例中,我們將同時使用這兩種方法。 ```java private Point2D[] points; ``` 在此數組中,我們存儲構成矩形的點。 ```java private final int SIZE = 8; ``` 這是黑色小矩形的大小。 ```java points = new Point2D[2]; points[0] = new Point2D.Double(50, 50); points[1] = new Point2D.Double(150, 100); ``` 這些是矩形的初始坐標。 ```java for (int i = 0; i < points.length; i++) { double x = points[i].getX() - SIZE / 2; double y = points[i].getY() - SIZE / 2; g2.fill(new Rectangle2D.Double(x, y, SIZE, SIZE)); } ``` 此代碼繪制了兩個小的控制矩形。 ```java Rectangle2D s = new Rectangle2D.Double(); s.setFrameFromDiagonal(points[0], points[1]); g2.draw(s); ``` 在這里,我們從這些點繪制一個矩形。 ```java @Override public void mousePressed(MouseEvent event) { Point p = event.getPoint(); for (int i = 0; i < points.length; i++) { double x = points[i].getX() - SIZE / 2; double y = points[i].getY() - SIZE / 2; Rectangle2D r = new Rectangle2D.Double(x, y, SIZE, SIZE); if (r.contains(p)) { pos = i; return; } } } ``` 在`mousePressed()`方法中,我們確定是否單擊了兩個控制點之一。 如果我們點擊其中一個,則`pos`變量將存儲其中的哪個。 ```java @Override public void mouseDragged(MouseEvent event) { if (pos == -1) { return; } points[pos] = event.getPoint(); repaint(); } ``` 在這里,矩形是動態調整大小的。 在`mouseDragged()`事件期間,我們獲取當前點,更新點數組并重新繪制面板。 ![Resize Rectangle](https://img.kancloud.cn/0f/d3/0fd3bcda30627fe4cc511af05f85b29b_300x300.jpg) 圖:縮放矩形 在 Java 2D 教程的這一部分中,我們介紹了命中測試和移動對象。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看