[英]How can I add a border to a JPanel which is added to a JFrame?
我有一個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);
}
}
}
}
}
}
public void paint(Graphics g) {
...這是您的關鍵問題
如果您仔細查看執行自定義繪畫
javax.swing.JComponent
擴展了此類,並進一步將paint方法分解為三個單獨的方法,並按以下順序調用:
- 受保護的void paintComponent(Graphics g)
- 受保護的void paintBorder(Graphics g)
- 受保護的void paintChildren(圖形g)
因此,通過覆蓋paint
並且不遵守現有的油漆鏈,可以防止對邊界進行油漆。
根據執行自定義繪畫的建議,您應該改寫paintComponent
(並在執行任何自定義繪畫之前調用super.paintComponent
)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.