【问题标题】:A Grid layout containing Card layouts - can it be done?包含卡片布局的网格布局 - 可以吗?
【发布时间】:2016-07-16 09:50:46
【问题描述】:

目标是显示一个单元格表,其中所有单元格相互独立,每个单元格都有几个可选显示(想象一个 Kakuro 板、jeopardy 板等)

这是我第一次尝试挥杆。经过大量阅读,我决定我的方法是首先使用卡片布局独立设计每个单元格(这部分我很满意),然后将其“包装”在网格布局中。 这可能是我对基本 Swing 缺乏了解的地方:

在设计每个单元格时,我会创建一个框架并为其添加一个面板:

    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;

    public class Cell extends Component{

    JFrame frame = new JFrame();

    /* we'll use a card layout with a panel for each look of the cell */
    CardLayout cardLayout = new CardLayout();
    JPanel containterPanel = new JPanel();
    JPanel firstPanel = new JPanel();
    JPanel secondPanel = new JPanel();
    JPanel thridpanel = new JPanel();

    public  Cell(){

        /* assign the card layout to the container panel */
        containterPanel.setLayout(cardLayout);

        /* assign objects to the different panels - details not important for the sake of the question */
        //....

        /* add the different panels to the container panel and show the initial one */
        containterPanel.add(firstPanel, "firstPanel");
        containterPanel.add(secondPanel, "secondPanel");
        containterPanel.add(thridpanel, "thridpanel");
        cardLayout.show(containterPanel, "firstPanel");

        /* add the container to the frame and display it*/
        frame.add(containterPanel);
        frame.setVisible(true);
    }
}

这表现得很好。 但是我尝试将它包装在网格布局中,每个单元格的行为都像这样非常笨拙:

import java.awt.*;


public class Board{

    private static final int COLUMNS_NUM = 3;
    private static final int ROWS_NUM = 3;

    JFrame frame = new JFrame();
    JPanel panel = new JPanel();
    Cell cells[] = new Cell[COLUMNS_NUM * ROWS_NUM];

    public Board(){

        panel.setLayout(new GridLayout(ROWS_NUM, COLUMNS_NUM));
        for (int i = 0; i <ROWS_NUM * COLUMNS_NUM; i++)
        {
            cells[i] = new Cell();
            panel.add(cells[i]);
        }

        frame.add(panel);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        new Board();
    }

}

我得到的是一堆不相关的框架,与主板框架分开。 显然我没有正确处理框架(我应该只创建一个......?)。 任何指导我正确方法的帮助将不胜感激。

【问题讨论】:

  • 1) “包含卡片布局的网格布局 - 可以吗?” 可以。 2) 为了尽快获得更好的帮助,请发帖minimal reproducible exampleShort, Self Contained, Correct Example
  • 谢谢@AndrewThompson,这里比较新——我做了一些小修改,我相信它现在满足“最小、完整和可验证”的要求。如果不是,请告诉我。
  • 如果要将单元格添加到 Board,请将它们设为 JPanel,而不是 JFrame
  • 一般来说,你画一个游戏板,其中的单元格可以取不同的值。请参阅 Painting in AWT and Swing 和我的 Swing 文章 Kakurasu Using Java Swing

标签: java swing jframe grid-layout cardlayout


【解决方案1】:

如果要将 Cells 添加到 Board,请将它们设为 JPanel,而不是 JFrame


一个例子:

import java.awt.CardLayout;
import javax.swing.JLabel;
import javax.swing.JPanel;

//make it a sub class of JPanel for easier implementation. 
public class Cell extends JPanel{

    public  Cell(){

        JPanel firstPanel = new JPanel();
        //add a lable just so something is displayed
        firstPanel.add(new JLabel(("Panel 1"))); 
        JPanel secondPanel = new JPanel();
        JPanel thridpanel = new JPanel();

        CardLayout cardLayout = new CardLayout();
        /* assign the card layout */
        setLayout(cardLayout);
    
        /* add the different panels to the container panel and show the initial one */
        add(firstPanel, "firstPanel");
        add(secondPanel, "secondPanel");
        add(thridpanel, "thridpanel");
        cardLayout.show(this, "firstPanel");
    }
}

还有一块板子用来装牢房:

    import java.awt.Dimension;
import java.awt.GridLayout;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;


//make it a sub class of JFrame for easier implementation.
public class Board extends JFrame{

    private static final int COLUMNS_NUM = 3;
    private static final int ROWS_NUM = 3;

    Cell cells[] = new Cell[COLUMNS_NUM * ROWS_NUM];

    public Board(){

        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setPreferredSize(new Dimension(800, 800));

        JPanel panel = new JPanel();
        add(panel);  //or better    getContentPane().add(panel);
        panel.setLayout(new GridLayout(ROWS_NUM, COLUMNS_NUM));

        for (int i = 0; i <(ROWS_NUM * COLUMNS_NUM); i++)
        {
            cells[i] = new Cell();
            panel.add(cells[i]);
        }

        pack();
        setVisible(true);
    }

    public static void main(String[] args) {
        new Board();
    }
}

它是这样的:

【讨论】:

  • 谢谢,这让我找到了方向。在您的建议中,卡片布局包含三个面板,没有父容器 - 如果我理解正确,拥有这样的容器面板是支持卡片之间转换的正确方法。所以我所做的是:panel.add(cells[i].containterPanel);而不是这个: panel.add(cells[i]);仅此而已 - 添加容器面板而不是 Cell 本身(在我的版本中,它不扩展 Jpanel)。
  • 我很高兴它有帮助。对你的问题投了赞成票,因为它的格式很好。
猜你喜欢
  • 1970-01-01
  • 2021-01-30
  • 2020-05-28
  • 1970-01-01
  • 2020-09-19
  • 2014-06-07
  • 1970-01-01
  • 2021-08-08
  • 2019-12-24
相关资源
最近更新 更多