如何将边框添加到添加到JFrame的JPanel?

时间:2018-03-30 03:30:59

标签: java swing jpanel border

我有一个java swing应用程序,它有一个名为GPanel的嵌套类,它扩展了JPanel。

GPanel的一个实例(名为graphicsPanel)被添加到带有GridBagLayout的JFrame中。

致电

之前
frame.getContentPane().add(graphicsPanel);

我打电话

graphicsPanel.setBorder(MyWindow.GRAPHICS_BORDER);

注意:

private static final Border GRAPHICS_BORDER = BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10), BorderFactory.createLineBorder(Color.BLACK, 1));

然而,边框不会出现。

我想在GPanel周围出现边框。

以下是完整代码:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridBagLayout;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.Border;

public class MyWindow {

    //virtual pixels
    private static boolean[][] screenPixels = {

        {true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false},
        {false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true},
        {true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false},
        {false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true},
        {true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false},
        {false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true},
        {true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false},
        {false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true},
        {true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false},
        {false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true},
        {true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false},
        {false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true},
        {true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false},
        {false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true},
        {true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false},
        {false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true},
        {true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false},
        {false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true},
        {true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false},
        {false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true}

    };

    //this is the border i want around my GPanel
    private static final Border GRAPHICS_BORDER = BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10), BorderFactory.createLineBorder(Color.BLACK, 1));

    //this is the size of the checkerboard inside the GPanel
    private static int dimension = 200;

    private JFrame frame;
    private GPanel graphicsPanel;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    MyWindow window = new MyWindow();
                    window.frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public MyWindow() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {

        frame = new JFrame();
        frame.setTitle("Alexander Fisher's Game");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(new GridBagLayout());
        frame.setResizable(false);

        graphicsPanel = new GPanel();
        //this is where i try to set the border
        graphicsPanel.setBorder(MyWindow.GRAPHICS_BORDER);
        graphicsPanel.setPreferredSize(new Dimension(MyWindow.dimension, MyWindow.dimension));
        graphicsPanel.setMinimumSize(new Dimension(MyWindow.dimension, MyWindow.dimension));
        graphicsPanel.setMaximumSize(new Dimension(MyWindow.dimension, MyWindow.dimension));
        frame.getContentPane().add(graphicsPanel);
        frame.pack();

    }

    private class GPanel extends JPanel {
        /**
         * 
         */
        private static final long serialVersionUID = 1L;

        @Override
        public void paint(Graphics g) {

            int pixelDimension = MyWindow.dimension / MyWindow.screenPixels.length;

            for(int intRowIndex = 0; intRowIndex < MyWindow.screenPixels.length; intRowIndex++) {
                for(int intColumnIndex = 0; intColumnIndex < MyWindow.screenPixels.length; intColumnIndex++) {
                    if(!MyWindow.screenPixels[intRowIndex][intColumnIndex]) {
                        g.setColor(Color.WHITE);
                        g.fillRect(intRowIndex * pixelDimension, intColumnIndex * pixelDimension, pixelDimension, pixelDimension);
                    } else if(MyWindow.screenPixels[intRowIndex][intColumnIndex]) {
                        g.setColor(Color.BLACK);
                        g.fillRect(intRowIndex * pixelDimension, intColumnIndex * pixelDimension, pixelDimension, pixelDimension);
                    }
                }
            }


        }
    }

}

EDIT(解决):

我添加了一行:

 private static final int BORDER_WIDTH = 11;

到MyWindow类的变量,因为部分问题是我在绘制边框的顶部绘画。除了这个更改,我更新了MyWindow.gameDimension变量用于计算边框宽度的任何地方。

接下来,我将覆盖paint(Graphics g)方法的方法更改为覆盖paintComponent(Graphics g)方法的方法,确保首先调用super.paintComponent(Graphics g)。 @MadProgrammer的建议

