动态创建 JPanel

Dynamically create JPanels

我正在尝试制作一个具有 JTabbedPane 并显示 RF 网络上无线电之间的连接的 GUI。我无法弄清楚如何使 tabbedPanes 动态创建。我尝试了很多事情都没有成功。这是我到目前为止所拥有的。

这是抽奖class

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;

public class draw extends JPanel implements MouseListener{

    private Color currentColor = Color.RED;

    //Array to hold the grid dimensions used for drawing radio[]
    private int[] gD = {40, 100, 160, 220, 280, 340, 400, 460};

    //Flag for changing colors in the grid
    private boolean colorChanged = false;

    public void drawing() {
        repaint();
    }

    public void paintComponent(final Graphics g) {
        super.paintComponent(g);
        final Graphics2D g2d = (Graphics2D)g;

        //Smooth Graphics
        ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);

        //Quality Color Rendering
        ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_COLOR_RENDERING,
                RenderingHints.VALUE_COLOR_RENDER_QUALITY);

        //Array to hold 40 radios
        final Ellipse2D.Double radio[] = new Ellipse2D.Double[39];

        //Array to hold lines that show radio connections
        final Line2D connection[] = new Line2D[49];

        /****************************************************************
        This section of code draws the Ellipses that represent the
        different radios.
        *****************************************************************/
        radio[0] = new Ellipse2D.Double(gD[2], gD[0], gD[0], gD[0]);
        g2d.setPaint(currentColor);
        g2d.fill(radio[0]);
        this.addMouseListener(this);

        radio[1] = new Ellipse2D.Double(gD[1], gD[1], gD[0], gD[0]);
        g2d.setPaint(currentColor);
        g2d.fill(radio[1]);
        this.addMouseListener(this);

        radio[2] = new Ellipse2D.Double(gD[0], gD[2], gD[0], gD[0]);
        g2d.setPaint(currentColor);
        g2d.fill(radio[2]);
        this.addMouseListener(this);

        radio[3] = new Ellipse2D.Double(gD[1], gD[3], gD[0], gD[0]);
        g2d.setPaint(currentColor);
        g2d.fill(radio[3]);
        this.addMouseListener(this);

        radio[4] = new Ellipse2D.Double(gD[2], gD[4], gD[0], gD[0]);
        g2d.setPaint(currentColor);
        g2d.fill(radio[4]);
        this.addMouseListener(this);

        radio[5] = new Ellipse2D.Double(gD[5], gD[0], gD[0], gD[0]);
        g2d.setPaint(currentColor);
        g2d.fill(radio[5]);
        this.addMouseListener(this);

        radio[6] = new Ellipse2D.Double(gD[6], gD[1], gD[0], gD[0]);
        g2d.setPaint(currentColor);
        g2d.fill(radio[6]);
        this.addMouseListener(this);

        radio[7] = new Ellipse2D.Double(gD[7], gD[2], gD[0], gD[0]);
        g2d.setPaint(currentColor);
        g2d.fill(radio[7]);
        this.addMouseListener(this);

        radio[8] = new Ellipse2D.Double(gD[6], gD[3], gD[0], gD[0]);
        g2d.setPaint(currentColor);
        g2d.fill(radio[8]);
        this.addMouseListener(this);

        radio[9] = new Ellipse2D.Double(gD[5], gD[4], gD[0], gD[0]);
        g2d.setPaint(currentColor);
        g2d.fill(radio[9]);
        this.addMouseListener(this);

        /****************************************************************
         This section of code draws the lines that represent the
         connections to the different radios.
        *****************************************************************/
        connection[0] = new Line2D.Double(radio[0].getCenterX(), radio[0].getCenterY(), radio[9].getCenterX(), radio[9].getCenterY());
        g2d.draw(connection[0]);

        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {

                /**************************************************************************
                 This block of statements changes the radio buttons to green when clicked
                 and sets the colorChanged flag to true.
                 *************************************************************************/
                if (!colorChanged && radio[0].contains(e.getX(), e.getY())) {
                    e.getSource();
                    currentColor = Color.GREEN;
                    colorChanged = true;
                    repaint(gD[2], gD[0], gD[0], gD[0]);
                } else if (!colorChanged && radio[1].contains(e.getX(), e.getY())) {
                    e.getSource();
                    currentColor = Color.GREEN;
                    colorChanged = true;
                    repaint(gD[1], gD[1], gD[0], gD[0]);
                } else if (!colorChanged && radio[2].contains(e.getX(), e.getY())) {
                    e.getSource();
                    currentColor = Color.GREEN;
                    colorChanged = true;
                    repaint(gD[0], gD[2], gD[0], gD[0]);
                } else if (!colorChanged && radio[3].contains(e.getX(), e.getY())) {
                    e.getSource();
                    currentColor = Color.GREEN;
                    colorChanged = true;
                    repaint(gD[1], gD[3], gD[0], gD[0]);
                } else if (!colorChanged && radio[4].contains(e.getX(), e.getY())) {
                    e.getSource();
                    currentColor = Color.GREEN;
                    colorChanged = true;
                    repaint(gD[2], gD[4], gD[0], gD[0]);
                } else if (!colorChanged && radio[5].contains(e.getX(), e.getY())) {
                    e.getSource();
                    currentColor = Color.GREEN;
                    colorChanged = true;
                    repaint(gD[5], gD[0], gD[0], gD[0]);
                } else if (!colorChanged && radio[6].contains(e.getX(), e.getY())) {
                    e.getSource();
                    currentColor = Color.GREEN;
                    colorChanged = true;
                    repaint(gD[6], gD[1], gD[0], gD[0]);
                } else if (!colorChanged && radio[7].contains(e.getX(), e.getY())) {
                    e.getSource();
                    currentColor = Color.GREEN;
                    colorChanged = true;
                    repaint(gD[7], gD[2], gD[0], gD[0]);
                } else if (!colorChanged && radio[8].contains(e.getX(), e.getY())) {
                    e.getSource();
                    currentColor = Color.GREEN;
                    colorChanged = true;
                    repaint(gD[6], gD[3], gD[0], gD[0]);
                } else if (!colorChanged && radio[9].contains(e.getX(), e.getY())) {
                    e.getSource();
                    currentColor = Color.GREEN;
                    colorChanged = true;
                    repaint(gD[5], gD[4], gD[0], gD[0]);

                /***************************************************************************
                 This block of statements changes the radio buttons to red when clicked
                 and sets the colorChanged flag to false
                ***************************************************************************/
                } else if (colorChanged && radio[0].contains(e.getX(), e.getY())) {
                    e.getSource();
                    currentColor = Color.RED;
                    colorChanged = false;
                    repaint(gD[0], gD[0], gD[0], gD[0]);
                } else if (colorChanged && radio[1].contains(e.getX(), e.getY())) {
                    e.getSource();
                    currentColor = Color.RED;
                    colorChanged = false;
                    repaint(gD[0], gD[1], gD[0], gD[0]);
                } else if (colorChanged && radio[2].contains(e.getX(), e.getY())) {
                    e.getSource();
                    currentColor = Color.RED;
                    colorChanged = false;
                    repaint(gD[0], gD[2], gD[0], gD[0]);
                } else if (colorChanged && radio[3].contains(e.getX(), e.getY())) {
                    e.getSource();
                    currentColor = Color.RED;
                    colorChanged = false;
                    repaint(gD[0], gD[3], gD[0], gD[0]);
                } else if (colorChanged && radio[4].contains(e.getX(), e.getY())) {
                    e.getSource();
                    currentColor = Color.RED;
                    colorChanged = false;
                    repaint(gD[0], gD[4], gD[0], gD[0]);
                } else if (colorChanged && radio[5].contains(e.getX(), e.getY())) {
                    e.getSource();
                    currentColor = Color.RED;
                    colorChanged = false;
                    repaint(gD[7], gD[0], gD[0], gD[0]);
                } else if (colorChanged && radio[6].contains(e.getX(), e.getY())) {
                    e.getSource();
                    currentColor = Color.RED;
                    colorChanged = false;
                    repaint(gD[7], gD[1], gD[0], gD[0]);
                } else if (colorChanged && radio[7].contains(e.getX(), e.getY())) {
                    e.getSource();
                    currentColor = Color.RED;
                    colorChanged = false;
                    repaint(gD[7], gD[2], gD[0], gD[0]);
                } else if (colorChanged && radio[8].contains(e.getX(), e.getY())) {
                    e.getSource();
                    currentColor = Color.RED;
                    colorChanged = false;
                    repaint(gD[7], gD[3], gD[0], gD[0]);
                } else if (colorChanged && radio[9].contains(e.getX(), e.getY())) {
                    e.getSource();
                    currentColor = Color.RED;
                    colorChanged = false;
                    repaint(gD[7], gD[4], gD[0], gD[0]);
                }
        }
    });
    }

    @Override
    public void mouseClicked(MouseEvent e) {

    }

    @Override
    public void mousePressed(MouseEvent mouseEvent) {

    }

    @Override
    public void mouseReleased(MouseEvent mouseEvent) {

    }

    @Override
    public void mouseEntered(MouseEvent mouseEvent) {

    }

    @Override
    public void mouseExited(MouseEvent mouseEvent) {

    }
}

