Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/346.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在BorderLayout内重新绘制JPanel_Java_Swing_Grid_Jpanel_Repaint - Fatal编程技术网

Java 如何在BorderLayout内重新绘制JPanel

Java 如何在BorderLayout内重新绘制JPanel,java,swing,grid,jpanel,repaint,Java,Swing,Grid,Jpanel,Repaint,在我的borderlayout中,我有JPanel,它们由数组theGrid引用。在一个单独的函数中,我想更改JPanel的外观,因此我要更改特定JPanel的绘制方式。我的问题是,我不知道我现在如何使它画这个新版本的JPanel 我已经研究了其他问题,并尝试在mainPanel或contentPane上或两者上使用.revalidate、.validate、.repaint()等,但没有一个会得到我创建的JPanel的新版本 在下面的构造器中,我设置了网格,以及它将如何适应JFrame的其余部

在我的borderlayout中,我有JPanel,它们由数组theGrid引用。在一个单独的函数中,我想更改JPanel的外观,因此我要更改特定JPanel的绘制方式。我的问题是,我不知道我现在如何使它画这个新版本的JPanel

我已经研究了其他问题,并尝试在mainPanel或contentPane上或两者上使用.revalidate、.validate、.repaint()等,但没有一个会得到我创建的JPanel的新版本