public void paintComponent(Graphics g) {
    super.paintComponent(g);//added this line

    int pixelDimension = MyWindow.dimension / MyWindow.screenPixels.length;

    for(int intRowIndex = 0; intRowIndex < MyWindow.screenPixels.length; intRowIndex++) {
        for(int intColumnIndex = 0; intColumnIndex < MyWindow.screenPixels.length; intColumnIndex++) {
            if(!MyWindow.screenPixels[intRowIndex][intColumnIndex]) {
                g.setColor(Color.WHITE);
                g.fillRect(intRowIndex * pixelDimension + MyWindow.BORDER_WIDTH, intColumnIndex * pixelDimension + MyWindow.BORDER_WIDTH, pixelDimension, pixelDimension);
            } else if(MyWindow.screenPixels[intRowIndex][intColumnIndex]) {
                g.setColor(Color.BLACK);
                g.fillRect(intRowIndex * pixelDimension + MyWindow.BORDER_WIDTH, intColumnIndex * pixelDimension + MyWindow.BORDER_WIDTH, pixelDimension, pixelDimension);
            }

        }

    }

}

编辑代码:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridBagLayout;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.Border;

public class MyWindow {

    //virtual pixels
    private static boolean[][] screenPixels = {

        {true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false},
        {false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true},
        {true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false},
        {false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true},
        {true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false},
        {false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true},
        {true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false},
        {false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true},
        {true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false},
        {false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true},
        {true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false},
        {false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true},
        {true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false},
        {false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true},
        {true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false},
        {false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true},
        {true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false},
        {false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true},
        {true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false},
        {false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true}

    };

    //this is the border i want around my GPanel
    private static final Border GRAPHICS_BORDER = BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10), BorderFactory.createLineBorder(Color.BLACK, 1));

    //this is the size of the colored square inside the border
    private static int dimension = 200;
    private static final int BORDER_WIDTH = 11;

    private JFrame frame;
    private GPanel graphicsPanel;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    MyWindow window = new MyWindow();
                    window.frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public MyWindow() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {

        frame = new JFrame();
        frame.setTitle("Alexander Fisher's Game");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(new GridBagLayout());
        frame.setResizable(false);

        graphicsPanel = new GPanel();
        graphicsPanel.setBorder(MyWindow.GRAPHICS_BORDER);
        graphicsPanel.setPreferredSize(new Dimension(MyWindow.dimension + 2 * MyWindow.BORDER_WIDTH, MyWindow.dimension + 2 * MyWindow.BORDER_WIDTH));
        graphicsPanel.setMinimumSize(new Dimension(MyWindow.dimension + 2 * MyWindow.BORDER_WIDTH, MyWindow.dimension + 2 * MyWindow.BORDER_WIDTH));
        graphicsPanel.setMaximumSize(new Dimension(MyWindow.dimension + 2 * MyWindow.BORDER_WIDTH, MyWindow.dimension + 2 * MyWindow.BORDER_WIDTH));
        frame.add(graphicsPanel);
        frame.pack();

    }

    private class GPanel extends JPanel {
        /**
         * 
         */
        private static final long serialVersionUID = 1L;

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

            int pixelDimension = MyWindow.dimension / MyWindow.screenPixels.length;

            for(int intRowIndex = 0; intRowIndex < MyWindow.screenPixels.length; intRowIndex++) {
                for(int intColumnIndex = 0; intColumnIndex < MyWindow.screenPixels.length; intColumnIndex++) {
                    if(!MyWindow.screenPixels[intRowIndex][intColumnIndex]) {
                        g.setColor(Color.WHITE);
                        g.fillRect(intRowIndex * pixelDimension + MyWindow.BORDER_WIDTH, intColumnIndex * pixelDimension + MyWindow.BORDER_WIDTH, pixelDimension, pixelDimension);
                    } else if(MyWindow.screenPixels[intRowIndex][intColumnIndex]) {
                        g.setColor(Color.BLACK);
                        g.fillRect(intRowIndex * pixelDimension + MyWindow.BORDER_WIDTH, intColumnIndex * pixelDimension + MyWindow.BORDER_WIDTH, pixelDimension, pixelDimension);
                    }
                }
            }


        }
    }

}

1 个答案:

答案 0 :(得分:1)

问题

public void paint(Graphics g) { ...这是您的关键问题

如果你仔细看看Performing Custom Painting

  

javax.swing.JComponent扩展了这个类,并进一步将paint方法分解为三个单独的方法,这些方法按以下顺序调用:

     
      
  • protected void paintComponent(Graphics g)
  •   
  • protected void paintBorder(Graphics g)
  •   
  • protected void paintChildren(Graphics g)
  •   

因此,通过覆盖paint并且无法兑现现有的油漆链,您可以防止绘制边框。

解决方案

根据Performing Custom Painting的建议,您应该覆盖paintComponent(并在执行任何自定义绘画之前调用super.paintComponent