【问题标题】:Adding Grid of Buttons to JPanel将按钮网格添加到 JPanel
【发布时间】:2018-03-01 12:16:02
【问题描述】:

我正在尝试制作一个 20px x 20px 按钮的网格,我将其定义为“单元格”,默认为空白,没有阴影等特殊装饰,单击时会更改颜色。 (它们只是为了测试目的而显示“1”)。我创建了一个 Cell 类来定义这些按钮,给每个按钮一个 ActionListener。

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

public class Cell implements ActionListener
{
    private JButton button;
    private EditorPanel editorPanel;

    public Cell(EditorPanel editorPanel){
    button = new JButton("1'");
    button.addActionListener(listener -> colorCell());
    button.setPreferredSize(new Dimension(20,20));
    button.setMargin(new Insets(0,0,0,0));
    button.setOpaque(true);
    button.setContentAreaFilled(false);
    this.editorPanel = editorPanel;
    }

public JButton getButton() {
    return button;
}

public void colorCell()
{
    button.setBackground(Color.BLACK);
}

@Override
public void actionPerformed(ActionEvent e) {

}

}

然后在我的 EditorPanel 类中使用一组 Cell 对象(单元格)来创建这些按钮的网格,其尺寸由“col”和“row”定义。

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


import javax.swing.JFrame;
import javax.swing.JPanel;
public class EditorPanel{

public JFrame jframe;
public JPanel jpanel;
public static EditorPanel editorPanel;
public Render render;
public static final int col = 45, row = 45,  tile_size=20;
public static final int panelWidth=900, panelHeight=900;
public Dimension dim;
public int coloredPixels;

public Cell[][] cells; 

public void getFrame() {

    editorPanel = new EditorPanel();
    dim = Toolkit.getDefaultToolkit().getScreenSize();
    jframe = new JFrame("Pixel Art Creator");
    jframe.setVisible(true);
    jframe.setSize(panelWidth+17, panelHeight+40);
    jframe.setLocation(dim.width/2 - jframe.getWidth()/2, dim.height/2 - jframe.getHeight()/2);
    jframe.add(render = new Render());
    jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

private JPanel addCells()
{
    cells=new Cell[row][col];
    JPanel panel = new JPanel(new GridLayout(row, col));
    for(int i = 0; i< row; i++){
        for(int j = 0; j<col; j++){
            cells[i][j] = new Cell(this);
            panel.add(cells[i][j].getButton());
        }
    }
    return panel;
}

public static void main (String[] args)
{
    editorPanel = new EditorPanel();
    editorPanel.getFrame();
    editorPanel.addCells();
}

}

然后,我尝试在 addCells() 方法中添加尝试放入单元格数组的每个已创建 Cell 对象,并将其添加到我的 JPanel。当我运行此代码时,我没有得到任何按钮,这意味着这些按钮没有被添加到 JPanel。我该怎么办?

【问题讨论】:

    标签: java swing jbutton grid-layout


    【解决方案1】:

    所以,两个“重大”问题:

    1. editorPanel.addCells(); 永远不会将它创建的 JPanel 添加到任何内容中,因此它永远不会显示
    2. 在您完成 UI 建立之前调用 JFrame#setVisible 可能会导致 UI 元素不显示在 UI 上。您可以通过在已更改的容器上调用 revalidaterepaint 来解决此问题,但如果可能,只需先建立 UI,然后使其可见

    不过,我建议稍微改变方法。与其让Cell 成为一个包含JButton 的类,然后将该按钮暴露给UI 的其他方面,不如让Cell 成为一个组件,然后简单地将其添加到您想要的任何容器中,例如。 ..

    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.border.LineBorder;
    
    public class Test {
    
        public static void main(String[] args) {
            new Test();
        }
    
        public Test() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    JFrame frame = new JFrame("Test");
                    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();
    
                for (int y = 0; y < 20; y++) {
                    gbc.gridy = y;
                    for (int x = 0; x < 20; x++) {
                        gbc.gridx = x;
                        add(new Cell(), gbc);
                    }
                }
            }
    
        }
    
        public class Cell extends JPanel {
    
            public Cell() {
                addMouseListener(new MouseAdapter() {
                    @Override
                    public void mouseClicked(MouseEvent e) {
                        colorCell();
                    }
                });
                setBorder(new LineBorder(Color.GRAY));
            }
    
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(20, 20);
            }
    
            protected void colorCell() {
                if (getBackground() != Color.DARK_GRAY) {
                    setBackground(Color.DARK_GRAY);
                } else {
                    setBackground(null);
                }
            }
    
        }
    
    }
    

    现在,在这种情况下,我刚刚使用了一个普通的旧 JPanel,但您可以轻松地从 JButtonJToggledButton 扩展......但我可能会想使用工厂模式相反,但那是我。

    使用GridBagLayout 的目的是允许调整框架和外部容器的大小而不改变Cells 本身的大小,这与GridLayout 不同,它会尝试使单元格填充可用空间

    【讨论】:

    • 喂!感谢您的快速回复。这绝对是个好主意。我从来不知道setBackground()GridBagLayout,它们是我努力实现的目标。使用 Cell 作为组件比使用单独的 Cell 类要容易WAY。谢谢十几个。您是否碰巧知道任何可以帮助我研究 GUI 的优秀在线资源?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-26
    • 1970-01-01
    • 2010-12-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多