在 Java Swing 上刷新 GridLayout 时出现问题

发布于 2025-01-17 12:19:37 字数 2895 浏览 5 评论 0原文

我在刷新我的gridlayout值时有问题。

因此,我在jframe中有一个jpanel,在那个jpanel中,一旦我输入了两个值(一个用于行,一个用于列),然后单击validate,我获得了一个带有jbuttons先前值的gridlayout。 因此,如果我输入(2,2),我会得到4个jbuttons的gridlayout,在每个jbutton中,我都有一个图像。

因此,我的问题是,每当我想通过更改值来刷新gridlayout,它不起作用,gridlayout不会改变,或者如果变化,jbuttons都可以包含在内。 我觉得每次点击validate时,我的jpanel都会创建一个新的gridlayout,但第一个仍然存在。

我将上传两个图片,一张具有正常功能(首次输入值),第二张带有错误(输入新值)。

谢谢大家。

第一个值 第二个值

import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Color;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.awt.event.ActionEvent;
import javax.swing.*;




    public class PagePrincipal extends JFrame implements ActionListener {

    JButton Valider;
    JTextField Columns;
    JTextField Rows;
    ArrayList<JButton> butt;
   
    
    public PagePrincipal(){
        
        getContentPane().setLayout(null); //this is not the panel that contains the GridLayout
    
        Columns = new JTextField();
        Columns.setBounds(219, 35, 197, 57);
        getContentPane().add(Columns);
        Columns.setColumns(10);
        
        Rows = new JTextField();
        Rows.setBounds(451, 35, 226, 57);
        getContentPane().add(Rows);
        Rows.setColumns(10);
        
        Valider = new JButton();
        Valider.setBackground(new Color(65, 179, 163));
        Valider.setForeground(Color.WHITE);
        Valider.setFont(new Font("Bookman Old Style", Font.BOLD, 20));
        Valider.setBounds(704, 15, 268, 81);
        Valider.setText("Validation");
        Valider.addActionListener(this);
        this.add(Valider);

        
        this.setResizable(true);
        this.setVisible(true);
        this.setExtendedState(JFrame.MAXIMIZED_BOTH); 
        
        
        
        
        
    }
    

    @Override    
   
    
        
    public void actionPerformed(ActionEvent event) {

     if (event.getSource() == Valider) {   
        int NbRows= Integer.parseInt(Rows.getText());
        int NbColumns=Integer.parseInt(Columns.getText());
        JButton button[] = new JButton[NbRows*NbColumns];
        butt = new ArrayList<>();
       
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        JPanel botPanel = new JPanel(); //this is the panel that contains the GridLayout
        botPanel.setBounds(100, 200, 1000, 400);
        this.add(botPanel);
        
        botPanel.setLayout(new GridLayout(NbRows,NbColumns));
        
        for (int i=0; i<NbRows*NbColumns; i++){
                button[i]=new JButton();
                botPanel.add(button[i]);
                butt.add(button[i]);    
        }
        this.setVisible(true);
        
    }
     
        
}
}

i have a problem with refreshing the values of my gridlayout.

So, i have a JPanel in a JFrame and in that JPanel , once i entered two values(one for rows and one for columns) and then by clicking on validate, i get a GridLayout with the previous values of JButtons.
So for exemple if I enter (2,2) i get a GridLayout of 4 JButtons and in each JButton i have an image.

So my problem here is, every time i wanna refresh the GridLayout by changing the values, it doesn’t work, the GridLayout doesn’t change, or if it change, the JButtons are inclickable.
I feel like every time i click on Validate, a new GridLayout is created on my JPanel, but the first one is still there.

I will upload two pictures, one with the normal functioning (entering values first time), and the second with the bug (entering new values).

Thanks guys.

First values
Second values

