我试图在相当大的图像上绘制矩形,以获取图像内对象的像素坐标。我能够显示图像并使其可滚动,或者显示图像并能够在其顶部绘制矩形。...但不能同时显示两者。
很明显,我是在试图在其上绘制矩形的画布上绘制图像,但我一生都无法弄清楚如何使其全部并存。
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);
}
}
答案 0 :(得分:1)
您绘制图像的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();