按下 JButton 时 JFrame 不添加组件
我的代码基本上是关于有一个框架和一个按钮.您按下按钮可以绘制矩形,通过鼠标按下和鼠标释放获取坐标.
My code is basically about having a frame and it has a button. You press the button you can draw rectangles, getting coordinates from the mouse press and the mouse release.
现在,如果您移除按钮,代码可以完美运行,代码如下.
Now, if you remove the button the code works perfectly, here is the code.
//测试文件
package ActionTest;
import java.awt.*;
import javax.swing.*;
public class MouseTest
{
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
JFrame frame = new MouseFrame();
frame.setTitle("MouseTest");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setSize(500,500);
}
});
}
}
我的框架,调用鼠标组件
My frame, calls on the mouse component
package ActionTest;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class MouseFrame extends JFrame
{
public MouseFrame()
{
add(new MouseComponent());
}
}
组件类:处理鼠标点击和绘制矩形
The component class: handles mouse clicks and drawing the rectangle
package ActionTest;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.*;
import javax.swing.*;
public class MouseComponent extends JComponent
{
Point first;
Point second;
private ArrayList<Rectangle2D> rectangles;
public MouseComponent()
{
rectangles = new ArrayList<>();//contains rectangles
addMouseListener(new MouseHandler());
}
//paint method of the component, simply re-paint the array
public void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
for (Rectangle2D r : rectangles)
g2.draw(r);
}
/**
* creates a rectangle and adds it to the rectangles ArrayList
* then repaint the component
* inside some operations to deal with rectangle drawing nothing to do with the issue
* @param p1: first coordinates
* @param p2: second coordinates
*/
public void addRec(Point2D p1, Point2D p2)
{
double w, h, x, y;
double x1 = p1.getX();
double y1 = p1.getY();
double x2 = p2.getX();
double y2 = p2.getY();
if(x1 <= x2){
x = x1;
w = x2-x1;
}
else{
x = x2;
w = x1-x2;
}
if (y1 <= y2){
y = y1;
h = y2-y1;
}
else{
y = y2;
h = y1-y2;
}
rectangles.add(new Rectangle2D.Double(x, y, w, h));
repaint();
}
//records mouse click and mose release
//you press the mouse that is the 1st coordinates
//you release it that is the 2nd coordinates
//pass both to the addRec method
private class MouseHandler extends MouseAdapter
{
@Override
public void mousePressed(MouseEvent event)
{
first = event.getPoint();
}
@Override
public void mouseReleased(MouseEvent event)
{
second = event.getPoint();
addRec(first, second);
}
}
}
完美运行.但是,回到最初的问题,如果我添加一个按钮,然后当按下按钮时继续并开始绘制矩形,它就不起作用了.
It works perfectly. However, going back to the original problem, if I add a button, and then when the button pressed go ahead and begin drawing rectangles it doesn't work.
这是修改后的框架类
package ActionTest;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class MouseFrame extends JFrame
{
private JPanel buttonPanel;
public MouseFrame()
{
JFrame frame = this;
buttonPanel = new JPanel();
JButton rec = new JButton("Rectangle");
rec.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent event)
{
System.out.println("pressed");
frame.add(new MouseComponent());
}});
buttonPanel.add(rec);
add(buttonPanel);
}
}
提前致谢.
推荐答案
frame.add(new MouseComponent());
新创建的组件的大小为 (0, 0),因此没有可绘制的内容.因此,当您将组件添加到可见 GUI 时,您需要调用布局管理器.
The size of a newly created component is (0, 0) so there is nothing to paint. So you need to invoke the layout manager when you add a component to a visible GUI.
frame.add(new MouseComponent());
frame.revalidate();
frame.repaint();
请注意,这仅在布局管理器允许您将多个组件添加到框架时才有效.框架的默认布局管理器是 BorderLayout,并且只能将单个组件添加到 BorderLayout 的 CENTER.
Note this will only work if the layout manager allows you to add multiple components to the frame. The default layout manager for a frame is the BorderLayout and only a single components can be added to the CENTER of the BorderLayout.
所以也许您需要使用以下方式添加按钮:
So maybe you need to add the button using:
frame.add(button, BorderLayout.PAGE_START);
阅读 Swing 教程中关于 如何使用布局管理器 了解更多信息和工作示例.
Read the section from the Swing tutorial on How to Use Layout Managers for more information and working examples.
此外,任何时候您进行自定义绘制都需要覆盖自定义组件的 getPreferredSize()
方法,以便布局管理器可以完成他们的工作.
Also, any time you do custom painting you need to override the getPreferredSize()
method of the custom component so the layout managers can do their job.
相关文章