在JFrame中,将一个JPanel放在另一个JPanel上无法显示。

4

你好,我是一名业余爱好者,想通过编写一个射箭记分卡来学习/提高对Java的理解。我正在尝试制作一个GUI,到目前为止已经成功地在JPanel上生成了一行18个标签,这些标签大小和颜色各异,适合用于计分。

然后,我尝试将其中的五个'标签面板'添加到另一个面板中,以建立一个网格,并避免创建和添加多达150个标签。但是原始标签面板仍未显示出来。所有面板都显示在JFrame上。

我尝试了许多不同的方法来使代码工作,使用Java教程和在互联网上搜索,并研究了本站上类似的问题,但我一直在打转。我肯定错过了某些东西,希望你能帮忙。

我正在使用Java 6和JGrasp v1.8.8_01作为IDE。

以下是标签面板的代码,因为其中许多内容是重复的,所以进行了简化。

import javax.swing.*;  
import java.awt.*;  
public class ArrowScoreLabels extends JPanel{
  public  JPanel createContentPane(){
    JPanel panelForLabels = new JPanel();
    panelForLabels.setLayout(null);
//Code creates 18 labels, sets the size, position, background colours, border and    
//font and adds the labels to the’panelForLabels
    JLabel scorelabel1;
     scorelabel1 = new JLabel("",JLabel.CENTER);
     scorelabel1.setBorder(BorderFactory.createLineBorder(Color.black)); 
     scorelabel1.setFont(new Font("Arial", Font.ITALIC, 26));  
     scorelabel1.setLocation(0, 0);//first value differs for each label
     scorelabel1.setSize(35, 35);
     scorelabel1.setOpaque(true);

        panelForLabels.add(scorelabel1);
        panelForLabels.setOpaque(true);
    return panelForLabels;
  }
}  

运行以下类会在面板上显示18个标签。
import javax.swing.*;
import java.awt.*; 
public class TestArrowScoreLabels {

  private static void createAndShowArrowLabels() {
 //Create and set up the window.
  JFrame frame = new JFrame("To score one dozen");
 //Create and set up the content pane.
  ArrowScoreLabels asl = new ArrowScoreLabels();
  frame.setContentPane(asl.createContentPane()); 
  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
  frame.setSize(676, 73);
  frame.setVisible(true);
  }
//Main method to show the GUI/
  public static void main(String[] args) {
    SwingUtilities.invokeLater(
     new Runnable() {
      public void run() {
      createAndShowArrowLabels();
      }
    });
  }
}

第二个面板的代码类似,可以编译,但只显示第二个绿色的JPanel,而不是带有标签的面板。
import javax.swing.*;
import java.awt.*;


