有没有办法从同一个类中的另一个方法在JPanel上绘制形状?

时间:2014-07-25 20:14:54

标签: java swing

我正在开发一个GUI,在其中我在不同位置重复绘制一些2D形状。目前我有一个创建基本布局和面板的方法createGUI(),然后我调用content_panel的构造函数在content_panel中创建2D形状。

但是,我想使用另一种方法在主JPanel中创建形状。在Java中有没有办法,所以我可以在main中有两个方法调用。第一种方法createGUI()创建GUI,包括JFrames和JPanel。而第二种方法createShapes()在一个特定的JPanel - content_panel中创建形状。我想重复调用这个createShapes()方法并传递不同的参数来查看不同位置的形状。

如果您需要更多信息或问题不清楚,请告诉我。感谢

代码:

import java.awt.*;
import java.util.*;
import javax.swing.*;

public class Board{

public static void main(String[] args)
{
    createGUI();
    drawShapes();
}

//This method creates the basic GUI 
private static void createGUI()
{
    //Creating the JFrame main window
    JFrame mainFrame = new JFrame();
    mainFrame.setSize(800, 500);
    mainFrame.setTitle("Particle Filter");
    mainFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    mainFrame.setLocation(100, 100);
    mainFrame.getContentPane().setLayout(new BoxLayout(mainFrame.getContentPane(), BoxLayout.X_AXIS));

    //creates two panels content and sidebar. Sidebar has null layout       
    JPanel content = new JPanel();
    content.setPreferredSize(new Dimension(700,500));
    content.setBackground(Color.LIGHT_GRAY);
    mainFrame.getContentPane().add(content);
    JPanel sidebar = new JPanel();
    sidebar.setBackground(Color.LIGHT_GRAY);
    sidebar.setPreferredSize(new Dimension(100,500));
    mainFrame.getContentPane().add(sidebar);
    sidebar.setLayout(null);

    //creates three buttons in sidebar
    JButton start_button = new JButton("START");
    start_button.setBounds(10, 75, 77, 23);
    sidebar.add(start_button);
    JButton stop_button = new JButton("STOP");
    stop_button.setBounds(10, 109, 77, 23);
    sidebar.add(stop_button);
    JButton reset_button = new JButton("RESET");
    reset_button.setBounds(10, 381, 77, 23);
    sidebar.add(reset_button);

    //calls the content_Walls class and sends the number of ovals to be generated
    int n=1000; // n denotes the number of ovals
    content.add( new Content_Walls(n));
    mainFrame.setVisible(true);

}

private static void drawShapes()
{

}

}
    class Content_Walls extends JPanel
    {


    ArrayList<Integer> list;

    Content_Walls(int n)
    {
        setPreferredSize(new Dimension(680,450));
        setBackground(Color.WHITE);
        list = new ArrayList<Integer>(Collections.nCopies(n, 0));
    }       

    public void paintComponent(Graphics g)
    {
        int x=0,y=0;
        super.paintComponent(g);

        createObstacles(g,150,225,100,40);
        createObstacles(g,500,300,40,100);

        for(int i=0;i<list.size();i++)
        {
            x=randomInteger(11,670); // bounds of x between which the particles should be generated 
            y=randomInteger(11,440); // bounds of y between which the particles should be generated 

            int radius = 4;

            x=x-(radius/2);
            y=y-(radius/2);
            g.fillOval(x, y, radius, radius);
        }

    private void createObstacles(Graphics g, int x, int y, int width, int height)
    {
        g.setColor(Color.BLACK);
        g.fillRect(x, y, width, height);
    }


    private static int randomInteger(int min, int max)
    {
        Random rand = new Random();
        int randomNum = rand.nextInt((max - min) + 1) + min;
        return randomNum;
    }
}

3 个答案:

答案 0 :(得分:1)

您的代码存在各种问题。

  1. 您在主线程上创建Swing组件而不是Event Dispatch Thread。寻求帮助。

  2. 拥有Board子类JFrame并在构造函数或实例方法中进行GUI初始化,而不是静态方法。

  3. 使drawShapes()成为实例方法。

  4. 创建JPanel时,将其引用存储在实例变量中(例如myPanel)。如果您修复#2,这将更容易做,并且不会太麻烦。

  5. 如果您执行#2和#3,只需将引用传递给drawShapes()方法。

  6. 如果所有逻辑都在drawShapes()方法中,则可能甚至不需要
  7. paintComponent()。致电myPanel.repaint()以调用paintComponent()方法。

答案 1 :(得分:0)

您应该使用事件分派让不同的JPanels组件对事件进行操作。

e.g。您可以使用事件类型和jpanel id附加自定义事件;然后从主要发射事件。听取事件的小组根据逻辑做了一些事情。

每个监听事件的JPanel都会拦截事件,如果事件中的jpanelid与自己的jpanel id匹配,它将绘制形状。

我希望你能得到指针。

这是一个示例代码,我还没有测试过,但它显示了如何使用事件调度/侦听来在GUI组件之间进行通信。

定义ChangeEventListener接口

public interface ChangeEventListener {
    public void stateChanged(ChangeEvent e);
}

定义一个事件

public class ChangeEvent {

    private Object source;
    private int jPanelId;

    public ChangeEvent(Object source, int jPanelId) {
        this.source = source;
        this.jPanelId= jPanelId;
    }

    public Object getSource() {
        return source;
    }

    public int getJPanelId() {
        return jPanelId;
    }

}

将面板定义为

public class ShapePanel extends JPanel {

private int jPanelId;

private ChangeEventListener changeEventListener;

public void ShapePanel(int jPanelId){
this.jPanelId = jPanelId;
}

/*
.............
.............. Other code
.................
*/

public void addChangeEventListener(ChangeEventListener changeEventListener) {
        this.changeEventListener = changeEventListener;
    }

public int getJPanelId(){
   return jPanelId;
 }

public getChangeEventListener(){
   return changeEventListener;
 }
}

你的主要应该包含类似的内容;

// Craete different Jpanel
JPanel squareShapePanel = new ShapePanel(1);
JPanel roundShapePanel = new ShapePanel(2);
JPanel triangleShapePanel = new ShapePanel(3);

// Attach event listener with each one like
squareShapePanel.addChangeEventListener(new ChangeEventListener() {
    @Override
    public void stateChanged(ChangeEvent e) {
      if(e.getJPanelId() == squareShapePanel.getJPanelId()){
      // Createshape method can be available inside JPanel code
      // something like squareShapePanel.craeteShape();
      // All in one it is a method which could do something for you on the event.
      // Assuming that it is available in current class
      createShape("square");
    }
});

/*
Similarly attach eventlistener with each panels.
*/
// to draw the square shape, Fire change event
ChangeEvent event = new ChangeEvent(new String("Main"),1);

squareShapePanel.getChangeEventListener().stateChanged(event);

希望这有帮助。

答案 2 :(得分:0)

查看Custom Painting Approaches了解自定义绘画的两种常用方法:

  1. 将要绘制的形状保留在列表中,然后仅绘制列表中的所有形状
  2. 使用BufferedImage,只需将Shapes绘制到BufferedImage上。
  3. 这两个示例都包含一个addRectangle(...)方法,允许您动态添加要绘制的矩形。