Contenuto dipinto invisibile durante il ridimensionamento in Java

Si prega di notare che non ho provato questo su una macchina Windows solo su un Mac-machine. Non sono sicuro che ciò avvenga anche su una macchina Windows …

Quando ridimensiono la mia applicazione Java il contenuto è invisibile. Ho già trovato un modo per risolverlo dopo averlo ridimensionato, ma non mentre l’utente sta ridimensionando la finestra.

Non sto usando Swing o qualcosa del genere perché rende il mio binario così lento (secondo me).

La struttura è così:

  • Frame mia finestra principale
    • Containe r Visualizzazione del contenuto della main-window
      • Viste secondarie basate su container che includono il metodo paint(Graphics g)

Ho aggiunto tutti gli ascoltatori alla My main-window e ora sono in grado di ridisegnare la vista del contenuto dopo aver ridimensionato la finestra.

 public void componentResized(ComponentEvent e) { this.contentView.paint(this.contentView.getGraphics()); } 

Sono attento al fatto che usare paint(getGraphics()) -method non è un buon modo per farlo, ma dal momento che il repaint repaint() -method non fa nulla, è l’unica possibilità di lavoro.

Durante il ridimensionamento, tutto il contenuto dipinto diventa invisibile. Tuttavia, quando aggiungo un’istanza Button alla mia Content-view e ridimensiono la mia Main-window , il pulsante non diventa invisibile.

Sono in grado di rintracciare l’evento “live”:

 public void componentMoved(ComponentEvent e) { System.out.println("Live-resize"); } 
  1. Quando inizio a ridimensionare questo metodo non viene chiamato.
  2. Durante il ridimensionamento genera “Live-ridimensiona” nel mio log ogni singolo pixel ridimensiono la finestra.
  3. Quando smetto di ridimensionare questo metodo non viene chiamato, il metodo componentResized fa.

Quando aggiungo il mio metodo repaint (o il metodo repaint ufficiale) all’evento di ridimensionamento “live” come questo, ottengo comunque l’output, tuttavia non è ridipingere o qualcosa

 public void componentMoved(ComponentEvent e) { System.out.println("Live-resize"); this.contentView.paint(this.contentView.getGraphics()); } 

O

 public void componentMoved(ComponentEvent e) { System.out.println("Live-resize"); this.contentView.repaint(); } 

Quando minimizzo la mia applicazione sul dock e ottimizzo nuovamente l’applicazione, accade la stessa cosa, suppongo che sia necessario lo stesso codice per risolvere il problema.

Non sto usando Graphics2D o qualcosa del genere, solo Graphics .

Potresti spiegarmi come posso ridipingere i punti di vista?

Grazie in anticipo, Tim

Per riferimento, ecco lo stesso programma che usa Swing. Poiché JPanel doppio buffer, non sfarfalla quando il mouse viene rilasciato dopo il ridimensionamento.

 import java.awt.*; import java.awt.event.*; import java.util.Random; import javax.swing.*; public class SwingPaint { public static void main(String[] args) { JFrame frame = new JFrame(); frame.add(new CirclePanel()); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setVisible(true); } private static class CirclePanel extends JPanel { private static final Random r = new Random(); public CirclePanel() { this.setPreferredSize(new Dimension(320, 240)); this.setForeground(new Color(r.nextInt())); this.addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { CirclePanel.this.update(); } }); } public void update() { this.setForeground(new Color(r.nextInt())); } @Override public void paintComponent(Graphics g) { super.paintComponent(g); Dimension size = this.getSize(); int d = Math.min(size.width, size.height) - 10; int x = (size.width - d) / 2; int y = (size.height - d) / 2; g.fillOval(x, y, d, d); g.setColor(Color.blue); g.drawOval(x, y, d, d); } } } 

Ho più familiarità con Swing, ma l’articolo Painting in AWT e Swing distingue tra pittura triggersta dal sistema e dall’applicazione. L’esempio seguente mostra come il sistema richiama paint() mentre la finestra viene ridimensionata, mentre l’applicazione richiama repaint() , che chiama update() , in risposta a un evento del mouse. Il comportamento è multipiattaforma.

 import java.awt.*; import java.awt.event.*; import java.util.Random; public class AWTPaint { public static void main(String[] args) { Frame frame = new Frame(); frame.add(new CirclePanel()); frame.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.pack(); frame.setVisible(true); } private static class CirclePanel extends Panel { private static final Random r = new Random(); public CirclePanel() { this.setPreferredSize(new Dimension(320, 240)); this.setForeground(new Color(r.nextInt())); this.addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { CirclePanel.this.repaint(); } }); } @Override public void update(Graphics g) { this.setForeground(new Color(r.nextInt())); } @Override public void paint(Graphics g) { Dimension size = this.getSize(); int d = Math.min(size.width, size.height) - 10; int x = (size.width - d) / 2; int y = (size.height - d) / 2; g.fillOval(x, y, d, d); g.setColor(Color.blue); g.drawOval(x, y, d, d); } } } 

Ok, finalmente l’ho risolto.

Invece di ridisegnarlo ogni volta nel paint(Graphics g) -method, è necessario bufferizzare l’output e solo ridisegnare quell’immagine (speravo che Java lo stesse già facendo, proprio come Obj-C).

 public BufferedImage buffer; public void redraw() { buffer = new BufferedImage( 200, // height 300, // width BufferedImage.TYPE_4BYTE_ABGR); // ABGR = RGBA, 4-byte (r, g, b, a) per pixel Graphics g = buffer.getGraphics(); // do your drawing here if (this.getGraphics()) { // 'this' is already shown, so it needs a redraw this.paint(this.getGraphics()); // little hack } } public void update(Graphics g) { this.paint(g); } public void paint(Graphics g) { g.drawImage(buffer, 0, 0, this); } 

Ora, quando si riduce a icona la finestra e si massimizza di nuovo, i dipinti rimangono. Solo che la finestra sfarfalla ora per 0,1 secondi o giù di lì, ma non mi interessa davvero.