public class FiveDozenScorePanel{
 public JPanel createContentPane(){
  //A bottom JPanel on which to place five dozenpanels.
  JPanel fivedozenpanel = new JPanel();
  fivedozenpanel.setLayout(null); //requires absolute spacing
  fivedozenpanel.setSize(676,185);  
  fivedozenpanel.setBackground(Color.green);
  //Label panels for five dozen
  ArrowScoreLabels dozenscorepanel1, dozenscorepanel2,
         dozenscorepanel3,dozenscorepanel4,dozenscorepanel5;   
  //Create the 5 dozenscorelabels.
  dozenscorepanel1 = new ArrowScoreLabels();         
  dozenscorepanel1.setLocation(5,5);//y value changes for each panel

  fivedozenpanel.add(dozenscorepanel1);//plus the other 4
  fivedozenpanel.setOpaque(true);
  return fivedozenpanel;
}

private static void createAndShowDozenPanels() {
 JFrame frame = new JFrame("To score five dozen");
  FiveDozenScorePanel fdsp = new FiveDozenScorePanel();
  frame.setContentPane(fdsp.createContentPane());   
  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
  //Display the window  
  frame.setSize(700, 233);
  frame.setVisible(true);
 }   

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

我也尝试过frame.getContentPane().add(fdsp); - frame.pack();并阅读了很多关于绘制方法的内容,但我完全感到困惑。我可以让ArrowScoreLabels图片直接显示在JFrame上而不是JPanel上,但只能显示其中一个,而不是五个。
我希望能指出正确的方向。谢谢你的时间。
更新-2010年12月14日 我已经成功地在JFrame的另一个JPanel上显示了panelForLabels Jpanel。这是通过将以下代码添加到ArrowScoreLabels类中完成的。原始的createContentPane()方法被重命名为createRowOne()。panelForLabels被涂成红色,fivedozen面板被涂成黄色以确定哪个正在显示。然而,尽管进行了大量的实验和研究,我仍然只能让程序显示一行标签。
public  static JPanel createContentPane(){
   //Bottom panelto hold rows of labels
     JPanel fivedozenscorepanel = new JPanel();      
     fivedozenscorepanel.setLayout(null);//requires absolute spacing
     fivedozenscorepanel.setSize(660,180);
     fivedozenscorepanel.setBackground(Color.yellow);
     fivedozenscorepanel.add(createRowOne());

     fivedozenscorepanel.setOpaque(true);
     return fivedozenscorepanel;
  }

我展示5行18个标签的唯一方法是在ArrowScoreLabels类中创建所有90个标签,然后使用绝对间距将它们添加到一个JPanel中,最后添加到JFrame中。

我已经注意到了pstanton的建议 - 谢谢您的建议 - 我正在研究使用MigLayout管理器。


1
你在面板或标签上调用 setVisible(true); 吗? - user489041
不,我一直在调用setOpaque(true); - Stuart
在标签和面板上调用setVisible(true)似乎没有任何区别。 - Stuart
2个回答

4
简单的答案是:使用布局管理器。不要使用绝对定位。只需注释掉所有的setLocation和setLayout调用,Swing将使用默认的FlowLayout。为了更好地控制显示,请使用不同的布局管理器。此外,如果您使用多个面板,则会遇到在不同面板中对齐事物的问题,除非它们包含完全相同大小的组件的相同数量,因此请考虑为所有标签使用一个面板。您可以使用MigLayout实现几乎任何所需的布局。
编辑:在您的示例中,没有必要让ArrowScoreLabels扩展JPanel,因为您正在createContentPane中进行工作以构造单独的JPanel。在代码的后面,您调用new ArrowScoreLabels(),这将只返回一个空白的JPanel,而不是您需要调用new ArrowScoreLabels().createContentPane()。
如果你想让 ArrowScoreLabels 扩展 JPanel,那么就要实现 public ArrowScoreLabels() 即构造函数,而不是 createContentPane

我已将标签面板的布局更改为GridLayout(1,18),尽管它们都是相同的大小,但仍会产生18个标签,这是我希望避免的。将fivedozenpanel设置为GridLayout(5,1)会导致白色框架而不是绿色面板。我将面板设置为绿色以查看是否已绘制。 - Stuart
可能与标签面板不在事件分派线程有关吗? - Stuart
不,我认为你现在不需要担心EDT。请看我的编辑^ - pstanton
感谢提供 MigLayout 的链接,我会跟进的。 - Stuart
请看以下链接...我认为您混淆了如何调用 ArrowScoreLabels - pstanton
显示剩余2条评论

0

我有这样的印象,你没有为你的dozenscorepanel1设置大小。所以,请设置一个大小 :-)

小心使用空布局,因为它很麻烦;你总是会忘记一些东西。编写自己的布局或使用现有的布局。


我已经为五十多个记分板设置了大小,但输出没有任何区别。 - Stuart
如果我将标签面板布局重置为null并将fivedozenpanel布局设置为null,调整dozenpanels的大小并设置位置,则输出是一个绿色面板,其上有对应于标签面板位置的白色条纹,尽管由于某种原因第一个标签面板不在一条直线上。 - Stuart

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接