爲了讓您的Swing應用程序按預期工作,您需要記住許多事項。爲避免可能出現的某些障礙,總會有一些步驟必須遵循,因爲您以錯誤的方式編碼。爲此,嚴格遵守Swing編程的基礎知識,並遵循它們。
這樣的循環孔內你的編碼可能會引起許多令人頭疼的問題,當你坐下來編寫大型節目時,最好是從一開始就安全的路上,然後在後期詛咒自己。正如他們所說的預防勝於治療。
由於未能指定CustomComponent
的大小(即JComponent
),因此您無法在屏幕上看到它,現在即將到達您的程序中,您錯過了主要的東西。當您將JCompoent
擴展到您的班級時,請將其設爲習慣性習慣來覆蓋它的getPreferredSize(),方法與覆蓋方法相同。
看看這個我爲你製作的小程序,可能會幫助你理解邏輯。
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.RoundRectangle2D;
import javax.swing.*;
public class CustomPainting {
private RectangleComponent life;
private RectangleComponent death;
private void createAndDisplayGUI() {
JFrame frame = new JFrame("Custom Painting");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel centerPanel = new JPanel();
centerPanel.setLayout(new GridLayout(0, 2, 5, 5));
// Specifying the WIDTH, HEIGHT and Colour for this JComponent.
life = new RectangleComponent(Color.GREEN.darker(), 20, 20);
death = new RectangleComponent(Color.RED.darker(), 20, 20);
centerPanel.add(life);
centerPanel.add(death);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 5));
JButton incLifeButton = new JButton("INCREASE LIFE");
incLifeButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
life.addLife(1);
}
});
JButton decLifeButton = new JButton("DECREASE LIFE");
decLifeButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
life.subtractLife(1);
}
});
JButton incDeathButton = new JButton("INCREASE DEATH");
incDeathButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
death.addLife(1);
}
});
JButton decDeathButton = new JButton("DECREASE DEATH");
decDeathButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
death.subtractLife(1);
}
});
buttonPanel.add(incLifeButton);
buttonPanel.add(decLifeButton);
buttonPanel.add(incDeathButton);
buttonPanel.add(decDeathButton);
frame.getContentPane().add(centerPanel, BorderLayout.CENTER);
frame.getContentPane().add(buttonPanel, BorderLayout.PAGE_END);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String\u005B\u005D args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new CustomPainting().createAndDisplayGUI();
}
});
}
}
class RectangleComponent extends JComponent {
private Color colour;
private static final int MARGIN = 10;
private int width;
private int height;
private int originalWidth;
private RoundRectangle2D roundedRectangle;
public RectangleComponent(Color c, int w, int h) {
colour = c;
width = w;
height = h;
originalWidth = width;
}
/*
* Overriding this method, so that
* the size of the JComponent
* can be determined, on the screen
* or by the LayoutManager concern.
*/
@Override
public Dimension getPreferredSize() {
return (new Dimension(width, height));
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
roundedRectangle = new RoundRectangle2D.Float(MARGIN, MARGIN,
width, height, MARGIN, MARGIN);
g2d.setPaint(colour);
g2d.draw(roundedRectangle);
g2d.fill(roundedRectangle);
}
public void subtractLife(int amount) {
width -= amount;
System.out.println("ORIGINAL Width : " + originalWidth);
System.out.println("Width : " + width);
if (width > 0) {
roundedRectangle.setRoundRect(MARGIN, MARGIN, width, height,
MARGIN, MARGIN);
/*
* This repaint() will call the paintComponent(...)
* by itself, so nothing else to be done.
*/
repaint();
} else {
width += amount;
}
}
public void addLife(int amount) {
width += amount;
System.out.println("ORIGINAL Width : " + originalWidth);
System.out.println("Width : " + width);
if (width < originalWidth) {
roundedRectangle.setRoundRect(MARGIN, MARGIN, width, height,
MARGIN, MARGIN);
repaint();
} else {
width -= amount;
}
}
}
可能會問任何問題,可能會出現,可能與您經過這個程序:-),我很樂意幫助上:-)
**兩種顏色最新編輯:**
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.RoundRectangle2D;
import javax.swing.*;
public class CustomPainting {
private RectangleComponent lifeDeath;
private void createAndDisplayGUI() {
JFrame frame = new JFrame("Custom Painting");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel centerPanel = new JPanel();
centerPanel.setLayout(new GridLayout(0, 2, 5, 5));
// Specifying the WIDTH, HEIGHT and Colour for this JComponent.
lifeDeath = new RectangleComponent(Color.GREEN, Color.RED, 20, 20);
centerPanel.add(lifeDeath);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new GridLayout(1, 2, 5, 5));
JButton incLifeButton = new JButton("INCREASE LIFE");
incLifeButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
lifeDeath.addLife(1);
}
});
JButton decLifeButton = new JButton("DECREASE LIFE");
decLifeButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
lifeDeath.subtractLife(1);
}
});
buttonPanel.add(incLifeButton);
buttonPanel.add(decLifeButton);
frame.getContentPane().add(centerPanel, BorderLayout.CENTER);
frame.getContentPane().add(buttonPanel, BorderLayout.PAGE_END);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String\u005B\u005D args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new CustomPainting().createAndDisplayGUI();
}
});
}
}
class RectangleComponent extends JComponent {
private Color lifeColour;
private Color deathColour;
private static final int MARGIN = 10;
private int widthLife;
private int widthDeath;
private int height;
private int originalWidth;
private RoundRectangle2D roundedRectangle;
public RectangleComponent(Color lc, Color dc, int w, int h) {
lifeColour = lc;
deathColour = dc;
widthLife = w;
height = h;
originalWidth = widthLife;
widthDeath = 0;
}
/*
* Overriding this method, so that
* the size of the JComponent
* can be determined, on the screen
* or by the LayoutManager concern.
*/
@Override
public Dimension getPreferredSize() {
return (new Dimension(originalWidth, height));
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
roundedRectangle = new RoundRectangle2D.Float((MARGIN + widthDeath), MARGIN,
widthLife, height, MARGIN, MARGIN);
g2d.setPaint(lifeColour);
g2d.draw(roundedRectangle);
g2d.fill(roundedRectangle);
roundedRectangle.setRoundRect(MARGIN, MARGIN,
widthDeath, height, MARGIN, MARGIN);
g2d.setPaint(deathColour);
g2d.draw(roundedRectangle);
g2d.fill(roundedRectangle);
}
public void subtractLife(int amount) {
widthLife -= amount;
widthDeath += amount;
System.out.println("ORIGINAL Width : " + originalWidth);
System.out.println("Width Life : " + widthLife);
System.out.println("Width Death : " + widthDeath);
if (widthLife > 0 && widthDeath < originalWidth) {
/*
* This repaint() will call the paintComponent(...)
* by itself, so nothing else to be done.
*/
repaint();
} else {
widthLife += amount;
widthDeath -= amount;
}
}
public void addLife(int amount) {
widthLife += amount;
widthDeath -= amount;
System.out.println("ORIGINAL Width : " + originalWidth);
System.out.println("Width Life : " + widthLife);
System.out.println("Width Death : " + widthDeath);
if (widthLife < originalWidth && widthDeath > 0) {
repaint();
} else {
widthLife -= amount;
widthDeath += amount;
}
}
}
你可以顯示你實際將RectangleComponent添加到任何東西的位置,因爲我在上面的文章中看不到這段代碼嗎?另外,你不應該直接調用'paintComponent(...)'或者'paint(...)。你可以在組件或容器層次結構中的容器上調用repaint(),這會建議JVM開始一個繪製週期,但是你不要直接自己做。 – 2012-04-20 02:36:34
@HovercraftFullOfEels - 在'GameFrame'構造函數調用的'createPanels()'中添加RectangleComponent字段'life'和'death'。它們在'createHealth()'中創建,從'createPanels()' – 2012-04-20 03:10:41