Java 如何使用画布根据用户输入绘制多个矩形?
因此,基本上我正在编写一个程序,用户点击并拖动鼠标到他/她想要的大小,然后放手,根据JComboBox中的选择填充一个矩形 我实现的是MouseListener和MouseMotionListener来跟踪鼠标的位置,并根据用户第一次单击的位置绘制一个矩形,然后将鼠标放在哪里 当用户单击并拖动(但不放手)时,会出现drawRect()而不是fillRect()(如中所示,矩形不会填充-只有当用户释放鼠标时,矩形才会填充颜色) 此类创建一个Rect对象,该对象在构造函数中有另一部分,即所选的颜色(在下面的ColorListener类中确定) 这就是我包含实例变量的地方,所有内容都在下面的构造函数中实例化:Java 如何使用画布根据用户输入绘制多个矩形?,java,swing,mouse-listeners,Java,Swing,Mouse Listeners,因此,基本上我正在编写一个程序,用户点击并拖动鼠标到他/她想要的大小,然后放手,根据JComboBox中的选择填充一个矩形 我实现的是MouseListener和MouseMotionListener来跟踪鼠标的位置,并根据用户第一次单击的位置绘制一个矩形,然后将鼠标放在哪里 当用户单击并拖动(但不放手)时,会出现drawRect()而不是fillRect()(如中所示,矩形不会填充-只有当用户释放鼠标时,矩形才会填充颜色) 此类创建一个Rect对象,该对象在构造函数中有另一部分,即所选的颜色
private ArrayList<Rect> rectList;
private Color currentColor;
private Canvas canvas;
private JPanel controlPanel;
private JButton undo, erase;
private JComboBox comboBox;
private int xStart, yStart, xEnd, yEnd;
private Graphics page;
private Point pt = null;
private PointListener pointListener;
private ColorListener colorListener;
public WholePanel()
{
// here we use black to draw a rectangle
currentColor = Color.black;
pointListener = new PointListener();
addMouseListener(pointListener);
addMouseMotionListener(pointListener);
String[] listOfColors = {"black", "red", "blue", "green", "orange"};
comboBox = new JComboBox(listOfColors);
comboBox.setSelectedIndex(0);
rectList = new ArrayList<Rect>();
controlPanel = new JPanel(new GridLayout(1,3));
undo = new JButton("Undo");
erase = new JButton("Erase");
controlPanel.add(comboBox);
controlPanel.add(undo);
controlPanel.add(erase);
undo.addActionListener(new ButtonListener());
erase.addActionListener(new ButtonListener());
canvas = new Canvas();
JSplitPane sp = new JSplitPane(JSplitPane.VERTICAL_SPLIT, controlPanel, canvas);
setLayout(new BorderLayout());
add(sp);
}
Canvas类创建允许绘制对象的空间
private class Canvas extends JPanel
{
public void paintComponent(Graphics page)
{
super.paintComponent(page);
setBackground(Color.white);
if (pt != null)
{
Rect rect = new Rect(xStart, yStart, xEnd-xStart, yEnd-yStart, currentColor);
rect.draw(page);
}
}
}
PointListener类查找存在的所有点,如用户单击的位置、用户拖动的位置以及用户释放的位置
private class PointListener implements MouseListener, MouseMotionListener
{
public void mousePressed(MouseEvent event)
{
pt = event.getPoint();
xStart = pt.x;
yStart = pt.y;
}
public void mouseReleased(MouseEvent event)
{
pt = event.getPoint();
if (pt != null)
{
xEnd = pt.x;
yEnd = pt.y;
page.fillRect(xStart, yStart, xEnd-xStart, yEnd-yStart);
}
}
public void mouseClicked(MouseEvent event) {}
public void mouseEntered(MouseEvent event) {}
public void mouseExited(MouseEvent event) {}
public void mouseDragged(MouseEvent event)
{
pt = event.getPoint();
if (pt != null)
{
xEnd = pt.x;
yEnd = pt.y;
Rect rect = new Rect(xStart, yStart, xEnd-xStart, yEnd-yStart, currentColor);
rect.draw(page);
}
repaint();
}
public void mouseMoved(MouseEvent event) {}
}
ColorListener查找在main()方法中确定的JComboBox中选择的对象类型,并将currentColor设置为它(它在上面的Rect构造函数中作为颜色放回)
所以我现在有麻烦的是能画出来。到目前为止,我在程序中没有发现任何逻辑缺陷,也没有任何东西能够绘制到画布上(不要担心JButtons撤消和擦除,因为它们很容易使用ArrayList、remove()和clear()之类的东西)。您的程序应该没有作为类字段的图形字段(您的页面类字段)。我很惊讶您在上面的鼠标侦听器类中尝试使用NullPointException时没有看到NullPointException:
public void mouseReleased(MouseEvent event)
{
pt = event.getPoint();
if (pt != null)
{
xEnd = pt.x;
yEnd = pt.y;
// !!!! don't do this !!!!
page.fillRect(xStart, yStart, xEnd-xStart, yEnd-yStart);
}
}
相反,图形对象应该只从JVM获取,应该只存在于paintComponent方法中,并且应该只在同一paintComponent方法中使用(例外情况是通过paintComponent调用的任何方法,这些方法传递给该对象,当然还有从BuffereImage获取的图形对象)。MouseListener/MouseMotionListener应在mouseDragged期间填写x-start、y-start、x-end和y-end变量,然后在mouseRelease上使用这些变量创建放置在rectList中的新Rect对象,然后调用重新绘制
然后,paintComponent应该遍历rectList,填充它在那里找到的每个Rect对象。它是我前面声明的一个实例变量,在整个类的构造函数中实例化,也就是WholePanel(我马上添加它)我仍然不明白为什么他们还没有画它们……你是说mousePressed应该得到按压的点,并将x坐标设置为xStart,y坐标设置为yStart,还是MouseDraged应该得到所有的4个点(这两个和xEnd和yEnd)?我只是对逻辑和东西还有什么问题感到困惑
private class ColorListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
if (event.getSource().equals("black"))
{
currentColor = Color.black;
comboBox.setSelectedIndex(0);
}
else if (event.getSource().equals("red"))
{
currentColor = Color.red;
comboBox.setSelectedIndex(1);
}
else if (event.getSource().equals("blue"))
{
currentColor = Color.blue;
comboBox.setSelectedIndex(2);
}
else if (event.getSource().equals("green"))
{
currentColor = Color.green;
comboBox.setSelectedIndex(3);
}
else if (event.getSource().equals("orange"))
{
currentColor = Color.orange;
comboBox.setSelectedIndex(4);
}
}
}
public void mouseReleased(MouseEvent event)
{
pt = event.getPoint();
if (pt != null)
{
xEnd = pt.x;
yEnd = pt.y;
// !!!! don't do this !!!!
page.fillRect(xStart, yStart, xEnd-xStart, yEnd-yStart);
}
}