删除 GridBagLayout 中按钮周围的 space
Removing space around buttons in GridBagLayout
我编写了这个令人烦恼的源代码来演示 another question 中提到的游戏屏幕的布局。它将按钮(或标签,在启动时可选择)放入 GridBagLayout
。
如果您在出现提示时(在 GUI 出现之前)选择不使用按钮,则整个 GUI 非常漂亮且紧凑,没有间隙。但是如果你选择使用按钮,它会(如果你的设置像我的一样)看起来像这样..
注意红色的水平线。那是透过的面板的BG颜色。当 GUI 使用标签时,看不到这些行。稍微拉伸一下 GUI,可以看到它甚至没有在每一行之后放一条红线(共有九行)——尽管每一行都使用按钮(相同的组件)。
如何在使用按钮时删除多余的垂直space?
我想这一定是我在配置按钮或行宽时忘记做的事情,但我不知道是什么!
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import java.net.URL;
import javax.imageio.ImageIO;
public class SoccerField {
private JPanel ui = null;
int[] x = {0, 35, 70, 107, 142, 177, 212, 247, 282, 315};
int[] y = {0, 45, 85, 140, 180, 225, 265, 280, 320, 345};
boolean buttons;
SoccerField() {
initUI();
}
public void initUI() {
int result = JOptionPane.showConfirmDialog(ui, "Use buttons?");
buttons = result == JOptionPane.OK_OPTION;
if (ui != null) {
return;
}
ui = new JPanel(new GridBagLayout());
ui.setBackground(Color.RED);
try {
URL url = new URL("http://i.stack.imgur.com/9E5ky.jpg");
BufferedImage img = ImageIO.read(url);
BufferedImage field = img.getSubimage(100, 350, 315, 345);
BufferedImage[] bi = subSampleImageColumns(field);
BufferedImage[][] fieldParts = new BufferedImage[bi.length][];
for (int ii=0; ii<bi.length; ii++) {
fieldParts[ii] = subSampleImageRows(bi[ii]);
}
for (int ii=0; ii<fieldParts[0].length; ii++) {
for (int jj=0; jj<fieldParts.length; jj++) {
addImageToPanel(ui, fieldParts[ii][jj], ii, jj);
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
private void addImageToPanel(JPanel panel, BufferedImage img, int row, int col) {
Insets insets = new Insets(0,0,0,0);
GridBagConstraints gbc = new GridBagConstraints(
row, col,
1, 1,
.5, .5,
GridBagConstraints.CENTER,
GridBagConstraints.BOTH,
insets, 0, 0);
ImageIcon ii = new ImageIcon(img);
JButton b = new JButton(ii);
b.setBorder(null);
b.setBorderPainted(false);
b.setContentAreaFilled(false);
Component c = buttons ? b : new JLabel(ii);
panel.add(c, gbc);
}
private BufferedImage[] subSampleImageColumns(BufferedImage img) {
System.out.println("Image Size: " + img.getWidth() + "," + img.getHeight());
BufferedImage[] imageRows = new BufferedImage[x.length - 1];
for (int ii = 0; ii < x.length - 1; ii++) {
BufferedImage bi = img.getSubimage(
x[ii], 0, x[ii + 1] - x[ii], img.getHeight());
imageRows[ii] = bi;
}
return imageRows;
}
private BufferedImage[] subSampleImageRows(BufferedImage img) {
BufferedImage[] imageRows = new BufferedImage[y.length - 1];
for (int ii = 0; ii < y.length - 1; ii++) {
BufferedImage bi = img.getSubimage(
0, y[ii], img.getWidth(), y[ii + 1] - y[ii]);
imageRows[ii] = bi;
}
return imageRows;
}
public JComponent getUI() {
return ui;
}
public static void main(String[] args) {
Runnable r = new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception useDefault) {
}
SoccerField o = new SoccerField();
JFrame f = new JFrame(o.getClass().getSimpleName());
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(o.getUI());
f.pack();
//f.setMinimumSize(f.getSize());
f.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
}
注意到按钮的首选高度似乎没有为按钮正确计算(在某些情况下)。
在标签高度为 40 的情况下,按钮的高度为 41。
好像按钮总是调整为奇数?
我修改了代码:
//int[] y = {0, 45, 85, 140, 180, 225, 265, 280, 320, 345};
int[] y = {0, 45, 86, 139, 180, 225, 266, 279, 320, 345};
它似乎有效。
啊,找到原因了。您还需要:
b.setFocusPainted(false);
我编写了这个令人烦恼的源代码来演示 another question 中提到的游戏屏幕的布局。它将按钮(或标签,在启动时可选择)放入 GridBagLayout
。
如果您在出现提示时(在 GUI 出现之前)选择不使用按钮,则整个 GUI 非常漂亮且紧凑,没有间隙。但是如果你选择使用按钮,它会(如果你的设置像我的一样)看起来像这样..
注意红色的水平线。那是透过的面板的BG颜色。当 GUI 使用标签时,看不到这些行。稍微拉伸一下 GUI,可以看到它甚至没有在每一行之后放一条红线(共有九行)——尽管每一行都使用按钮(相同的组件)。
如何在使用按钮时删除多余的垂直space?
我想这一定是我在配置按钮或行宽时忘记做的事情,但我不知道是什么!
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import java.net.URL;
import javax.imageio.ImageIO;
public class SoccerField {
private JPanel ui = null;
int[] x = {0, 35, 70, 107, 142, 177, 212, 247, 282, 315};
int[] y = {0, 45, 85, 140, 180, 225, 265, 280, 320, 345};
boolean buttons;
SoccerField() {
initUI();
}
public void initUI() {
int result = JOptionPane.showConfirmDialog(ui, "Use buttons?");
buttons = result == JOptionPane.OK_OPTION;
if (ui != null) {
return;
}
ui = new JPanel(new GridBagLayout());
ui.setBackground(Color.RED);
try {
URL url = new URL("http://i.stack.imgur.com/9E5ky.jpg");
BufferedImage img = ImageIO.read(url);
BufferedImage field = img.getSubimage(100, 350, 315, 345);
BufferedImage[] bi = subSampleImageColumns(field);
BufferedImage[][] fieldParts = new BufferedImage[bi.length][];
for (int ii=0; ii<bi.length; ii++) {
fieldParts[ii] = subSampleImageRows(bi[ii]);
}
for (int ii=0; ii<fieldParts[0].length; ii++) {
for (int jj=0; jj<fieldParts.length; jj++) {
addImageToPanel(ui, fieldParts[ii][jj], ii, jj);
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
private void addImageToPanel(JPanel panel, BufferedImage img, int row, int col) {
Insets insets = new Insets(0,0,0,0);
GridBagConstraints gbc = new GridBagConstraints(
row, col,
1, 1,
.5, .5,
GridBagConstraints.CENTER,
GridBagConstraints.BOTH,
insets, 0, 0);
ImageIcon ii = new ImageIcon(img);
JButton b = new JButton(ii);
b.setBorder(null);
b.setBorderPainted(false);
b.setContentAreaFilled(false);
Component c = buttons ? b : new JLabel(ii);
panel.add(c, gbc);
}
private BufferedImage[] subSampleImageColumns(BufferedImage img) {
System.out.println("Image Size: " + img.getWidth() + "," + img.getHeight());
BufferedImage[] imageRows = new BufferedImage[x.length - 1];
for (int ii = 0; ii < x.length - 1; ii++) {
BufferedImage bi = img.getSubimage(
x[ii], 0, x[ii + 1] - x[ii], img.getHeight());
imageRows[ii] = bi;
}
return imageRows;
}
private BufferedImage[] subSampleImageRows(BufferedImage img) {
BufferedImage[] imageRows = new BufferedImage[y.length - 1];
for (int ii = 0; ii < y.length - 1; ii++) {
BufferedImage bi = img.getSubimage(
0, y[ii], img.getWidth(), y[ii + 1] - y[ii]);
imageRows[ii] = bi;
}
return imageRows;
}
public JComponent getUI() {
return ui;
}
public static void main(String[] args) {
Runnable r = new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception useDefault) {
}
SoccerField o = new SoccerField();
JFrame f = new JFrame(o.getClass().getSimpleName());
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(o.getUI());
f.pack();
//f.setMinimumSize(f.getSize());
f.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
}
注意到按钮的首选高度似乎没有为按钮正确计算(在某些情况下)。
在标签高度为 40 的情况下,按钮的高度为 41。
好像按钮总是调整为奇数?
我修改了代码:
//int[] y = {0, 45, 85, 140, 180, 225, 265, 280, 320, 345};
int[] y = {0, 45, 86, 139, 180, 225, 266, 279, 320, 345};
它似乎有效。
啊,找到原因了。您还需要:
b.setFocusPainted(false);