gpt4 book ai didi

java - 在可滚动的 JPanel 上绘制形状

转载 作者:行者123 更新时间:2023-11-30 05:52:10 25 4
gpt4 key购买 nike

我正在尝试在相当大的图像上绘制矩形,以便获取图像内对象的像素坐标。我能够显示图像并使其可滚动,或者显示图像并能够在其顶部绘制矩形......但不能两者兼而有之。

很明显,我正在尝试在其上绘制矩形的 Canvas 上绘制图像,但我一生都无法弄清楚如何使它们共存。

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;

import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;

public class DrawRect extends JPanel {

int x, y, x2, y2;
private static final long serialVersionUID = 1L;
private BufferedImage image;
private JPanel canvas;

public static void main(String[] args) {
JPanel p = new DrawRect();
JFrame f = new JFrame();
f.setContentPane(p);
f.setSize(400, 300);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}

DrawRect() {
x = y = x2 = y2 = 0; //
MyMouseListener listener = new MyMouseListener();
addMouseListener(listener);
addMouseMotionListener(listener);

try {
this.image = ImageIO.read(new URL("https://previews.123rf.com/images/victoroancea/victoroancea1201/victoroancea120100059/12055848-tv-color-test-pattern-test-card-for-pal-and-ntsc.jpg"));
}catch(IOException ex) {
Logger.getLogger(DrawRect.class.getName()).log(Level.SEVERE, null, ex);
}

this.canvas = new JPanel() {
private static final long serialVersionUID = 1L;
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, null);
}
};
canvas.setPreferredSize(new Dimension(image.getWidth(), image.getHeight()));
JScrollPane sp = new JScrollPane(canvas);
setLayout(new BorderLayout());
add(sp, BorderLayout.CENTER);
}

public void setStartPoint(int x, int y) {
this.x = x;
this.y = y;
}

public void setEndPoint(int x, int y) {
x2 = (x);
y2 = (y);
}

public void drawRect(Graphics g, int x, int y, int x2, int y2) {
int px = Math.min(x,x2);
int py = Math.min(y,y2);
int pw=Math.abs(x-x2);
int ph=Math.abs(y-y2);
g.drawRect(px, py, pw, ph);
}

class MyMouseListener extends MouseAdapter {

public void mousePressed(MouseEvent e) {
setStartPoint(e.getX(), e.getY());
}

public void mouseDragged(MouseEvent e) {
setEndPoint(e.getX(), e.getY());
repaint();
}

public void mouseReleased(MouseEvent e) {
setEndPoint(e.getX(), e.getY());
repaint();
}
}

public void paintComponent(Graphics g) {
super.paintComponent(g);

g.setColor(Color.RED);
drawRect(g, x, y, x2, y2);
}
}

最佳答案

您的图像绘制 JPanel 必须与绘制矩形且添加了 MouseAdapter 的 JPanel 相同。例如:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Image;
import java.io.IOException;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;

@SuppressWarnings("serial")
public class DrawRect2 extends JPanel {
public static final String IMG_PATH = "https://previews.123rf.com/images/victoroancea"
+ "/victoroancea1201/victoroancea120100059"
+ "/12055848-tv-color-test-pattern-test-card-for-pal-and-ntsc.jpg";
private static final int PREF_W = 600;
private static final int PREF_H = PREF_W;
private DrawingPanel drawingPanel;

public DrawRect2(Image img) {
drawingPanel = new DrawingPanel(img);
JScrollPane scrollPane = new JScrollPane(drawingPanel);
MyMouse myMouse = new MyMouse();
drawingPanel.addMouseListener(myMouse);
drawingPanel.addMouseMotionListener(myMouse);

setLayout(new BorderLayout());
add(scrollPane);
}

@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}

private static void createAndShowGui() {
Image img = null;
try {
URL url = new URL(IMG_PATH);
img = ImageIO.read(url);
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
DrawRect2 mainPanel = new DrawRect2(img);

JFrame frame = new JFrame("DrawRect2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}

public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}

}

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;

import javax.swing.JPanel;

@SuppressWarnings("serial")
public class DrawingPanel extends JPanel {
private Image img;
private Rectangle rectangle;

public DrawingPanel(Image img) {
this.img = img;
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (img != null) {
g.drawImage(img, 0, 0, this);
}
if (rectangle != null) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setXORMode(Color.WHITE);
g2.draw(rectangle);
g2.dispose(); // since we created this object
}
}

@Override
public Dimension getPreferredSize() {
Dimension superSize = super.getPreferredSize();
if (img == null) {
return super.getPreferredSize();
} else {
int w = img.getWidth(this);
int h = img.getHeight(this);
return new Dimension(w, h);
}
}

public void setRectangle(Rectangle rectangle) {
this.rectangle = rectangle;
}
}

import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class MyMouse extends MouseAdapter {
private Point p1;

@Override
public void mousePressed(MouseEvent e) {
p1 = e.getPoint();
}

@Override
public void mouseDragged(MouseEvent e) {
if (p1 != null) {
createRect(e);
}
}

private void createRect(MouseEvent e) {
Point p2 = e.getPoint();
int x = Math.min(p1.x, p2.x);
int y = Math.min(p1.y, p2.y);
int width = Math.abs(p1.x - p2.x);
int height = Math.abs(p1.y - p2.y);

Rectangle r = new Rectangle(x, y, width, height);
((DrawingPanel) e.getSource()).setRectangle(r);
((DrawingPanel) e.getSource()).repaint();
}

@Override
public void mouseReleased(MouseEvent e) {
if (p1 != null) {
createRect(e);
}
p1 = null;
}
}

因此,在此 PaintComponent 方法中,我使用 Graphics2D XOR 模式绘制图像和矩形,以帮助显示线条,而不管背景颜色如何:

@SuppressWarnings("serial")
public class DrawingPanel extends JPanel {
private Image img;
private Rectangle rectangle;

public DrawingPanel(Image img) {
this.img = img;
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (img != null) {
g.drawImage(img, 0, 0, this);
}
if (rectangle != null) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setXORMode(Color.WHITE);
g2.draw(rectangle);
g2.dispose(); // since we created this object
}
}

我也有这个方法:

public void setRectangle(Rectangle rectangle) {
this.rectangle = rectangle;
}

允许 MouseListener/Adapter 将 Rectangle 传递到此 JPanel 中。

    Rectangle r = new Rectangle(x, y, width, height);
((DrawingPanel) e.getSource()).setRectangle(r);
((DrawingPanel) e.getSource()).repaint();

关于java - 在可滚动的 JPanel 上绘制形状,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53712597/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com