【问题标题】:How can I add a border to a JPanel which is added to a JFrame?如何向添加到 JFrame 的 JPanel 添加边框?
【发布时间】:2018-09-09 02:46:48
【问题描述】:

我有一个 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);
                    }
                }
            }


        }
    }

}

编辑(已解决):

我添加了一行:

 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);
                    }
                }
            }


        }
    }

}

【问题讨论】:

  • 试试graphicspanel.setBorder(BorderFactory.createEmptyBorder(0,10,10,10)); 你应该使用BorderFactory
  • @SteelToe 常量 MyWindow.GRAPHICS_BORDER 是在代码中使用 BorderFactory 定义的。

标签: java swing jpanel border


【解决方案1】:

问题

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

如果你仔细看看Performing Custom Painting

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

  • 受保护的 void 油漆组件(图形 g)
  • 受保护的 void paintBorder(Graphics g)
  • protected void paintChildren(Graphics g)

因此,通过覆盖 paint 并且不遵守现有的绘制链,您可以防止绘制边框。

解决办法

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多