首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将JPanel添加到JFrame

将JPanel添加到JFrame
EN

Code Review用户
提问于 2015-01-26 02:08:59
回答 2查看 14.5K关注 0票数 11

我刚刚完成了一项相当简单的作业。基本上,我所要做的就是添加六个JPanels,这只是文本框,颜色名称作为文本。然而,字体的颜色必须与文字相匹配,例如,黑色必须是黑色,蓝色必须是蓝色等等。它的工作原理是找到,但似乎我可以把这段代码缩短一点。

代码语言:javascript
复制
import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.border.*;


public class SixLabels extends JFrame
{
    public SixLabels()
    {
        // sets layout of square
        setLayout(new GridLayout(2,3));

        //set JLabel properties such as border, text, font, etc.
        Border line =  new LineBorder(Color.yellow, 4);
        Font TNR = new Font("Times New Roman", Font.BOLD, 20);
        JLabel black = new JLabel("Black", JLabel.CENTER);
        JLabel blue = new JLabel("Blue", JLabel.CENTER);
        JLabel cyan = new JLabel("Cyan", JLabel.CENTER);
        JLabel green = new JLabel("Green", JLabel.CENTER);
        JLabel magenta = new JLabel("Magenta", JLabel.CENTER);
        JLabel orange = new JLabel("Orange", JLabel.CENTER);

        // add set properties and add panel to JFrame
        black.setOpaque(true);
        black.setForeground(Color.black);
        black.setBackground(Color.white);
        black.setBorder(line);
        black.setFont(TNR);
        black.setToolTipText("This is Black");
        add(black);

        // add set properties and add panel to JFrame
        blue.setOpaque(true);
        blue.setForeground(Color.blue);
        blue.setBackground(Color.white);
        blue.setBorder(line);
        blue.setFont(TNR);
        blue.setToolTipText("This is Blue");
        add(blue);

        // add set properties and add panel to JFrame
        cyan.setOpaque(true);
        cyan.setForeground(Color.cyan);
        cyan.setBackground(Color.white);
        cyan.setBorder(line);
        cyan.setFont(TNR);
        cyan.setToolTipText("This is Cyan");
        add(cyan);

        // add set properties and add panel to JFrame
        green.setOpaque(true);
        green.setForeground(Color.green);
        green.setBackground(Color.white);
        green.setBorder(line);
        green.setFont(TNR);
        green.setToolTipText("This is Green");
        add(green);

        // add set properties and add panel to JFrame
        magenta.setOpaque(true);
        magenta.setForeground(Color.magenta);
        magenta.setBackground(Color.white);
        magenta.setBorder(line);
        magenta.setFont(TNR);
        magenta.setToolTipText("This is Magenta");
        add(magenta);

        // add set properties and add panel to JFrame
        orange.setOpaque(true);
        orange.setForeground(Color.orange);
        orange.setBackground(Color.white);
        orange.setBorder(line);
        orange.setFont(TNR);
        orange.setToolTipText("This is Orange");
        add(orange);





    }


    public static void main(String[] args) 
    {
        SixLabels frame = new SixLabels(); // creates frame
        frame.setTitle("Chapter 12 Exercise 12.8"); // sets name on title bar
        frame.setSize(600, 400); // sets size of GUI frame
        frame.setLocationRelativeTo(null); // Centers GUI frame
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Stop/Close program on exit 
        frame.setVisible(true); // Shows the frame, must be true

    }

}
EN

回答 2

Code Review用户

发布于 2015-01-26 02:09:37

我建议:

  • 你用的是GridLayout(2, 3) --很好。
  • 我会把它变成一个GridLayout(2, 0, GAP, GAP),其中GAP是一个常数,允许JLabels之间的间隙。第一个和第二个参数表示有可变列数的2行。
  • 然后,如果您将JPanel的背景色设置为黄色,将JLabels设置为不透明和白色,则给背景JPanel一个空白的空白边框,这样就得到了您的黄色边框
  • 使用枚举将颜色与字符串组合起来。一个替代方案可以是使用Map<String, Color>
  • 枚举方法values()将返回该枚举的所有项的数组。如果使用地图(如HashMap ),您将得到密钥集并遍历该键集。
  • 然后,您可以使用一个简单的for循环来遍历这个数组,创建具有所需文本和所需前景色的JLabels。
  • 在需要更多灵活性的情况下,让类扩展JFrame,迫使您创建和显示JFrames,就有可能将自己画在角落里。事实上,我敢打赌,我创建的大多数Swing GUI代码以及我所见过的大多数Swing GUI代码都没有扩展JFrame,而且实际上您很少会想要这样做。更常见的情况是,您的GUI类将面向创建JPanels,然后可以将其放置到JFrames或JDialogs或JTabbedPanes中,或者在需要时通过CardLayouts进行交换。这可以极大地提高GUI编码的灵活性。