这是首页class

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.*;
import javax.swing.JTabbedPane;
import javax.swing.JPanel;
import javax.swing.JFrame;


public class FrontPage extends JFrame{

    private JPanel rootPanel;
    private JButton buttonPushConfiguration;
    private JTabbedPane tabbedPane;

    public FrontPage() {

        this.setBounds(new Rectangle(0, 0, 600, 600));
        setContentPane(rootPanel);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
        draw object = new draw();

        //Creates the first tab
        tabbedPane.addTab("Switch 1", object);

        object.drawing();


        buttonPushConfiguration.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JOptionPane.showMessageDialog(FrontPage.this, "Configuration Pushed to Panel");
            }

        });
    }
}

这是主要的class

import javax.swing.*;

public class Main {
    public static void main(String[] args) {

        //Set the theme to the current system theme.
        try {

            UIManager.setLookAndFeel(
                    UIManager.getSystemLookAndFeelClassName());
        }
        catch(UnsupportedLookAndFeelException e){

            // handle exception
        }
        catch(ClassNotFoundException e){

            // handle exception
        }
        catch(InstantiationException e){

            // handle exception
        }
        catch(IllegalAccessException e){
        }

        //Instantiates FrontPage
        new FrontPage();

    }
}

如果您的目标是在按钮的 ActionListener 中向 JTabbedPane 添加新的 JPanel,那么这正是您需要做的,例如:

  @Override
  public void actionPerformed(ActionEvent e) {
     // int variable for the tab title
     tabIndex++;
     String title = "Switch " + tabIndex; 

     // I renamed your draw class to conform to Java standards
     DrawPanel tabComponent = new DrawPanel();
     tabbedPane.add(title, tabComponent);
  }

如果您需要做更多,请告诉我们。我还必须重申我对你原来的评论 post:

  • 您在绘画方法(这里是 paintComponent)中添加了一个 MouseListener,这是您永远不应该做的事情。当您真的只需要一个时,这可能会向 JPanel 添加许多 MouseListeners,实际上是无法控制的数量。仅在 paint 或 paintComponent 方法中进行绘制,仅此而已。
  • 您上面的代码可以编译,但会在您尝试使用未初始化的组件时从许多位置抛出 NullPointerExceptions。请在 post 到这里之前尝试解决这个问题。
  • 此外,您的 Ellipse2D 和 Line2D 数组应该成为实例字段,而不是局部于 paintComponent 方法。此外,您在 paintComponent 中重新添加了无数次 MouseListener,而不仅仅是一次。
  • 您似乎试图一次解决太多问题,导致错误代码成倍增加。考虑改变你创建这个程序的方式——从简单开始,从第一原则开始,一次单独解决一个小问题,然后才将这些项目放在一个 GUI 中

MouseListener 更改点颜色的示例:

import java.awt.BorderLayout;
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.event.*;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.*;

@SuppressWarnings("serial")
public class DrawPanelMain extends JPanel {  

   private static final int PREF_W = 600;
   private static final int PREF_H = PREF_W;
   private List<Point> POINT_LIST = Arrays.asList(new Point[] {
         new Point(160, 40),
         new Point(100, 100),
         new Point(40, 160),
         new Point(100, 220),
         new Point(160, 280),
         new Point(340, 40),
         new Point(400, 100),
         new Point(460, 160),
         new Point(400, 220),
         new Point(340, 280)
   });
   private JTabbedPane tabbedPane = new JTabbedPane();
   private int tabIndex = 0;

   public DrawPanelMain() {
      JPanel btnPanel = new JPanel();
      btnPanel.add(new JButton(new PushConfigAction("Push Config")));

      setLayout(new BorderLayout());
      add(tabbedPane, BorderLayout.CENTER);
      add(btnPanel, BorderLayout.PAGE_END);
   }

   @Override
   public Dimension getPreferredSize() {
      if (isPreferredSizeSet()) {
         return super.getPreferredSize();
      }
      return new Dimension(PREF_W, PREF_H);
   }

   private class PushConfigAction extends AbstractAction {
      public PushConfigAction(String name) {
         super(name);
         int mnemonic = (int) name.charAt(0);
         putValue(MNEMONIC_KEY, mnemonic);
      }

      @Override
      public void actionPerformed(ActionEvent e) {
         tabIndex++;
         String title = "Switch " + tabIndex;
         DrawPanel2 tabComponent = new DrawPanel2(POINT_LIST);
         tabbedPane.add(title, tabComponent);
      }
   }

   private static void createAndShowGui() {
      DrawPanelMain mainPanel = new DrawPanelMain();

      JFrame frame = new JFrame("DrawPanelMain");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

@SuppressWarnings("serial")
class DrawPanel2 extends JPanel {
   private static final int OVAL_WIDTH = 40;
   private static final Color INACTIVE_COLOR = Color.RED;
   private static final Color ACTIVE_COLOR = Color.green;
   private List<Point> points;
   private List<Ellipse2D> ellipses = new ArrayList<>();
   private Map<Ellipse2D, Color> ellipseColorMap = new HashMap<>();

   public DrawPanel2(List<Point> points) {
      this.points = points;
      for (Point p : points) {
         int x = p.x - OVAL_WIDTH / 2;
         int y = p.y - OVAL_WIDTH / 2;
         int w = OVAL_WIDTH;
         int h = OVAL_WIDTH;
         Ellipse2D ellipse = new Ellipse2D.Double(x, y, w, h);
         ellipses.add(ellipse);
         ellipseColorMap.put(ellipse, INACTIVE_COLOR);
      }

      MyMouseAdapter mListener = new MyMouseAdapter();
      addMouseListener(mListener);
      addMouseMotionListener(mListener);
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2 = (Graphics2D) g;
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
      for (Ellipse2D ellipse : ellipses) {
         g2.setColor(ellipseColorMap.get(ellipse));
         g2.fill(ellipse);
      }
   }

   private class MyMouseAdapter extends MouseAdapter {
      @Override
      public void mousePressed(MouseEvent e) {
         for (Ellipse2D ellipse : ellipses) {
            if (ellipse.contains(e.getPoint())) {
               Color c = ellipseColorMap.get(ellipse);
               c =  (c == INACTIVE_COLOR) ? ACTIVE_COLOR : INACTIVE_COLOR;
               ellipseColorMap.put(ellipse, c);
            }
         }
         repaint();
      }
   }
}