Tôi có một số mã để vẽ hình chữ nhật. Nó được sử dụng để vẽ hình chữ nhật trên JPanel
, để đánh dấu ranh giới của các tiện ích con. Ở đây mã đầu tiên, sau đó tôi sẽ giải thích vấn đề của tôi cq. câu hỏi.Java Swing - Cách tiếp cận hợp lệ để kéo hình chữ nhật vào một JPanel?
Trước hết, tôi có một lớp học (WidgetDrawingPanel
) mở rộng JPanel
.
public WidgetDrawingPanel(int width, int height) {
/*To make things visible at least*/
widgets.add(new Widget(10,10,100,100, WidgetType.TextField));
widgets.add(new Widget(50,50,100,200, WidgetType.TextField));
this.width = width;
this.height = height;
this.setBackground(Color.BLUE);
addListener(); //adds both MouseMotionListener and MouseListener
}
Dưới đây bạn sẽ thấy tôi tham chiếu ch
rất nhiều. Đây là CoordinateHolder
, giữ các tọa độ bắt đầu và hiện tại của chuyển động của chuột.
private void addListener() {
this.addMouseMotionListener(new MouseMotionListener() {
@Override
public void mouseDragged(MouseEvent arg0) {
ch.currentX = arg0.getX();
ch.currentY = arg0.getY();
System.out.println("dragging " + ch.currentX + ","+ch.currentY);
WidgetDrawingPanel.this.repaint();
}
});
this.addMouseListener(new MouseListener() {
@Override
public void mouseReleased(MouseEvent event) {
ch.endX = event.getX();
ch.endY = event.getY();
try {
checkCoords();
} catch (OutsidePanelException e) {
e.printStackTrace();
JOptionPane.showMessageDialog(null, "drawn Outside Panel");
}
}
@Override
public void mousePressed(MouseEvent event) {
ch = new CoordinateHolder(event.getX(), event.getY());
}
});
}
và, cuối cùng, phương pháp paintComponent(Grapics)
. Có vòng lặp qua Widgets
, thực ra chỉ được vẽ Rects
(thuộc tính x, y, w, h), nhưng có thêm một chút thông tin, không hữu ích trong phần bản vẽ của ứng dụng. Mỗi khi bạn nhả chuột, CoordinateHolder
được chuyển đổi thành một Widget và được thêm vào widgets
.
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
System.out.println("Paint");
g.setColor(Color.BLUE);
g.fillRect(0, 0, width, height); //making the whole panel blue
g.setColor(Color.RED);
Graphics2D g2 = (Graphics2D)g;
g2.setStroke(new BasicStroke(3));
for (Widget w : widgets) {
g.drawRect(w.getX(), w.getY(), w.getW(), w.getH());
}
if (ch != null)
g.drawRect(ch.startX, ch.startY, ch.currentX - ch.startX, ch.currentY - ch.startY);
}
Mã này đang làm việc, nhưng tôi nghi ngờ điều này rất hiệu quả và inperformant, như trên đang liên tục làm mới JPanel
trên kéo chuột, đó là, nói, một lần mỗi 10ms? Tôi cho rằng nó sẽ sớm bị chậm, đặc biệt là khi người dùng tạo ra một heck của một hình chữ nhật rất nhiều (cũng được liên tục vẽ lại, như được thấy trong painComponent(Graphics)
).
Câu hỏi cq. Sự cố
Có phương pháp tiêu thụ tài nguyên ít hơn, tốt hơn, nơi người dùng có thể kéo hình chữ nhật trơn tru không?
Tôi đã đọc câu trả lời cho số Drag rectangle on JFrame in Java này, nhưng tác giả của câu trả lời đó dường như cũng giống như tôi. Nhưng một lần nữa, đó là cách không hiệu quả, phải không? Hay máy tính có thể dễ dàng vẽ lại thành phần liên tục được không, và đây có thực sự là một cách tiếp cận hợp lệ không?
Cảm ơn, tôi sẽ kiểm tra BufferedImage sớm, nhưng nó có thể mất một thời gian, bởi vì tôi khá bận rộn. Và giả định của bạn là chính xác. – stealthjong
@ChristiaandeJong: vui lòng xem chỉnh sửa cho ví dụ [sscce] (http://sscce.org) –
Ví dụ hay. Ngay cả thông qua RDP, điều này diễn ra suôn sẻ. Tôi nghĩ tôi có thể sử dụng nó cho mục đích của mình. – stealthjong