import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Color;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.awt.event.ActionEvent;
import javax.swing.*;




    public class PagePrincipal extends JFrame implements ActionListener {

    JButton Valider;
    JTextField Columns;
    JTextField Rows;
    ArrayList<JButton> butt;
   
    
    public PagePrincipal(){
        
        getContentPane().setLayout(null); //this is not the panel that contains the GridLayout
    
        Columns = new JTextField();
        Columns.setBounds(219, 35, 197, 57);
        getContentPane().add(Columns);
        Columns.setColumns(10);
        
        Rows = new JTextField();
        Rows.setBounds(451, 35, 226, 57);
        getContentPane().add(Rows);
        Rows.setColumns(10);
        
        Valider = new JButton();
        Valider.setBackground(new Color(65, 179, 163));
        Valider.setForeground(Color.WHITE);
        Valider.setFont(new Font("Bookman Old Style", Font.BOLD, 20));
        Valider.setBounds(704, 15, 268, 81);
        Valider.setText("Validation");
        Valider.addActionListener(this);
        this.add(Valider);

        
        this.setResizable(true);
        this.setVisible(true);
        this.setExtendedState(JFrame.MAXIMIZED_BOTH); 
        
        
        
        
        
    }
    

    @Override    
   
    
        
    public void actionPerformed(ActionEvent event) {

     if (event.getSource() == Valider) {   
        int NbRows= Integer.parseInt(Rows.getText());
        int NbColumns=Integer.parseInt(Columns.getText());
        JButton button[] = new JButton[NbRows*NbColumns];
        butt = new ArrayList<>();
       
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        JPanel botPanel = new JPanel(); //this is the panel that contains the GridLayout
        botPanel.setBounds(100, 200, 1000, 400);
        this.add(botPanel);
        
        botPanel.setLayout(new GridLayout(NbRows,NbColumns));
        
        for (int i=0; i<NbRows*NbColumns; i++){
                button[i]=new JButton();
                botPanel.add(button[i]);
                butt.add(button[i]);    
        }
        this.setVisible(true);
        
    }
     
        
}
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一向肩并 2025-01-24 12:19:37

同样,如果可能的话,请避免使用零布局,因为它们迫使您创建刚性,僵化,难以维护可能仅在一个平台上使用的GUI。取而代之的是,Nest Jpanels使用自己的布局来帮助创建看起来不错,灵活,可扩展和工作的GUI。

此外,在更改更改后,在容器中持有的组件时,请调用Revalidate() and repaver()。例如,以下GUI:

”输入映像在此处“

“在此处输入图像描述”

是使用以下代码创建的:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.util.ArrayList;
import java.util.List;

import javax.swing.*;

public class PagePrincipal2 extends JPanel {
    public static final int MAX_ROWS = 40;
    public static final int MAX_COLS = 12;
    private JButton validatorButton = new JButton("Validate");
    private JSpinner columnsSpinner = new JSpinner(new SpinnerNumberModel(2, 1, MAX_COLS, 1));
    private JSpinner rowsSpinner = new JSpinner(new SpinnerNumberModel(2, 1, MAX_ROWS, 1));
    private List<JButton> buttonsList = new ArrayList<>();
    private JPanel gridPanel = new JPanel();
    
    public PagePrincipal2() {
        JPanel topPanel = new JPanel();
        topPanel.add(new JLabel("Columns:"));
        topPanel.add(columnsSpinner);
        topPanel.add(Box.createHorizontalStrut(10));
        topPanel.add(new JLabel("Rows:"));
        topPanel.add(rowsSpinner);
        topPanel.add(Box.createHorizontalStrut(10));
        topPanel.add(validatorButton);
        
        JScrollPane scrollPane = new JScrollPane(gridPanel);
        
        int gridWidth = 1000;
        int gridHeight = 600;
        scrollPane.setPreferredSize(new Dimension(gridWidth, gridHeight));
        
        setLayout(new BorderLayout());
        add(topPanel, BorderLayout.PAGE_START);
        add(scrollPane, BorderLayout.CENTER);
        
        validatorButton.addActionListener(e -> validateGrid());
    }
    
    private void validateGrid() {
        int nbRows = (int) rowsSpinner.getValue();
        int nbColumns = (int) columnsSpinner.getValue();
        gridPanel.removeAll();
        buttonsList.clear();
        gridPanel.setLayout(new GridLayout(nbRows, nbColumns));
        for (int i = 0; i < nbRows * nbColumns; i++) {
            int column = i % nbColumns;
            int row = i / nbColumns;
            String text = String.format("[%02d, %02d]", column, row);
            JButton button = new JButton(text);
            button.addActionListener(e -> gridButtonAction(column, row));
            buttonsList.add(button);
            gridPanel.add(button);
        }
        gridPanel.revalidate();
        gridPanel.repaint();
    }
    
    private void gridButtonAction(int column, int row) {
        String message = String.format("Button pressed: [%02d, %02d]", column, row);
        String title = "Grid Button Press";
        int type = JOptionPane.INFORMATION_MESSAGE;
        JOptionPane.showMessageDialog(this, message, title, type);
    }
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            PagePrincipal2 mainPanel = new PagePrincipal2();

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


请注意,握住按钮的Gridpanel被放置在JSCrollpane中:

JScrollPane scrollPane = new JScrollPane(gridPanel);

请注意,请注意持有所有内容的主jpanel都会给出一个边框,然后添加了2个组件,toppanel jpanel保存数据输入标签,按钮和字段,添加在borderlayout.page_start.page_start borderlayout.center位置:

setLayout(new BorderLayout());
add(topPanel, BorderLayout.PAGE_START);
add(scrollPane, BorderLayout.CENTER);

从Gridpanel中删除旧按钮,然后添加新按钮,我将调用revalidate()和repaver()在Gridpanel上,这是第一个让布局经理布局布局的方法,以及第二种方法调用以删除可能存在的任何肮脏像素:

private void validateGrid() {
    int nbRows = (int) rowsSpinner.getValue();
    int nbColumns = (int) columnsSpinner.getValue();
    gridPanel.removeAll();
    buttonsList.clear();
    gridPanel.setLayout(new GridLayout(nbRows, nbColumns));
    for (int i = 0; i < nbRows * nbColumns; i++) {
        int column = i % nbColumns;
        int row = i / nbColumns;
        String text = String.format("[%02d, %02d]", column, row);
        JButton button = new JButton(text);
        button.addActionListener(e -> gridButtonAction(column, row));
        buttonsList.add(button);
        gridPanel.add(button);
    }
    gridPanel.revalidate();
    gridPanel.repaint();
}

Again, avoid null layouts if at all possible, since they force you to create rigid, inflexible, hard to maintain GUI's that might work on one platform only. Instead, nest JPanels, each using its own layout to help create GUI's that look good, are flexible, extendable and that work.

Also, when changing components held within a container, call revalidate() and repaint() on the container after making the changes. For example, the following GUI:

enter image description here

enter image description here

Is created with the following code:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.util.ArrayList;
import java.util.List;

import javax.swing.*;

public class PagePrincipal2 extends JPanel {
    public static final int MAX_ROWS = 40;
    public static final int MAX_COLS = 12;
    private JButton validatorButton = new JButton("Validate");
    private JSpinner columnsSpinner = new JSpinner(new SpinnerNumberModel(2, 1, MAX_COLS, 1));
    private JSpinner rowsSpinner = new JSpinner(new SpinnerNumberModel(2, 1, MAX_ROWS, 1));
    private List<JButton> buttonsList = new ArrayList<>();
    private JPanel gridPanel = new JPanel();
    
    public PagePrincipal2() {
        JPanel topPanel = new JPanel();
        topPanel.add(new JLabel("Columns:"));
        topPanel.add(columnsSpinner);
        topPanel.add(Box.createHorizontalStrut(10));
        topPanel.add(new JLabel("Rows:"));
        topPanel.add(rowsSpinner);
        topPanel.add(Box.createHorizontalStrut(10));
        topPanel.add(validatorButton);
        
        JScrollPane scrollPane = new JScrollPane(gridPanel);
        
        int gridWidth = 1000;
        int gridHeight = 600;
        scrollPane.setPreferredSize(new Dimension(gridWidth, gridHeight));
        
        setLayout(new BorderLayout());
        add(topPanel, BorderLayout.PAGE_START);
        add(scrollPane, BorderLayout.CENTER);
        
        validatorButton.addActionListener(e -> validateGrid());
    }
    
    private void validateGrid() {
        int nbRows = (int) rowsSpinner.getValue();
        int nbColumns = (int) columnsSpinner.getValue();
        gridPanel.removeAll();
        buttonsList.clear();
        gridPanel.setLayout(new GridLayout(nbRows, nbColumns));
        for (int i = 0; i < nbRows * nbColumns; i++) {
            int column = i % nbColumns;
            int row = i / nbColumns;
            String text = String.format("[%02d, %02d]", column, row);
            JButton button = new JButton(text);
            button.addActionListener(e -> gridButtonAction(column, row));
            buttonsList.add(button);
            gridPanel.add(button);
        }
        gridPanel.revalidate();
        gridPanel.repaint();
    }
    
    private void gridButtonAction(int column, int row) {
        String message = String.format("Button pressed: [%02d, %02d]", column, row);
        String title = "Grid Button Press";
        int type = JOptionPane.INFORMATION_MESSAGE;
        JOptionPane.showMessageDialog(this, message, title, type);
    }
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            PagePrincipal2 mainPanel = new PagePrincipal2();

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


Note that the gridPanel, the one holding the buttons, is placed into a JScrollPane:

JScrollPane scrollPane = new JScrollPane(gridPanel);

Note that the main JPanel that holds everything is given a BorderLayout, and then 2 components are added, a topPanel JPanel that holds labels, buttons and fields for data input, added at the BorderLayout.PAGE_START, the top position, and the JScrollPane is added to the main JPanel at the BorderLayout.CENTER position:

setLayout(new BorderLayout());
add(topPanel, BorderLayout.PAGE_START);
add(scrollPane, BorderLayout.CENTER);

When the old buttons are removed from the gridPanel, and then new buttons are added, I will call revalidate() and repaint() on the gridPanel, the first method to get the layout managers to layout the new components, and the second method call to remove any dirty pixels that may be present:

private void validateGrid() {
    int nbRows = (int) rowsSpinner.getValue();
    int nbColumns = (int) columnsSpinner.getValue();
    gridPanel.removeAll();
    buttonsList.clear();
    gridPanel.setLayout(new GridLayout(nbRows, nbColumns));
    for (int i = 0; i < nbRows * nbColumns; i++) {
        int column = i % nbColumns;
        int row = i / nbColumns;
        String text = String.format("[%02d, %02d]", column, row);
        JButton button = new JButton(text);
        button.addActionListener(e -> gridButtonAction(column, row));
        buttonsList.add(button);
        gridPanel.add(button);
    }
    gridPanel.revalidate();
    gridPanel.repaint();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文