例如,

代码语言:javascript
复制
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import javax.swing.*;

@SuppressWarnings("serial")
public class SixLabels2 extends JPanel {
   private static final int GAP = 8;
   private static final int LABEL_WIDTH = 160;
   private static final Dimension LABEL_SIZE = new Dimension(LABEL_WIDTH, LABEL_WIDTH);
   private static final int ROWS = 2;
   private static final Font LABEL_FONT = new Font("Times New Roman", Font.BOLD, 20);

   public SixLabels2() {
      setBackground(Color.yellow);
      setLayout(new GridLayout(ROWS, 0, GAP, GAP)); 
      setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));

      // iterate through all the items in the MyColor enum
      for (MyColor myColor : MyColor.values()) {
         JLabel label = new JLabel(myColor.getText(), SwingConstants.CENTER);
         label.setForeground(myColor.getColor());
         label.setPreferredSize(LABEL_SIZE);
         label.setFont(LABEL_FONT);
         label.setOpaque(true);
         label.setBackground(Color.white);
         add(label);
      }
   }

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

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

enum MyColor {
   BLACK("Black", Color.black), BLUE("Blue", Color.blue), 
   CYAN("Cyan", Color.cyan), GREEN("Green", Color.green), 
   MAGENTA("Magenta", Color.magenta), ORANGE("Orange", Color.orange);

   private String text;
   private Color color;

   private MyColor(String text, Color color) {
      this.text = text;
      this.color = color;
   }

   public String getText() {
      return text;
   }

   public Color getColor() {
      return color;
   }

   @Override
   public String toString() {
      return text;
   }

}

请注意,我的代码的长度可能不会更短,但我敢打赌,调试和增强会更容易。考虑在代码和我的代码中再添加几个颜色,看看需要在这两个变量和语句中更改多少个变量和语句。例如,如果您想要给我添加两种颜色,那么您所需要做的就是将枚举更改为包含另外两种颜色。节目会帮你处理剩下的事。

例如,如果您从以下内容中更改枚举:

代码语言:javascript
复制
enum MyColor {
   BLACK("Black", Color.black), BLUE("Blue", Color.blue), 
   CYAN("Cyan", Color.cyan), GREEN("Green", Color.green), 
   MAGENTA("Magenta", Color.magenta), ORANGE("Orange", Color.orange);

对此:

代码语言:javascript
复制
enum MyColor {
   BLACK("Black", Color.black), BLUE("Blue", Color.blue), 
   CYAN("Cyan", Color.cyan), GREEN("Green", Color.green), 
   MAGENTA("Magenta", Color.magenta), ORANGE("Orange", Color.orange),
   GRAY("Gray", Color.gray), FOO("Foo", new Color(100, 250, 255));

然后GUI将自动地容纳额外的颜色。

票数 10
EN

Code Review用户

发布于 2015-01-26 10:44:16

在我看来,使用枚举的答案是有力的,但稍微有点过火。我更希望通过将标签创建代码提取到一个单独的方法中来保持简单,因此如下:

代码语言:javascript
复制
{
    ...
    // add set properties and add panel to JFrame
    magenta.setOpaque(true);
    magenta.setForeground(Color.magenta);
    magenta.setBackground(Color.white);
    magenta.setBorder(line);
    magenta.setFont(TNR);
    magenta.setToolTipText("This is Magenta");
    add(magenta);

    // add set properties and add panel to JFrame
    orange.setOpaque(true);
    orange.setForeground(Color.orange);
    orange.setBackground(Color.white);
    orange.setBorder(line);
    orange.setFont(TNR);
    orange.setToolTipText("This is Orange");
    add(orange);
}

变成这样:

代码语言:javascript
复制
{
    magenta = createLabel("This is Magenta", Color.magenta);
    orange = createLabel("This is Orange", Color.orange);
    ...

    add(magenta);
    add(orange);
    add(...);
}

private static JLabel createLabel(String text, Color color) {
    JLabel label = new JLabel();
    label.setOpaque(true);
    label.setForeground(color);
    label.setBackground(Color.white);
    label.setBorder(line);
    label.setFont(TNR);
    label.setToolTipText(text);
    return label;
}

这样做仍然很清楚,如果你决定改变创建标签的方式,那就有一个显而易见的地方-- createLabel方法。

为了清晰和简洁而重构时,我的第一个调用端口是考虑提取一个简短的方法并多次调用该方法,而不是使用循环。但是,如果需要添加大量的JLabels,并且不需要保留引用(通常不需要),那么循环可能更合适。

票数 4
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/78591

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档