在JPanel的一侧绘制 [英] Draw on one side of a JPanel
问题描述
我想编写一个应用程序,使您可以通过单击JFrame
左侧的鼠标来绘制圆,所有点都在右侧镜像".我遇到的第一个问题是,当我尝试在框架中实现此绘制机制时,没有出现圆.
I want to program an application that lets you draw circles with a mouse click on the left side of a JFrame
, and all the points are getting "mirrored" to the right side. The first problem I encountered was that when I try to implement this draw-mechanic in my frame, no circles appear.
public class Application{
int x,y;
private JPanel container;
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new Application().gui();
}
});
}
public void gui()
{
int height = 250;
int width = 700;
JFrame jframe = new JFrame();
container = new JPanel();
container.setLayout(new BorderLayout());
container.add(new DrawCircle(), BorderLayout.WEST);
container.setVisible(true);
jframe.add(container);
//jframe.add(new DrawCircle());
jframe.setSize(500,700);
jframe.setVisible(true);
jframe.setTitle("Title");
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jframe.setResizable(false);
}
}
当我使用container.add(new DrawCircle)
时,它可以(在整个框架上)起作用,但是如果我想添加约束,则不会.
It works (on the whole frame) when I use container.add(new DrawCircle)
but if I want to add constraints, it doesn't.
这是圈子类别:
public class DrawCircle extends JPanel implements MouseListener
{
ArrayList<Point> p = new ArrayList<Point>();
public DrawCircle()
{
addMouseListener(this);
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
for(Point point : p)
{
g.fillOval(point.x,point.y,30,30);
}
}
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mousePressed(MouseEvent e) {
p.add(new Point(e.getY(), e.getX()));
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseDragged(MouseEvent e) {
}
@Override
public void mouseMoved(MouseEvent arg0) {
}
}
推荐答案
让我们来解决您的问题:
Let's go through your problems:
我遇到的第一个问题是,当我尝试在框架中实现此绘制机制时,没有圆圈出现.
The first problem I encountered was that when I try to implement this draw-mechanic in my frame, no circles appear.
这是因为您忘记调用 JPanel#repaint()
,只要您单击DrawCircle
类中的某个位置即可.
This is because you forgot to call JPanel#revalidate()
and JPanel#repaint()
whenever you click somewhere in the DrawCircle
class.
因此,您可以将mousePressed()
方法更改为:
So, you could change your mousePressed()
method to:
@Override
public void mousePressed(MouseEvent e) {
p.add(new Point(e.getX(), e.getY()));
revalidate();
repaint();
}
请注意,我还更改了e.getX()
和e.getY()
调用,因为它们放置在错误的位置(除非您这样想).
Note that I also changed the e.getX()
and e.getY()
calls, because they were on the wrong places (unless you want them that way).
这将使您的圆圈出现,但是您的DrawCircle
确实很细(我将此图像的JFrame
的高度更改为200,否则它会很高):
That will make your circles to appear, but, your DrawCircle
is really thin (I changed the height of your JFrame
to 200 for this image, otherwise it would be really tall):
红色部分是您的DrawCircle
面板.
要解决此问题,您需要覆盖其getPreferredSize()
方法:
To fix this you need to override its getPreferredSize()
method:
@Override
public Dimension getPreferredSize() {
return new Dimension(width, height);
}
这将使您的JPanel
返回一半大小,width
和height
作为参数传递给构造函数,并且您的类DrawCircle
现在应如下所示:
That will make your JPanel
to return half the size, width
and height
were passed as parameters to the constructor, and your class DrawCircle
should now look like this:
class DrawCircle extends JPanel implements MouseListener {
ArrayList<Point> p = new ArrayList<Point>();
int width = 0;
int height = 0;
public DrawCircle(int width, int height) {
this.width = width;
this.height = height;
addMouseListener(this);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(width, height);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
for (Point point : p) {
g.fillOval(point.x, point.y, 30, 30);
}
}
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mousePressed(MouseEvent e) {
p.add(new Point(e.getX(), e.getY()));
revalidate();
repaint();
}
@Override
public void mouseReleased(MouseEvent e) {
}
}
输出将是这样的:
当我使用container.add(new DrawCircle)时,它可以(在整个框架上)工作
It works (on the whole frame) when I use container.add(new DrawCircle)
这是因为默认情况下BorderLayout
默认情况下会将元素放置在CENTER
区域上,并且如果其余方向(NORTH
,SOUTH
等)没有其他内容,则它将占用整个空间
That's because by default BorderLayout
places by default the elements on the CENTER
region, and if you have nothing else in the rest of orientations (NORTH
, SOUTH
, etc) it will take the whole space.
现在让我们继续解决问题:
Now let's continue with how to solve your problem:
我还对Application
类进行了一些更改(在我的情况下,我将其重命名为CustomPaintingInHalfFrame
):
I also made some changes to the Application
class (which in my case I renamed to CustomPaintingInHalfFrame
):
这些更改是:
- 为
WIDTH
和HEIGHT
属性创建最终常量. - 使用
BorderLayout
布局删除不必要的JPanel
,因为默认情况下JFrame
已经具有此布局,所以我只是在其中添加了DrawClass
. - 为
DrawCircle
面板绘制边框(因为您不希望在https://stackoverflow中声明 JFrame
的两个部分(左右)之间进行分隔. com/questions/41685700/two-jpanels-in-one-jframe>上一个问题,您只需将其删除即可(我建议您在测试时将其保留在此处,以便知道左侧面板的右端和右侧)面板开始. - 将
WIDTH / 2
和HEIGHT
作为DrawCircle
构造函数的参数传递,因此它可以返回正确的Dimension
.
- Create final constants for the
WIDTH
andHEIGHT
attributes. - Removal of unnecessary
JPanel
withBorderLayout
layout, asJFrame
already has this layout by default, I simply added ourDrawClass
to it. - Drawing of a border for the
DrawCircle
panel (as you don't want a division between both (left and right) parts of yourJFrame
as stated in your previous question you can simply remove it (I recommend you to leave it there while you're testing so you know where left panel ends and right panel starts. - Passing
WIDTH / 2
andHEIGHT
as parameters forDrawCircle
constructor, so it can return the correctDimension
.
因此,我们的类现在应如下所示:
So, our class should now look like this:
public class CustomPaintingInHalfFrame {
int x, y;
public static final int WIDTH = 500;
public static final int HEIGHT = 200;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new CustomPaintingInHalfFrame().gui();
}
});
}
@SuppressWarnings("serial")
public void gui() {
JFrame jframe = new JFrame("Title");
DrawCircle dc = new DrawCircle(WIDTH / 2, HEIGHT);
dc.setBorder(BorderFactory.createLineBorder(Color.RED));
jframe.add(dc, BorderLayout.WEST);
jframe.setSize(WIDTH, HEIGHT);
jframe.setVisible(true);
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jframe.setResizable(false);
}
}
其他提示
-
我建议您将
DrawCircle
重命名为Circle
或类似的名称.作为常规,类名称应是名词
I recommend you to rename your
DrawCircle
toCircle
or something like that. As a convention, Classes names should be nouns
将gui()
方法重命名为createGui()
,例如,因为作为类名,方法名称应为动词
Rename gui()
method to createGui()
for example because, as Classes names, method names should be verbs
这篇关于在JPanel的一侧绘制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!