在下面的构造器中,我设置了网格,以及它将如何适应JFrame的其余部分

 public class GraphicDisplay extends JFrame {

        private static int ROWS = 6;
        private static int COLS = 7;
        private JPanel[][] theGrid = new JPanel[ROWS][COLS];
        private JPanel mainPanel = new JPanel(new GridLayout(ROWS, COLS));
        private Container contentPane;

        public GraphicDisplay() {
            for (int i = 0; i < theGrid.length; i++) { //Initialize theGrid (with blanks)
                for (int j = 0; j < theGrid[i].length; j++) {
                    theGrid[i][j] = new JPanel();
                }
            }

            //add them to the JFrame
            contentPane = getContentPane();
            contentPane.setLayout(new BorderLayout());

            JPanel boardElements = new JPanel();
            boardElements.setLayout(new BoxLayout(boardElements, BoxLayout.Y_AXIS)); //vertical layout for the two parts, theGrid itself and then the
            // button which goes underneath, 

            final int SPACE = 3;
            final Color COLORCHOICE = Color.BLACK;


            mainPanel.setBorder(BorderFactory.createEmptyBorder(SPACE, SPACE, SPACE, SPACE));
            mainPanel.setBackground(COLORCHOICE);
            JPanel[][] panels = new JPanel[ROWS][COLS];
            for (int i = 0; i < panels.length; i++) {
                for (int j = 0; j < panels[i].length; j++) {
                    panels[i][j] = new JPanel(new GridLayout(1, 1, 1, 1));
                    panels[i][j].setBackground(COLORCHOICE);
                    panels[i][j].setBorder(BorderFactory.createEmptyBorder(SPACE, SPACE, SPACE, SPACE));

                    mainPanel.add(panels[i][j]);


                    panels[i][j].add(theGrid[i][j]);


                }
            }
            //adding the grid to the vertical layout
            boardElements.add(mainPanel);
            //adding the button which will go directly under the grid
            boardElements.add(new JButton("Button"));

            contentPane.add(boardElements, BorderLayout.CENTER);

        }
创建GraphicDisplay对象的另一个类中的Main方法

public static void main(String[] args) {

            GraphicDisplay display2 = new GraphicDisplay();
            display2.setSize(600, 600);
            display2.setVisible(true);
            display2.addDotToGrid();
        }

问题是显示网格,但addDotToGrid()不会更改任何内容,并且网格中没有添加点

您正在更改由theGrid数组持有的JPanel,但这对GUI中显示的JPanel没有影响,这就是变量和引用或对象之间的关键区别——更改变量引用的对象对它以前引用的对象没有影响。您的解决方案是更改网格持有的JPanel

实现这一点的一种方法是,为所有这些组件提供绘制所需内容的paintComponent方法,但让它们由布尔值控制,然后更改感兴趣面板的布尔变量

如果这是我的GUI,我会创建一个由JLabel组成的网格,并在需要的地方和时间简单地交换ImageIcon——让它尽可能简单

比如说

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;

import javax.swing.*;

@SuppressWarnings("serial")
public class MyGridEg extends JPanel {
    private static final int SPACE = 6;
    private static final int ROWS = 6;
    private static final int COLS = 7;
    private static final int IMG_W = 80;
    private static final int SML_GAP = 3;
    private static final Color IMG_BACKG = new Color(240, 240, 240);
    private static final String TITLE = "Click on a Cell";

    private JLabel[][] labelGrid = new JLabel[ROWS][COLS];
    private Icon blankIcon = createIconDisk(new Color(0, 0, 0, 0));
    private Icon redIcon = createIconDisk(Color.RED);

    public MyGridEg() {
        MyMouse myMouse = new MyMouse();
        JPanel gridHolder = new JPanel(new GridLayout(ROWS, COLS, SPACE, SPACE));
        gridHolder.setBackground(Color.BLACK);
        for (int i = 0; i < labelGrid.length; i++) {
            for (int j = 0; j < labelGrid[i].length; j++) {
                JLabel label = new JLabel(blankIcon);
                label.addMouseListener(myMouse);
                labelGrid[i][j] = label;
                gridHolder.add(label);
            }
        }
        gridHolder.setBorder(BorderFactory.createLineBorder(Color.black, SPACE));

        JLabel titleLabel = new JLabel(TITLE, SwingConstants.CENTER);
        titleLabel.setFont(titleLabel.getFont().deriveFont(Font.BOLD, 20));

        JButton clearButton = new JButton(new ClearAction("Clear"));
        JPanel btnPanel = new JPanel();
        btnPanel.add(clearButton);

        setLayout(new BorderLayout());
        add(gridHolder, BorderLayout.CENTER);
        add(btnPanel, BorderLayout.PAGE_END);
        add(titleLabel, BorderLayout.PAGE_START);
    }

    private Icon createIconDisk(Color color) {
        BufferedImage img = new BufferedImage(IMG_W, IMG_W, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2 = img.createGraphics();
        g2.setBackground(IMG_BACKG);
        g2.clearRect(0, 0, IMG_W, IMG_W);
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setColor(color);
        int x = SML_GAP;
        int y = x;
        int width = IMG_W - 2 * x;
        int height = IMG_W - 2 * y;
        g2.fillOval(x, y, width, height);
        g2.dispose();
        return new ImageIcon(img);
    }

    private class MyMouse extends MouseAdapter {
        @Override
            public void mousePressed(MouseEvent e) {
                JLabel selected = (JLabel) e.getSource();
                Icon icon = selected.getIcon() == blankIcon ? redIcon : blankIcon;
                selected.setIcon(icon);
            }
    }

    private class ClearAction extends AbstractAction {
        public ClearAction(String name) {
            super(name);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            for (JLabel[] labelRow : labelGrid) {
                for (JLabel cell : labelRow) {
                    cell.setIcon(blankIcon);
                }
            }
        }
    }

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

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

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}

没有子对象的JPanel的首选大小为0×0像素,如果有子对象,则加上其边框的插入部分。重写JPanel子类中的getPreferredSize(),以返回适合椭圆的大小。
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;

import javax.swing.*;

@SuppressWarnings("serial")
public class MyGridEg extends JPanel {
    private static final int SPACE = 6;
    private static final int ROWS = 6;
    private static final int COLS = 7;
    private static final int IMG_W = 80;
    private static final int SML_GAP = 3;
    private static final Color IMG_BACKG = new Color(240, 240, 240);
    private static final String TITLE = "Click on a Cell";

    private JLabel[][] labelGrid = new JLabel[ROWS][COLS];
    private Icon blankIcon = createIconDisk(new Color(0, 0, 0, 0));
    private Icon redIcon = createIconDisk(Color.RED);

    public MyGridEg() {
        MyMouse myMouse = new MyMouse();
        JPanel gridHolder = new JPanel(new GridLayout(ROWS, COLS, SPACE, SPACE));
        gridHolder.setBackground(Color.BLACK);
        for (int i = 0; i < labelGrid.length; i++) {
            for (int j = 0; j < labelGrid[i].length; j++) {
                JLabel label = new JLabel(blankIcon);
                label.addMouseListener(myMouse);
                labelGrid[i][j] = label;
                gridHolder.add(label);
            }
        }
        gridHolder.setBorder(BorderFactory.createLineBorder(Color.black, SPACE));

        JLabel titleLabel = new JLabel(TITLE, SwingConstants.CENTER);
        titleLabel.setFont(titleLabel.getFont().deriveFont(Font.BOLD, 20));

        JButton clearButton = new JButton(new ClearAction("Clear"));
        JPanel btnPanel = new JPanel();
        btnPanel.add(clearButton);

        setLayout(new BorderLayout());
        add(gridHolder, BorderLayout.CENTER);
        add(btnPanel, BorderLayout.PAGE_END);
        add(titleLabel, BorderLayout.PAGE_START);
    }

    private Icon createIconDisk(Color color) {
        BufferedImage img = new BufferedImage(IMG_W, IMG_W, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2 = img.createGraphics();
        g2.setBackground(IMG_BACKG);
        g2.clearRect(0, 0, IMG_W, IMG_W);
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setColor(color);
        int x = SML_GAP;
        int y = x;
        int width = IMG_W - 2 * x;
        int height = IMG_W - 2 * y;
        g2.fillOval(x, y, width, height);
        g2.dispose();
        return new ImageIcon(img);
    }

    private class MyMouse extends MouseAdapter {
        @Override
            public void mousePressed(MouseEvent e) {
                JLabel selected = (JLabel) e.getSource();
                Icon icon = selected.getIcon() == blankIcon ? redIcon : blankIcon;
                selected.setIcon(icon);
            }
    }

    private class ClearAction extends AbstractAction {
        public ClearAction(String name) {
            super(name);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            for (JLabel[] labelRow : labelGrid) {
                for (JLabel cell : labelRow) {
                    cell.setIcon(blankIcon);
                }
            }
        }
    }

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

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

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}
private class ClearAction extends AbstractAction {
    public ClearAction(String name) {
        super(name);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        for (JLabel[] labelRow : labelGrid) {
            for (JLabel cell : labelRow) {
                cell.setIcon(blankIcon);
            }
        }
    }
}