import java.util.*; import java.util.zip.*; import java.util.List; import java.util.regex.*; import java.util.concurrent.*; import java.util.concurrent.atomic.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.text.*; import javax.swing.table.*; import java.io.*; import java.net.*; import java.lang.reflect.*; import java.lang.ref.*; import java.lang.management.*; import java.security.*; import java.security.spec.*; import java.awt.*; import java.awt.event.*; import java.awt.image.*; import javax.imageio.*; import java.math.*; import com.sun.scenario.animation.Clip; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Container; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GridLayout; import java.awt.Rectangle; import java.awt.RenderingHints; import java.lang.reflect.Method; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.SwingUtilities; public class main { // scenario public static void main(String[] args) throws Exception { VsyncSwingTest.main(args); } /** * @author Dmitri Trembovetski */ static class VsyncSwingTest extends JPanel { volatile int translateX; private static boolean doRepaint; static boolean doVsync = true; public int getTranslateX() { return translateX; } public void setTranslateX(int translateX) { int curX = this.translateX; this.translateX = translateX; // getting fancy here, repaint() works just as well if (doRepaint) { repaint(50+Math.min(curX, translateX), 50, 100+Math.abs(curX - translateX), 300); } else { paintImmediately(50+Math.min(curX, translateX), 50, 100+Math.abs(curX - translateX), 300); } } @Override protected void paintComponent(Graphics g) { g.setColor(getBackground()); Rectangle r = g.getClipBounds(); g.fillRect(r.x, r.y, r.width, r.height); ((Graphics2D)g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g.setColor(Color.black); g.fillRect(50+translateX, 50, 100, 300); } public VsyncSwingTest() { setBackground(Color.WHITE); setPreferredSize(new Dimension(600, 400)); Clip c = Clip.create(1000, Clip.INDEFINITE, this, "translateX", 0, 400); c.start(); } static void setVsyncRequested(JFrame f, boolean b) { try { Class tmpClass = Class.forName("com.sun.java.swing.SwingUtilities3"); Method tmpMethod = tmpClass.getMethod("setVsyncRequested", Container.class, boolean.class); tmpMethod.invoke(tmpClass, f, Boolean.valueOf(b)); } catch (Throwable ignore) { System.err.println("Warning: Error while requesting vsync: "+ignore); } } public static void main(String[] args) { int instances = 1; for (String arg : args) { if (arg.equalsIgnoreCase("-repaint")) { doRepaint = true; } else if (arg.equals("+i")) { instances++; } else if (arg.equals("-novsync")) { doVsync = false; } } if (doRepaint) { System.err.println("Using repaint()"); } else { System.err.println("Using paintImmediately()"); } if (doVsync) { System.err.println("Requesting VSYNC"); } else { System.err.println("Not requesting VSYNC"); } final int insts = instances; SwingUtilities.invokeLater(new Runnable() { public void run() { JFrame frame = new JFrame(); // frame.setUndecorated(true); JPanel p = new JPanel(); p.setLayout(new GridLayout(insts, 1)); VsyncSwingTest test; for (int i = 0; i < insts; i++) { test = new VsyncSwingTest(); p.add(test); } frame.add(BorderLayout.CENTER, p); String[] arr = { "So How's the responsiveness?", "two", "three", "four", "five", "six", "seven", "eight", "1", "2", "3", "4", "5", "6", "7", "8" }; frame.add(BorderLayout.NORTH, new JComboBox(arr)); frame.add(BorderLayout.SOUTH, new JButton("some button")); frame.pack(); setVsyncRequested(frame, doVsync); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } } }