【问题标题】:Problems in mixing two JPanels in 1 JFrame在 1 个 JFrame 中混合两个 JPanel 的问题
【发布时间】:2014-08-21 20:42:38
【问题描述】:

我在一帧中混合了两个JPanels,它给了我这个输出!

这是我添加两个 JPanel 的代码:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.*;
import java.util.*;

public class Board extends JFrame{
private int width=500;
private int height=450;

Obstacles asd= new Obstacles();

Human human;    
private Dimension mindim= new Dimension(width+10,height+10);

Board(){
    human = new Human();
    this.setTitle("Athwart");
    //setLayout(null);
    human.add(asd);     //!!!we see here, I add asd (which is inherited from a JPanel)     
                        //  to another existing JPanel
    this.setMinimumSize(mindim); //
    this.getContentPane().setLayout(new BorderLayout());
    this.getContentPane().add(human); 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //
    this.setLocationRelativeTo(null); //
    this.setResizable(true); //
    pack(); //
    setVisible(true);
    human.requestFocus(); //
    }
}

这就是我的Obstacles 类的样子。

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

public class Obstacles extends JPanel {

private int width=500;
private int height=450;  
private Dimension mindim= new Dimension(width+10,height+10);
    Obstacles()
    {
        this.setBackground(Color.white);
       // this.addKeyListener(this);
       // this.setFocusable(true);
       // this.setRequestFocusEnabled(true);
        setSize(mindim);
        this.setVisible(true);
    }
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g); //
        g.fillRect(0, 0, 60, 30);
        g.setColor(Color.black);
        g.draw3DRect(0, 0, 60, 30, true);
        g.setColor(Color.black);
    }
 }

所以你可以看到组件的高度是 30,宽度是 60,但上面的图片甚至没有显示一半!

有什么办法可以让这两个JPanels 混合在一起吗?顺便一提, 我之前尝试过使用BoxLayout,但没有成功。有什么问题还是只是我的 IDE 无法正常工作?干杯并感谢您的精彩回复。我只是一个入门的 gui 程序员,我真的不知道如何处理事情。是的,如果您要询问完整的代码,我会编辑它,如果它重要的话。 :)

【问题讨论】:

  • 你真的认为问题可能出在你的 IDE 上吗?
  • 无法通过屏幕截图告诉您您要做什么。你想把它们并排放置吗?上下?
  • @usar,是的,这引起了我的注意,但这只是分散注意力,因为我确信(或者我当然希望)原始海报是在开玩笑,并且知道错误的可能性在 IDE 中与在他的代码中的对比非常低,接近 1 到 1000000。更重要的是,原始帖子没有包含足够的代码让我们看到正在发生的事情。我的猜测是您正在尝试绘制两个图像,然后不应该使用两个 JPanel,而应该使用一个 JPanel 包含两个逻辑对象,帮助指导它绘制两个图像。
  • 你的期望实际上是什么,因为我觉得它看起来不错......
  • 更多细节:你想达到什么目的?人类做什么? Human 类是什么样的?您是否尝试向单个 JPanel 添加多个障碍? 你想做什么?

标签: java swing jpanel paintcomponent


【解决方案1】:

最后,你提出一个要求:

我只是想将一个矩形图像与另一个圆形图像的 Jpanel 放在一个 jframe 内。看看我在不重叠的情况下将两个 Jpanel 混合在一起是否会走那么远。

是的,这可以做到,比如通过使用 JLayeredPane,您可以将一个 JPanel 叠加在另一个上,但您需要确保上面的 JPanel 不是不透明的 (setOpaque(false))。

但话虽如此,我仍然坚持我的评论,你看起来是在做错事。您不应该创建一个 JPanel 来绘制 一个东西 并尝试组合多个 JPanel,因为这可能会导致一团糟。相反,您应该考虑创建一个绘图 JPanel,并给它逻辑对象,比如非 GUI 障碍对象,将它们放在一个集合中,例如 ArrayList,然后在绘图 JPanel 中,遍历绘图 JPanel 的 paintComponent 方法中的所有障碍,按照它的指示绘制每个障碍物。


编辑
例如:

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.util.ArrayList;
import java.util.List;

import javax.swing.*;

public class ObstacleDrawer extends JPanel {
   private static final int PREF_W = 800;
   private static final int PREF_H = PREF_W;
   private List<Obstacle> obstacleList = new ArrayList<>();

   public ObstacleDrawer() {

   }

   public void addObstacle(Obstacle obstacle) {
      obstacleList.add(obstacle);
   }

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

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2 = (Graphics2D) g;
      // smooth out the drawing
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);

      // iterate through the obstacle list, drawing each obstacle
      for (Obstacle obstacle : obstacleList) {
         obstacle.draw(g2);
      }
   }

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

      mainPanel.addObstacle(new CircleObstacle(new Point(200, 200), 100, Color.red));
      mainPanel.addObstacle(new CircleObstacle(new Point(400, 300), 150, Color.blue));

      JFrame frame = new JFrame("ObstacleDrawer");
      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();
         }
      });
   }
}

interface Obstacle {
   public Point getCenter();
   public void setCenter(Point center);
   public int getWidth();
   public void setWidth(int width);
   public Color getColor();
   public void setColor(Color color);
   public void draw(Graphics2D g2);
}

class CircleObstacle implements Obstacle {
   private Point center;
   private int width;
   private Color color;

   public CircleObstacle(Point center, int width, Color color) {
      this.center = center;
      this.width = width;
      this.color = color;
   }

   @Override
   public Point getCenter() {
      return center;
   }

   @Override
   public void setCenter(Point center) {
      this.center = center;
   }

   @Override
   public int getWidth() {
      return width;
   }

   @Override
   public void setWidth(int width) {
      this.width = width;
   }

   @Override
   public Color getColor() {
      return color;
   }

   @Override
   public void setColor(Color color) {
      this.color = color;
   }

   @Override
   public void draw(Graphics2D g2) {
      Color oldColor = g2.getColor();
      g2.setColor(color);
      int x = center.x - width / 2;
      int y = center.y - width / 2;
      int height = width;
      g2.fillOval(x, y, width, height);
      g2.setColor(oldColor);
   }
}

【讨论】:

  • @Hovercraft Full Of Eels 谢谢你又一次有趣的课程!
【解决方案2】:

当您想要混合 JPanel 时,最好的方法是将它们嵌套在另一个 JPanel 中。对于嵌套,最好的布局(根据我的经验)是 BoxLayout 和 GridLayout。下面的示例尝试在您的 JFrame 中复制绘图。

JPanel outsidePanel = new JPanel();
Obstacle obstacle1 = new Obstacle();
Human human1 = new Human();

outsidePanel.setLayout(new BoxLayout(BoxLayout.Y_AXIS));
outsidePanel.add(human1);
outsidePanel.add(obstacle1);

此外,我建议您在 JFrame 中实际使用 BorderLayout,然后将此 Panel 添加到 BorderLayout 的 CENTER 位置。按照你的例子:

this.setLayout(new BorderLayout());
this.add(outsidePanel(), BorderLayout.CENTER);

通常这会给你最好的结果。 BoxLayout 文档 (http://docs.oracle.com/javase/7/docs/api/javax/swing/BoxLayout.html) 中有关嵌套面板的更多信息。希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-12
    • 2014-06-04
    • 2011-06-29
    • 2012-06-13
    • 2014-10-28
    相关资源
    最近更新 更多