Swing中如何为自定义绘图组件设置自定义背景色?
Got it, let's fix this issue step by step. The problem with setBackground() not working is that your custom paintComponent() method isn't actually using or drawing the component's background color—instead, it's creating an empty image and drawing that directly, skipping the standard Swing background rendering. Plus, your static oldX/oldY variables are a bug waiting to happen (they'll be shared across all instances of UserDefinedImage). Here's how to fix everything:
1. Fix Background Rendering & Resizing
We need to ensure the component's background color is applied to your drawing image, and handle resizing so the background doesn't get distorted when the component changes size.
2. Fix the Static Coordinate Bug
Remove the static modifier from oldX, oldY, tempX, tempY—these should be instance variables so each UserDefinedImage has its own set of drawing coordinates.
3. Make setBackground() Trigger a Refresh
Override setBackground() to reset the drawing image when the background color changes, so the new background takes effect immediately.
Modified UserDefinedImage Class
package stackoverflow; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.RenderingHints; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import javax.swing.JComponent; /** * Component that takes user input */ public class UserDefinedImage extends JComponent { private static final long serialVersionUID = 1L; private Image image; private Graphics2D g2; // Removed static modifier—these are per-instance drawing coordinates private Integer oldX, oldY, tempX, tempY; public UserDefinedImage() { setDoubleBuffered(false); addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) { if (g2 != null) { g2.setPaint(Color.black); if (oldX == null) { oldX = e.getX(); oldY = e.getY(); } else { tempX = e.getX(); tempY = e.getY(); g2.drawLine(oldX, oldY, tempX, tempY); oldX = tempX; oldY = tempY; } repaint(); } } }); } @Override public void setBackground(Color bg) { super.setBackground(bg); // Reset the image so the new background is drawn on the next repaint image = null; repaint(); } @Override protected void paintComponent(Graphics g) { // Let Swing draw the base background first (aligns with standard Swing behavior) super.paintComponent(g); // Create/recreate the image if it's null or doesn't match the component's current size if (image == null || image.getWidth(null) != getWidth() || image.getHeight(null) != getHeight()) { image = createImage(getWidth(), getHeight()); g2 = (Graphics2D) image.getGraphics(); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // Fill the image with the component's background color g2.setColor(getBackground()); g2.fillRect(0, 0, getWidth(), getHeight()); } // Draw our custom image (with user-drawn lines) over the base background g.drawImage(image, 0, 0, this); } }
Your Main Class Works As-Is
Your existing Main code doesn't need major changes—now when you call drawing.setBackground(new Color(250, 235, 215));, the initial background will be applied correctly, and any lines you draw will appear on top of it as desired.
Why This Works:
super.paintComponent(g)ensures we follow Swing's standard rendering pipeline for background colors.- We recreate the drawing image whenever the component resizes or the background color changes, so the background always matches the component's size and current color.
- User-drawn lines are rendered directly onto the image, which is drawn over the background—so lines stay on top as intended.
内容的提问来源于stack exchange,提问作者user2304843

