Java Swing Rectangle2D:如何选择顶部的一个
简单问题: 我在一个JPane中绘制了多个具有重叠的矩形2D(或其他形状)。 我想通过单击重叠区域选择顶部的一个,然后执行一些操作,例如更改颜色或拖动 但是我不能选择我想要的 形状的顺序不受控制 我找到了一个方法setComponentZOrder,但它是针对组件的,而不是针对Rectangle2D的Java Swing Rectangle2D:如何选择顶部的一个,java,swing,Java,Swing,简单问题: 我在一个JPane中绘制了多个具有重叠的矩形2D(或其他形状)。 我想通过单击重叠区域选择顶部的一个,然后执行一些操作,例如更改颜色或拖动 但是我不能选择我想要的 形状的顺序不受控制 我找到了一个方法setComponentZOrder,但它是针对组件的,而不是针对Rectangle2D的 我认为这是一个典型的问题,但我找不到答案。矩形2D等形状的绘制顺序取决于它们在任何集合中的保存顺序,因为该集合在JComponent(如JPanel)的绘制方法中迭代。因此,集合中的最后一项,无论
我认为这是一个典型的问题,但我找不到答案。矩形2D等形状的绘制顺序取决于它们在任何集合中的保存顺序,因为该集合在JComponent(如JPanel)的绘制方法中迭代。因此,集合中的最后一项,无论是数组、ArrayList还是LinkedList,都绘制在顶部 因此,如果您想在鼠标按下或单击时获得顶部形状,那么关键是向后迭代同一集合,获得包含(点p)鼠标点位置的第一个形状。就这样 例如,请看我的代码,它在这个方法中只执行his,这个方法是从MouseListener(实际上是MouseDapAter)调用的: 例如:
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Path2D;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import javax.swing.*;
@SuppressWarnings("serial")
public class RandomShapes extends JPanel {
private static final Stroke STROKE = new BasicStroke(4f);
private static final int PREF_W = 800;
private static final int PREF_H = 650;
private static final int SHAPE_COUNT = 30;
private static final int SHAPE_WIDTH = 100;
private static final int SHAPE_HEIGHT = SHAPE_WIDTH;
private List<Path2D> paths = new ArrayList<>();
private Map<Path2D, Color> colorMap = new HashMap<>();
private Random random = new Random();
public RandomShapes() {
for (int i = 0; i < SHAPE_COUNT; i++) {
Shape shape = createRandomShape(i);
Path2D path = new Path2D.Double(shape);
paths.add(path);
colorMap.put(path, createRandomColor());
}
MyMouse myMouse = new MyMouse();
addMouseListener(myMouse);
addMouseMotionListener(myMouse);
}
private class MyMouse extends MouseAdapter {
private Path2D selectedPath = null;
private Point p1;
@Override
public void mousePressed(MouseEvent e) {
if (e.getButton() != MouseEvent.BUTTON1) {
return;
}
for (int i = paths.size() - 1; i >= 0; i--) {
Path2D path = paths.get(i);
if (path.contains(e.getPoint())) {
selectedPath = path;
p1 = e.getPoint();
paths.remove(selectedPath);
paths.add(selectedPath);
repaint();
break;
}
}
}
private void movePath(MouseEvent e) {
Point p2 = e.getPoint();
int tx = p2.x - p1.x;
int ty = p2.y - p1.y;
p1 = p2;
AffineTransform at = AffineTransform.getTranslateInstance(tx, ty);
selectedPath.transform(at);
repaint();
}
@Override
public void mouseDragged(MouseEvent e) {
if (selectedPath != null) {
movePath(e);
}
}
@Override
public void mouseReleased(MouseEvent e) {
if (selectedPath != null) {
movePath(e);
}
selectedPath = null;
}
}
private Color createRandomColor() {
float min = 0.2f;
float h = random.nextFloat();
float s = min * random.nextFloat() + (1f - min);
float b = min * random.nextFloat() + (1f - min);
return Color.getHSBColor(h, s, b);
}
private Shape createRandomShape(int i) {
Dimension size = getPreferredSize();
int x = random.nextInt(size.width - SHAPE_WIDTH);
int y = random.nextInt(size.height - SHAPE_HEIGHT);
switch (i % 3) {
case 0:
return new Ellipse2D.Double(x, y, SHAPE_WIDTH, SHAPE_HEIGHT);
case 1:
return new Rectangle2D.Double(x, y, SHAPE_WIDTH, SHAPE_HEIGHT);
case 2:
return new RoundRectangle2D.Double(x, y, SHAPE_WIDTH, SHAPE_HEIGHT, 15, 15);
default:
break;
}
return null;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setStroke(STROKE);
for (Path2D path : paths) {
g2.setColor(colorMap.get(path));
g2.fill(path);
g2.setColor(colorMap.get(path).darker());
g2.draw(path);
}
}
@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private static void createAndShowGui() {
JFrame frame = new JFrame("RandomShapes");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new RandomShapes());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
import java.awt.BasicStroke;
导入java.awt.Color;
导入java.awt.Dimension;
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入java.awt.Point;
导入java.awt.RenderingHints;
导入java.awt.Shape;
导入java.awt.Stroke;
导入java.awt.event.MouseAdapter;
导入java.awt.event.MouseEvent;
导入java.awt.geom.AffineTransform;
导入java.awt.geom.Ellipse2D;
导入java.awt.geom.Path2D;
导入java.awt.geom.Rectangle2D;
导入java.awt.geom.RoundRectangle2D;
导入java.util.ArrayList;
导入java.util.HashMap;
导入java.util.List;
导入java.util.Map;
导入java.util.Random;
导入javax.swing.*;
@抑制警告(“串行”)
公共类扩展JPanel{
专用静态最终冲程=新基本冲程(4f);
专用静态最终整型预调W=800;
专用静态最终int PREF_H=650;
私有静态最终整型计数=30;
私有静态最终整型_宽度=100;
私有静态最终整数形状高度=形状宽度;
私有列表路径=新的ArrayList();
私有映射colorMap=newhashmap();
私有随机=新随机();
公共形状(){
对于(int i=0;i=0;i--){
Path2D path=路径。获取(i);
if(path.contains(例如getPoint())){
selectedPath=路径;
p1=e.getPoint();
路径。删除(selectedPath);
路径。添加(selectedPath);
重新油漆();
打破
}
}
}
专用void移动路径(MouseEvent e){
点p2=e.getPoint();
int tx=p2.x-p1.x;
int-ty=p2.y-p1.y;
p1=p2;
AffineTransform at=AffineTransform.getTranslateInstance(tx,ty);
选择路径转换(at);
重新油漆();
}
@凌驾
公共无效鼠标标记(鼠标事件e){
如果(selectedPath!=null){
移动路径(e);
}
}
@凌驾
公共无效MouseEvent(MouseEvent e){
如果(selectedPath!=null){
移动路径(e);
}
selectedPath=null;
}
}
私有颜色createRandomColor(){
浮动最小值=0.2f;
float h=random.nextFloat();
float s=min*random.nextFloat()+(1f-min);
float b=min*random.nextFloat()+(1f-min);
返回颜色。getHSBColor(h、s、b);
}
私有形状createRandomShape(int i){
维度大小=getPreferredSize();
int x=random.nextInt(size.width-SHAPE\u width);
int y=random.nextInt(size.height-SHAPE\u height);
交换机(i%3){
案例0:
返回新的椭圆2d.Double(x,y,SHAPE\u宽度,SHAPE\u高度);
案例1:
返回新的矩形2D.Double(x,y,SHAPE\u宽度,SHAPE\u高度);
案例2:
返回新的RoundRectangle2D.Double(x,y,SHAPE\u宽度,SHAPE\u高度,15,15);
违约:
打破
}
返回null;
}
@凌驾
受保护组件(图形g){
超级组件(g);
图形2d g2=(图形2d)g;
g2.setRenderingHint(renderingHits.KEY\u ANTIALIASING,renderingHits.VALUE\u ANTIALIAS\u ON);
g2.设定行程(行程);
用于(路径2D路径:路径){
g2.setColor(colorMap.get(path));
g2.填充(路径);
g2.setColor(colorMap.get(path.darker());
g2.绘制(路径);
}
}
@凌驾
公共维度getPreferredSize(){
如果(isPreferredSizeSet()){
返回super.getPreferredSize();
}
返回新维度(PREF_W,PREF_H);
}
私有静态void createAndShowGui(){
JFrame=新JFrame(“随机形状”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(新的RandomShapes());
frame.pack();
frame.setLocationRela
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Path2D;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import javax.swing.*;
@SuppressWarnings("serial")
public class RandomShapes extends JPanel {
private static final Stroke STROKE = new BasicStroke(4f);
private static final int PREF_W = 800;
private static final int PREF_H = 650;
private static final int SHAPE_COUNT = 30;
private static final int SHAPE_WIDTH = 100;
private static final int SHAPE_HEIGHT = SHAPE_WIDTH;
private List<Path2D> paths = new ArrayList<>();
private Map<Path2D, Color> colorMap = new HashMap<>();
private Random random = new Random();
public RandomShapes() {
for (int i = 0; i < SHAPE_COUNT; i++) {
Shape shape = createRandomShape(i);
Path2D path = new Path2D.Double(shape);
paths.add(path);
colorMap.put(path, createRandomColor());
}
MyMouse myMouse = new MyMouse();
addMouseListener(myMouse);
addMouseMotionListener(myMouse);
}
private class MyMouse extends MouseAdapter {
private Path2D selectedPath = null;
private Point p1;
@Override
public void mousePressed(MouseEvent e) {
if (e.getButton() != MouseEvent.BUTTON1) {
return;
}
for (int i = paths.size() - 1; i >= 0; i--) {
Path2D path = paths.get(i);
if (path.contains(e.getPoint())) {
selectedPath = path;
p1 = e.getPoint();
paths.remove(selectedPath);
paths.add(selectedPath);
repaint();
break;
}
}
}
private void movePath(MouseEvent e) {
Point p2 = e.getPoint();
int tx = p2.x - p1.x;
int ty = p2.y - p1.y;
p1 = p2;
AffineTransform at = AffineTransform.getTranslateInstance(tx, ty);
selectedPath.transform(at);
repaint();
}
@Override
public void mouseDragged(MouseEvent e) {
if (selectedPath != null) {
movePath(e);
}
}
@Override
public void mouseReleased(MouseEvent e) {
if (selectedPath != null) {
movePath(e);
}
selectedPath = null;
}
}
private Color createRandomColor() {
float min = 0.2f;
float h = random.nextFloat();
float s = min * random.nextFloat() + (1f - min);
float b = min * random.nextFloat() + (1f - min);
return Color.getHSBColor(h, s, b);
}
private Shape createRandomShape(int i) {
Dimension size = getPreferredSize();
int x = random.nextInt(size.width - SHAPE_WIDTH);
int y = random.nextInt(size.height - SHAPE_HEIGHT);
switch (i % 3) {
case 0:
return new Ellipse2D.Double(x, y, SHAPE_WIDTH, SHAPE_HEIGHT);
case 1:
return new Rectangle2D.Double(x, y, SHAPE_WIDTH, SHAPE_HEIGHT);
case 2:
return new RoundRectangle2D.Double(x, y, SHAPE_WIDTH, SHAPE_HEIGHT, 15, 15);
default:
break;
}
return null;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setStroke(STROKE);
for (Path2D path : paths) {
g2.setColor(colorMap.get(path));
g2.fill(path);
g2.setColor(colorMap.get(path).darker());
g2.draw(path);
}
}
@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private static void createAndShowGui() {
JFrame frame = new JFrame("RandomShapes");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new RandomShapes());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}