Sto cercando di creare un semplice strumento di disegno. Gli eventi mouseDrag
creano una nuova ellisse e causa il repaint()
mio JPanel
repaint()
.
Questo funziona bene finora. Tuttavia, se premo un pulsante qualsiasi (o qualsiasi altro componente dell’interfaccia utente) prima di mouseDrag
evento mouseDrag
per la prima volta, il pulsante viene dipinto nell’angolo in alto a sinistra del mio pannello.
Ho isolato il codice in questa applicazione di test:
import java.awt.BasicStroke; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; public class Test extends JFrame { public Test() { final JPanel paintPanel = new JPanel(){ @Override protected void paintComponent(Graphics g) { Graphics2D g2d = (Graphics2D)g; g2d.setPaintMode(); g2d.setStroke(new BasicStroke(1)); g2d.fillRect(100, 100, 10, 10); } }; paintPanel.setPreferredSize(new Dimension(300,300)); paintPanel.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { paintPanel.repaint(); } }); this.setLayout(new FlowLayout()); this.add(paintPanel); this.add(new JButton("Dummy")); this.pack(); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setVisible(true); } public static void main(String... args) { new Test(); } }
Uno screenshot per “vedere” il problema nella mia applicazione principale
+1 alle risposte @ MadProgrammer.
super.paintComponent(..)
come prima chiamata nel tuo overriden paintComponent()
JFrame
inutilmente setPrefferedSize()
piuttosto sovrascrivere getPrefferedSize()
Ecco un esempio che incorpora i miei consigli e @ MadProgrammer:
import java.awt.BasicStroke; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.ArrayList; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.SwingUtilities; public class Test { JFrame frame; public Test() { frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); final PaintPanel paintPanel = new PaintPanel(); paintPanel.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { paintPanel.addRect(e.getX(), e.getY()); } }); frame.setLayout(new FlowLayout()); frame.add(paintPanel); frame.add(new JButton("Dummy")); frame.pack(); frame.setVisible(true); } public static void main(String... args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new Test(); } }); } } class PaintPanel extends JPanel { public PaintPanel() { addRect(100, 100); } ArrayList rects = new ArrayList<>(); @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g; g2d.setPaintMode(); for (Rectangle r : rects) { g2d.setStroke(new BasicStroke(1)); g2d.fillRect(rx, ry, r.width, r.height); } } public void addRect(int x, int y) { rects.add(new Rectangle(x, y, 10, 10)); repaint(); } @Override public Dimension getPreferredSize() { return new Dimension(300, 300); } }
Non stai chiamando super.paintComponent
.
Il contesto grafico utilizzato per un ciclo pittorico è condiviso tra tutti i componenti che iniziano a dipingere, questo significa che se non si cura di eliminarlo prima di dipingere, si finirà con ciò che è stato dipinto prima di te.
Uno dei compiti di paintComponent
è quello di preparare la grafica per la pittura