Swing / JFrame vs AWT / Frame for rendering outside of EDT

What are the fundamental differences between using an AWT frame and a Swing JFrame when implementing native rendering, rather than using standard Java GUI components?

This is the previous question:

AWT Custom Rendering - Captures smooth resizing and eliminates flicker

Typical conversation points in Swing vs AWT do not seem to apply, because we only use frames. For example, heavy versus light weight will exit the window (and the JFrame expands the frame).

So what is the best, JFrame or Frame for this situation ? Does that make sense?

Note: this scenario is where rendering in the EDT is not desirable . There is an application workflow that is not EDT related, and rendering is performed as needed outside of the EDT. Rendering synchronization with EDT will add latency to rendering. We do not show any Swing or AWT components other than Frame or JFrame (or the included JPanel / Component / etc, if that is better).

import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Insets; import java.awt.Toolkit; import java.awt.image.BufferStrategy; import java.awt.Frame; public class SmoothResize extends Frame { public static void main(String[] args) { Toolkit.getDefaultToolkit().setDynamicLayout(true); System.setProperty("sun.awt.noerasebackground", "true"); SmoothResize srtest = new SmoothResize(); //srtest.setIgnoreRepaint(true); srtest.setSize(100, 100); srtest.setVisible(true); } public SmoothResize() { render(); } private Dimension old_size = new Dimension(0, 0); private Dimension new_size = new Dimension(0, 0); public void validate() { super.validate(); new_size.width = getWidth(); new_size.height = getHeight(); if (old_size.equals(new_size)) { return; } else { render(); } } public void paint(Graphics g) { validate(); } public void update(Graphics g) { paint(g); } public void addNotify() { super.addNotify(); createBufferStrategy(2); } protected synchronized void render() { BufferStrategy strategy = getBufferStrategy(); if (strategy == null) { return; } // Render single frame do { // The following loop ensures that the contents of the drawing buffer // are consistent in case the underlying surface was recreated do { Graphics draw = strategy.getDrawGraphics(); Insets i = getInsets(); int w = (int)(((double)(getWidth() - i.left - i.right))/2+0.5); int h = (int)(((double)(getHeight() - i.top - i.bottom))/2+0.5); draw.setColor(Color.YELLOW); draw.fillRect(i.left, i.top + h, w,h); draw.fillRect(i.left + w, i.top, w,h); draw.setColor(Color.BLACK); draw.fillRect(i.left, i.top, w, h); draw.fillRect(i.left + w, i.top + h, w,h); draw.dispose(); // Repeat the rendering if the drawing buffer contents // were restored } while (strategy.contentsRestored()); // Display the buffer strategy.show(); // Repeat the rendering if the drawing buffer was lost } while (strategy.contentsLost()); } } 
+6
source share
2 answers

Extending to @camickr's answer , the "missing detail" is the JRootPane that manages the contentPane . Note that for JFrame " add and its remove and setLayout options have been redefined to go to contentPane if necessary." JRootPane#createContentPane() "creates a new JComponent a [n] d sets a BorderLayout as its LayoutManager ." As an implementation detail, JComponent is new JPanel() . This has several implications for the contentPane of JFrame :

  • By default, contentPane uses a double buffer by default.
  • contentPane has a BorderLayout , although JPanel usually defaults to FlowLayout .
  • contentPane has an L&F-specific UI delegate, usually derived from the PanelUI , which can affect the appearance and geometry.
+2
source

Swing is double buffered by default, so usually you only need to focus on your picture.

Here is the version of Swing:

 import java.awt.*; import javax.swing.*; public class SwingResize extends JPanel { protected void paintComponent(Graphics g) { int w = (int)(((double)(getWidth()))/2+0.5); int h = (int)(((double)(getHeight()))/2+0.5); g.setColor(Color.YELLOW); g.fillRect(0, h, w,h); g.fillRect(w, 0, w,h); g.setColor(Color.BLACK); g.fillRect(0, 0, w, h); g.fillRect(w, h, w,h); } public static void main(String[] args) { // Toolkit.getDefaultToolkit().setDynamicLayout(true); // System.setProperty("sun.awt.noerasebackground", "true"); JFrame frame = new JFrame(); frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); frame.add( new SwingResize() ); frame.setSize(100, 100); frame.setLocationRelativeTo( null ); frame.setVisible(true); } } 
+2
source

Source: https://habr.com/ru/post/894027/


All Articles