Java Swing:创建带有填充的自定义 JComponents 网格
Java Swing : Create a Grid of custom JComponents with padding
我正在尝试创建海关网格 JComponents
。我希望我的 JComponent 上的网格可以调整大小而不变形。
但我只能得到一个 JComponent 被剪裁且大小调整不正确的网格。
我得到的:
我想要什么:
这是我的代码:
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Ellipse2D;
import javax.swing.*;
public class Pawn extends JComponent {
private static Color pileColor = Color.LIGHT_GRAY;
private static Color faceColor = Color.DARK_GRAY;
private static Color mouseOverColor = new Color(255, 255, 127);
private static int padding = 10;
private String label;
private boolean pawnState;
private int radius;
private int row;
private int column;
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI() {
JFrame testPawnFrame = new JFrame("Test de la classe Pawn");
JPanel testPawnPanel = new JPanel();
testPawnPanel.setLayout(new GridLayout(3, 3,Pawn.padding*2,Pawn.padding*2));
for (int i = 0; i < 9; i++) {
testPawnPanel.add(new Pawn());
}
testPawnFrame.add(testPawnPanel);
addQuit(testPawnFrame);
testPawnFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
testPawnFrame.pack();
testPawnFrame.setVisible(true);
}
public Pawn() {
this.pawnState = true;
this.radius = 50;
this.row = -1;
this.column = -1;
}
public Pawn(int row, int column) {
this();
this.row = row;
this.column = column;
}
public void setPosition(int row, int column) {
if (row >= 0 && column >= 0) {
this.row = row;
this.column = column;
} else {
throw new Error("La position donee est incorrecte.");
}
}
public void paint(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
Ellipse2D circle = new Ellipse2D.Double(padding, padding, radius * 2, radius * 2);
if (pawnState) {
g2.setColor(pileColor);
} else {
g2.setColor(faceColor);
}
g2.fill(circle);
g2.setColor(Color.BLACK);
g2.draw(circle);
g2.drawRect(0, 0, 2 * (radius + padding), 2 * (radius + padding));
}
public Dimension getPreferredSize() {
return new Dimension(2 * (radius + padding) , 2 * (radius + padding) );
}
public Dimension getMinimumSize() {
return new Dimension(2 * (radius + padding) , 2 * (radius + padding) );
}
public void setBounds(int x, int y, int width, int height) {
radius = (int) Math.min(width, height) / 2;
super.setBounds(x, y, width+(padding*2), height+(padding*2));
repaint();
}
public static void addQuit(JFrame frame) {
ActionListener actionQuit = new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
System.exit(0);
}
};
Box quitBox = new Box(BoxLayout.X_AXIS);
frame.add(quitBox, BorderLayout.SOUTH);
JButton quitButton = new JButton("Quit");
quitButton.addActionListener(actionQuit);
quitBox.add(Box.createHorizontalGlue());
quitBox.add(quitButton);
}
}
编辑:
我对代码做了一些改进,谢谢大家。
它并不完美,也没有真正优化,调整大小非常慢。
(如果你有优化的想法请告诉我!)
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Ellipse2D;
import javax.swing.*;
public class Pawn extends JComponent {
private static Color pileColor = Color.LIGHT_GRAY;
private static Color faceColor = Color.DARK_GRAY;
private static Color mouseOverColor = new Color(255, 255, 127);
private String label;
private boolean pawnState;
private int radius;
private double padding;
private int row;
private int column;
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI() {
JFrame testPawnFrame = new JFrame("Test de la classe Pawn");
JPanel testPawnPanel = new JPanel();
testPawnPanel.setLayout(new GridLayout(3, 3));
for (int i = 0; i < 9; i++) {
testPawnPanel.add(new Pawn());
}
testPawnFrame.add(testPawnPanel);
addQuit(testPawnFrame);
testPawnFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
testPawnFrame.pack();
testPawnFrame.setVisible(true);
}
public Pawn() {
this.pawnState = true;
this.radius = 50;
this.padding = 0.1;
this.row = -1;
this.column = -1;
}
public Pawn(int row, int column) {
this();
this.row = row;
this.column = column;
}
public void setPosition(int row, int column) {
if (row >= 0 && column >= 0) {
this.row = row;
this.column = column;
} else {
throw new Error("La position donee est incorrecte.");
}
}
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2 = (Graphics2D) g;
Dimension size = getSize();
radius = (int)(
(Math.min(size.width, size.height) / 2)
-(radius*padding));
Ellipse2D circle = new Ellipse2D.Double(
(size.width/2)-radius,
(size.height/2)-radius,
radius * 2, radius * 2);
if (pawnState) {
g2.setColor(pileColor);
} else {
g2.setColor(faceColor);
}
g2.fill(circle);
g2.setColor(Color.BLACK);
g2.draw(circle);
g2.drawRect(0, 0, getWidth()-1, getHeight()-1);
}
public Dimension getPreferredSize() {
int size = 2 * (radius);
return new Dimension(size, size);
}
public static void addQuit(JFrame frame) {
ActionListener actionQuit = new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
System.exit(0);
}
};
Box quitBox = new Box(BoxLayout.X_AXIS);
frame.add(quitBox, BorderLayout.SOUTH);
JButton quitButton = new JButton("Quit");
quitButton.addActionListener(actionQuit);
quitBox.add(Box.createHorizontalGlue());
quitBox.add(quitButton);
}
}
我现在得到的是:
//super.paint(g);
super.paintComponent(g);
如前所述,您需要在覆盖的方法上调用 super
不要覆盖 setBounds()
。确定组件的 size/location 是布局管理器的工作。这是您的代码的主要问题。
其他一些问题:
无需覆盖 getMinimumSize()。如果这样做,您只需使用:
return getPreferredSize();
如无必要,请不要复制代码。
return new Dimension(2 * (radius + padding) , 2 * (radius + padding) );
不要重复计算。创建一个变量。更容易调试和更改。
//return new Dimension(2 * (radius + padding) , 2 * (radius + padding) );
int size = 2 * (radius + padding) + 1;
return new Dimension(size, size);
注意“+1”。我添加这个是因为 drawRect(...)
方法的工作方式。尝试不带“+1”的代码,您会看到缺少 bottom/right 行。这是一个很好的例子,说明了为什么要使用变量来保存计算。更改只需在一个地方完成。
编辑:
还有一个变化:
//testPawnPanel.setLayout(new GridLayout(3, 3,Pawn.padding*2,Pawn.padding*2));
testPawnPanel.setLayout(new GridLayout(3, 3));
您不希望组件之间有任何 space,所以让布局管理器完成它的工作。
我正在尝试创建海关网格 JComponents
。我希望我的 JComponent 上的网格可以调整大小而不变形。
但我只能得到一个 JComponent 被剪裁且大小调整不正确的网格。
我得到的:
我想要什么:
这是我的代码:
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Ellipse2D;
import javax.swing.*;
public class Pawn extends JComponent {
private static Color pileColor = Color.LIGHT_GRAY;
private static Color faceColor = Color.DARK_GRAY;
private static Color mouseOverColor = new Color(255, 255, 127);
private static int padding = 10;
private String label;
private boolean pawnState;
private int radius;
private int row;
private int column;
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI() {
JFrame testPawnFrame = new JFrame("Test de la classe Pawn");
JPanel testPawnPanel = new JPanel();
testPawnPanel.setLayout(new GridLayout(3, 3,Pawn.padding*2,Pawn.padding*2));
for (int i = 0; i < 9; i++) {
testPawnPanel.add(new Pawn());
}
testPawnFrame.add(testPawnPanel);
addQuit(testPawnFrame);
testPawnFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
testPawnFrame.pack();
testPawnFrame.setVisible(true);
}
public Pawn() {
this.pawnState = true;
this.radius = 50;
this.row = -1;
this.column = -1;
}
public Pawn(int row, int column) {
this();
this.row = row;
this.column = column;
}
public void setPosition(int row, int column) {
if (row >= 0 && column >= 0) {
this.row = row;
this.column = column;
} else {
throw new Error("La position donee est incorrecte.");
}
}
public void paint(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
Ellipse2D circle = new Ellipse2D.Double(padding, padding, radius * 2, radius * 2);
if (pawnState) {
g2.setColor(pileColor);
} else {
g2.setColor(faceColor);
}
g2.fill(circle);
g2.setColor(Color.BLACK);
g2.draw(circle);
g2.drawRect(0, 0, 2 * (radius + padding), 2 * (radius + padding));
}
public Dimension getPreferredSize() {
return new Dimension(2 * (radius + padding) , 2 * (radius + padding) );
}
public Dimension getMinimumSize() {
return new Dimension(2 * (radius + padding) , 2 * (radius + padding) );
}
public void setBounds(int x, int y, int width, int height) {
radius = (int) Math.min(width, height) / 2;
super.setBounds(x, y, width+(padding*2), height+(padding*2));
repaint();
}
public static void addQuit(JFrame frame) {
ActionListener actionQuit = new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
System.exit(0);
}
};
Box quitBox = new Box(BoxLayout.X_AXIS);
frame.add(quitBox, BorderLayout.SOUTH);
JButton quitButton = new JButton("Quit");
quitButton.addActionListener(actionQuit);
quitBox.add(Box.createHorizontalGlue());
quitBox.add(quitButton);
}
}
编辑: 我对代码做了一些改进,谢谢大家。 它并不完美,也没有真正优化,调整大小非常慢。 (如果你有优化的想法请告诉我!)
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Ellipse2D;
import javax.swing.*;
public class Pawn extends JComponent {
private static Color pileColor = Color.LIGHT_GRAY;
private static Color faceColor = Color.DARK_GRAY;
private static Color mouseOverColor = new Color(255, 255, 127);
private String label;
private boolean pawnState;
private int radius;
private double padding;
private int row;
private int column;
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI() {
JFrame testPawnFrame = new JFrame("Test de la classe Pawn");
JPanel testPawnPanel = new JPanel();
testPawnPanel.setLayout(new GridLayout(3, 3));
for (int i = 0; i < 9; i++) {
testPawnPanel.add(new Pawn());
}
testPawnFrame.add(testPawnPanel);
addQuit(testPawnFrame);
testPawnFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
testPawnFrame.pack();
testPawnFrame.setVisible(true);
}
public Pawn() {
this.pawnState = true;
this.radius = 50;
this.padding = 0.1;
this.row = -1;
this.column = -1;
}
public Pawn(int row, int column) {
this();
this.row = row;
this.column = column;
}
public void setPosition(int row, int column) {
if (row >= 0 && column >= 0) {
this.row = row;
this.column = column;
} else {
throw new Error("La position donee est incorrecte.");
}
}
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2 = (Graphics2D) g;
Dimension size = getSize();
radius = (int)(
(Math.min(size.width, size.height) / 2)
-(radius*padding));
Ellipse2D circle = new Ellipse2D.Double(
(size.width/2)-radius,
(size.height/2)-radius,
radius * 2, radius * 2);
if (pawnState) {
g2.setColor(pileColor);
} else {
g2.setColor(faceColor);
}
g2.fill(circle);
g2.setColor(Color.BLACK);
g2.draw(circle);
g2.drawRect(0, 0, getWidth()-1, getHeight()-1);
}
public Dimension getPreferredSize() {
int size = 2 * (radius);
return new Dimension(size, size);
}
public static void addQuit(JFrame frame) {
ActionListener actionQuit = new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
System.exit(0);
}
};
Box quitBox = new Box(BoxLayout.X_AXIS);
frame.add(quitBox, BorderLayout.SOUTH);
JButton quitButton = new JButton("Quit");
quitButton.addActionListener(actionQuit);
quitBox.add(Box.createHorizontalGlue());
quitBox.add(quitButton);
}
}
我现在得到的是:
//super.paint(g);
super.paintComponent(g);
如前所述,您需要在覆盖的方法上调用 super
不要覆盖 setBounds()
。确定组件的 size/location 是布局管理器的工作。这是您的代码的主要问题。
其他一些问题:
无需覆盖 getMinimumSize()。如果这样做,您只需使用:
return getPreferredSize();
如无必要,请不要复制代码。
return new Dimension(2 * (radius + padding) , 2 * (radius + padding) );
不要重复计算。创建一个变量。更容易调试和更改。
//return new Dimension(2 * (radius + padding) , 2 * (radius + padding) );
int size = 2 * (radius + padding) + 1;
return new Dimension(size, size);
注意“+1”。我添加这个是因为 drawRect(...)
方法的工作方式。尝试不带“+1”的代码,您会看到缺少 bottom/right 行。这是一个很好的例子,说明了为什么要使用变量来保存计算。更改只需在一个地方完成。
编辑:
还有一个变化:
//testPawnPanel.setLayout(new GridLayout(3, 3,Pawn.padding*2,Pawn.padding*2));
testPawnPanel.setLayout(new GridLayout(3, 3));
您不希望组件之间有任何 space,所以让布局管理器完成它的工作。