【问题标题】:How to put 1 JPanel and 1 Custom JPanel in a JFrame如何将 1 个 JPanel 和 1 个自定义 JPanel 放入 JFrame
【发布时间】:2019-03-26 10:25:15
【问题描述】:

我想在我的应用中并排放置 2 个 JPanel。一个将在右侧包含一些关于我的自定义板的信息,另一个将在左侧包含关于绘制该自定义板的信息。第一个 JPanel 是经典的,但第二个是自定义面板。我似乎在将自定义面板放入框架时遇到问题。

我在我的 gui 类中创建了一个名为 BoardPanel 的类来绘制我的自定义板。我不知道这是否是最好的方法。我应该创建一个单独的类吗?

这是gui类的代码:

public class BattleshipGUI extends JFrame {

    private BoardPanel mainPanel;


    ///////////////////////////////////////////////////////////////////////////////////////////////
    // Create my frame
    ///////////////////////////////////////////////////////////////////////////////////////////////
    public BattleshipGUI() {

        JPanel container = new JPanel(new BorderLayout()); //the container panel that contains the 2 other panels

        mainPanel = new BoardPanel(); //main panel with my custom painting
        JPanel detailsPanel = new JPanel(new BorderLayout()); //secondary panel with various details about the game

        container.add(mainPanel, BorderLayout.CENTER); //add the 2 panels in the container
        container.add(detailsPanel, BorderLayout.EAST);

        this.add(container); //add container to my frame
        //this.setContentPane(container);



        this.setIconImage(Toolkit.getDefaultToolkit().getImage(BattleshipGUI.class.getResource("/resources/battleship_128.png")));
        this.setTitle("My Battleship Game");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //this.setBounds(100, 100, 850, 700);
        //this.pack();
        this.setSize(850, 600);

        this.setVisible(true);

    }

这是自定义绘画的内部类的代码

class BoardPanel extends JPanel {

        private static final int ROWS = 20;
        private static final int COLUMNS = 20;


        public void paintComponent(Graphics g) {
            super.paintComponent(g);

            int sqSize = this.getHeight()/ROWS;

            for(int i=0; i<ROWS; i++) {
                for(int j=0; j<COLUMNS; j++) {
                    int x = j * sqSize;
                    int y = i * sqSize;
                    g.drawRect(x, y, sqSize, sqSize);

                }
            }

        }
    }

除了所有这些,我还有一个问题。如果我想要自定义绘画,是否可以与 WindowsBuilderPro 一起工作?我一开始就开始使用那个工具。但是,我看到我无法使用该工具绘制自定义的东西,我不得不编写代码来做到这一点。是否可以为自定义绘画编写代码并同时将该工具用于不同目的,例如添加简单的文本标签,甚至编辑该自定义绘画?我想看到的预期结果在我运行程序时出现。我的框架有两个面板。但是当我打开 WindowsBuilderPro 时,我的自定义面板没有出现,结果有点错误。这就是为什么我对我的方法以及我是否可以同时编写代码和使用该工具有疑问的原因。谢谢你,很抱歉那些长文的家伙。我对此感到很困惑。

【问题讨论】:

  • BoardPanel 需要提供尺寸提示。您需要覆盖 getPreferredSize 并返回组件想要的“首选”大小
  • @MadProgrammer 我为什么要这样做?我的意思是,它解决了什么问题,不包括它有什么问题?像这样? public Dimension getPreferredSize() { return new Dimension(400, 600); }
  • 布局管理器将使用大小提示来决定如何最好地布局组件,没有大小提示,组件的默认大小为 0x0
  • @MadProgrammer 所以,我每次都必须这样做,对吧?我是否也必须为第一个经典面板这样做?我在 BoardPanel 中实现了该公共方法,但我没有看到 BoardPanel 组件的大小发生变化。
  • @MadProgrammer 可以帮我解决这个问题吗?对于大小和我对两个面板的方法的问题。我真的不知道如何继续,等等。谢谢。

标签: java windowsbuilder


【解决方案1】:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

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

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.fill = gbc.BOTH;
            gbc.gridx = 0;
            gbc.gridy = 0;

            JPanel filler = new JPanel() {
                @Override
                public Dimension getPreferredSize() {
                    return new Dimension(200, 300);
                }
            };
            filler.setBackground(Color.BLUE);

            add(filler, gbc);
            gbc.gridx++;
            add(new BoardPanel(), gbc);
        }

    }

    class BoardPanel extends JPanel {

        private static final int ROWS = 20;
        private static final int COLUMNS = 20;
        private int sqSize = 20;

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(COLUMNS * sqSize, ROWS * sqSize);
        }

        public void paintComponent(Graphics g) {
            super.paintComponent(g);

            for (int i = 0; i < ROWS; i++) {
                for (int j = 0; j < COLUMNS; j++) {
                    int x = j * sqSize;
                    int y = i * sqSize;
                    g.drawRect(x, y, sqSize, sqSize);

                }
            }

        }
    }

}

花时间阅读Laying Out Components Within a Container,以更好地了解布局管理 API 的工作原理

【讨论】:

  • 哇。谢谢你。但我有一些问题,因为我真的需要很好地理解这一点。我已经从上面的链接中阅读了 GridBagLayout 和 BorderLayout 。我怎么知道我应该使用所有这些布局中的哪一种?我已经(严重)使用了 BorderLayout。您使用了 GridBadLayout。此外,您调用 .pack() 方法而不是 setSize。它是可取的吗?当您调用该方法时,框架是否有任何大小?
  • 布局选择是设计问题,您使用复合布局来实现高级布局。窗口的默认大小为 0x0,使用 pack 将采用内容的首选大小并将框架装饰包裹在其周围 - 重要的是要注意框架装饰可以根据配置和操作系统的不同大小
  • 啊哈,我明白了。那么,如果我愿意,我可以使用 BorderLayout 吗? GridBagLayout 看起来很有趣。另外,我读过这篇文章:如果您对学习布局管理的所有细节不感兴趣,您可能更喜欢使用 GroupLayout 布局管理器和构建器工具来布局您的 GUI。 NetBeans IDE 就是这样一种构建器工具。否则,如果您想手动编码并且不想使用 GroupLayout,那么建议使用 GridBagLayout 作为下一个最灵活且功能强大的布局管理器。。我想这回答了我关于同时使用工具和编写代码的问题。
  • 初学者更喜欢什么?使用 GroupLayout plus builder 工具还是手写?正如我所说,我发现了 Windowsbuilder Pro,它有一些潜力,但对我的情况没有多大帮助。
  • 恕我直言,您花时间学习如何手动使用布局管理器。 GUI 编辑器会产生不良习惯,通常会将您锁定在单个编辑器中。 GUI 编辑器也往往会生成糟糕的代码,而且我在组布局方面也遇到过不少问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-11
相关资源
最近更新 更多