我试图创建一个海关网格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);
}
}
我现在得到的东西:
答案 0 :(得分:3)
//super.paint(g);
super.paintComponent(g);
如前所述,您需要在覆盖
的方法上调用super
不要覆盖setBounds()
。布局管理器的工作是确定组件的大小/位置。这是您的代码的主要问题。
其他一些问题:
无需覆盖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);
注意&#34; + 1&#34;。我添加了这个,因为drawRect(...)
方法的工作方式。尝试没有&#34; + 1&#34;的代码你会看到缺少底线/右线。这是使用变量进行计算的一个完美示例。改变只需要在一个地方完成。
编辑:
还有一个变化:
//testPawnPanel.setLayout(new GridLayout(3, 3,Pawn.padding*2,Pawn.padding*2));
testPawnPanel.setLayout(new GridLayout(3, 3));
您不希望组件之间有任何空间,因此请让布局管理员完成其工作。