Best practices in Java and Swing

7,375
-1

Published on

Published in: Technology, Education
1 Comment
11 Likes
Statistics
Notes
  • nice presentation,but download is disabled
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total Views
7,375
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
0
Comments
1
Likes
11
Embeds 0
No embeds

No notes for slide

Best practices in Java and Swing

  1. 1. Best practices in Java and Swing Arne Bachmann Folie 1 Vortrag > Autor > Dokumentname > 09.11.2005
  2. 2. Topics Arrays, Collections and Loops Enumerations The final keyword Threading In Swing Singleton Tools Folie 2 Vortrag > Autor > Dokumentname > 09.11.2005
  3. 3. Arrays, Collections and Loops "Foreach" style loop void listLines(String[] lines) { PrintStream ps = new PrintStream( new FileOutputStream("C:test.out")); for (String line: lines) { ps.println(line); } ps.close(); } Folie 3 Vortrag > Autor > Dokumentname > 09.11.2005
  4. 4. Arrays, Collections and Loops "Map-Entry" style loop – similar to ".items()" in Python String listItems(Map<String, Long> collection) { StringBuilder sb = new StringBuilder(); for (Entry<String, Long> entry: collection.entrySet()) { sb.append(entry.getKey()) .append(" maps to ") .append(entry.getValue()); .append("n"); } return sb.toString(); } Folie 4 Vortrag > Autor > Dokumentname > 09.11.2005
  5. 5. Enumerations Folie 5 Vortrag > Autor > Dokumentname > 09.11.2005
  6. 6. Enumerations Don't try to serialize enums don't provide a private static final long serialVersionUID Use enum instead of true/false where possible import static my.package.Visibility.VISIBLE; import static my.package.Visibility.HIDDEN; display.setVisible(VISIBLE); display.setVisible(HIDDEN); Folie 6 Vortrag > Autor > Dokumentname > 09.11.2005
  7. 7. Enumerations Don't try to serialize enums don't provide a private static final long serialVersionUID Use enum instead of true/false where possible import static my.package.Visibility.VISIBLE; import static my.package.Visibility.HIDDEN; Import static my.package.Visibility.SEMI_TRANSPARENT; display.setVisible(SEMI_TRANSPARENT); Folie 7 Vortrag > Autor > Dokumentname > 09.11.2005
  8. 8. Enumerations Combine settings by using enumSet enum ELogCapability { Console, Graphical, File; } // Constructor MyLogger(EnumSet<ELogCapability> logTypes) { if (logTypes.contains(ELogCapability.Console)) { // ... } else if ... } Folie 8 Vortrag > Autor > Dokumentname > 09.11.2005
  9. 9. Enumerations Powerful enumerations – Part 1: The less known constructor enum EVariableDataType { Integer ("long"), Real ("double"), File ("file"); private final String type; private EVariableDataType(String aType) { type = aType; } } Folie 9 Vortrag > Autor > Dokumentname > 09.11.2005
  10. 10. Enumerations Powerful enumerations – Part 2: The trick private static final Map<String, EVariableDataType> TYPES = new Hashtable<String, EVariableDataType>(); static { TYPES.put(Integer.type, Integer); TYPES.put(Real.type, Real); TYPES.put(File.type, File); } public static EVariableDataType typeOf(String forName) { return TYPES.get(forName.toLowerCase()); } Folie 10 Vortrag > Autor > Dokumentname > 09.11.2005
  11. 11. Final Folie 11 Vortrag > Autor > Dokumentname > 09.11.2005
  12. 12. Final Use final as often as possible final class ExampleClass { void example(final File source) { final File[] files = source.listFiles(); for (final File file: files) { final String name = file.getAbsolutePath(); try { file.delete(); } catch (final IOException e) { logger.error(e); } } } } Folie 12 Vortrag > Autor > Dokumentname > 09.11.2005
  13. 13. Final Constant value initialization from the constructor protected class MyClass { final private String param; MyClass(final String p) { param = p; } } Folie 13 Vortrag > Autor > Dokumentname > 09.11.2005
  14. 14. Variable number of arguments Beware of varargs methods: Can create very hard to find errors Long[] createLongArray(final long first) { return new Long[] { first }; } Long[] createLongArray(final long first, final long second) { return new Long[] { first, second }; } Long[] createLongArray(long... args) { final List<Long> list = new ArrayList<Long>(); for (final Long l: args) { list.add(l); } return list.toArray(new Long[0]); // or: new Long[] {} } Folie 14 Vortrag > Autor > Dokumentname > 09.11.2005
  15. 15. Collections Folie 15 Vortrag > Autor > Dokumentname > 09.11.2005
  16. 16. Collections Always type collections (we're in Java SE 5, which already came 2004) e.g.: List<Pair<String, Wrapper<ELogCapability>[]>> list; Hashtable<T, U> Allows only non-null keys and values Synchronized HashMap<T, U> Allows null for both keys and values Unsynchronized Use new ConcurrentHashMap() for Collections.synchronizedMap() Internally synchronized Folie 16 Vortrag > Autor > Dokumentname > 09.11.2005
  17. 17. Singleton Folie 17 Vortrag > Autor > Dokumentname > 09.11.2005
  18. 18. Singleton Singleton – Often implemented wrong: public class MySingleton { private static MySingleton instance; private MySingleton() { // initialization } public static MySingleton getInstance() { if (instance == null) { instance = new MySingleton(); } return instance; } } Folie 18 Vortrag > Autor > Dokumentname > 09.11.2005
  19. 19. Singleton Singleton – This works public class MySingleton { private static MySingleton instance; private MySingleton() { // initialization } public static synchronized MySingleton getInstance() { if (instance == null) { instance = new MySingleton(); } return instance; } } Folie 19 Vortrag > Autor > Dokumentname > 09.11.2005
  20. 20. Singleton Singleton – Use synchronization of the classloader public class MySingleton2 { final static private MySingleton2 instance = new MySingleton2(); private MySingleton2() { // initialization } public MySingleton2 getInstance() { return instance; } } Folie 20 Vortrag > Autor > Dokumentname > 09.11.2005
  21. 21. Threading Folie 21 Vortrag > Autor > Dokumentname > 09.11.2005
  22. 22. Threading Useful: Set UncaughtExceptionHandler class MyHandler implements UncaughtExceptionHandler { public void uncaughtException(final Thread t, final Throwable e) { logger.error(t.getName() + ": " + e.getMessage()); } } void newThread() { final Thread thread = new Thread(new Runnable() { public void run() { // do something in the thread } }); thread.setUncaughtExceptionHandler(new MyHandler.getInstance()); } Folie 22 Vortrag > Autor > Dokumentname > 09.11.2005
  23. 23. Threading How to create standard threads Dont' use new Thread(…) anymore! final ExecutorService single; single = Executors.newSingleThreadExecutor(); single.execute(new Runnable() { public void run() { // anonymous code } }); Folie 23 Vortrag > Autor > Dokumentname > 09.11.2005
  24. 24. Threading How to create standard threads Dont' use new Thread(…) anymore! final ExecutorService single; final ExecutorService pool; final ExecutorService timed; single = Executors.newSingleThreadExecutor(); pool = Executors.newFixedThreadPool(3); timed = Executors.newSingleThreadScheduledExecutor(); single.execute(new Runnable() { public void run() { // anonymous code } }); Folie 24 Vortrag > Autor > Dokumentname > 09.11.2005
  25. 25. Threading Use volatile and synchronize wisely Not easy to understand, find yourself some articles on that topic! Volatile ensures visibility of Variable reference (for reference types) Variable value (for simple types) Use atomic types for long and double Because Java usually doesn't guarantee visibility of other threads' memory changes Synchronize explicitly uses JVM's object locking mechanism to synchronize (linearize) variable accesses → deadlocks possible Folie 25 Vortrag > Autor > Dokumentname > 09.11.2005
  26. 26. Threading Avoid using anonymous classes where applicable Refactor to named classes step-by-step How to avoid the "synthetic accessor method" problem? Named inner classes, see next slide Folie 26 Vortrag > Autor > Dokumentname > 09.11.2005
  27. 27. Threading "Read access is emulated by a synthetic accessor" (Eclipse warning) public class WrongSyntheticAccessorExample extends JDialog { private String name; protected JPanel createPanel() { final JPanel panel = new JPanel(); final JButton button = new JButton("Huh?"); button.addActionListener(new ActionListener() { public void actionPerformed(final ActionEvent evt) { button.setText(button.getText() + name); } }); return panel; } } Folie 27 Vortrag > Autor > Dokumentname > 09.11.2005
  28. 28. Threading Solution: Inner classes public class SyntheticAccessorExample extends JDialog { private class InnerClass implements ActionListener { private final String copyOfName; private final JButton buttonRef; InnerClass(final String name, final JButton button) { copyOfName = new String(name); // shallow clone buttonRef = button; // keep reference } public void actionPerformed(final ActionEvent evt) { buttonRef.setText(buttonRef.getText() + copyOfName); } } protected JPanel createPanel() { final JPanel panel = new JPanel(); final JButton button = new JButton("Huh?"); button.addActionListener(new InnerClass("Done!", button)); return panel; } } Folie 28 Vortrag > Autor > Dokumentname > 09.11.2005
  29. 29. Threading in Swing The Event Dispatch Thread (EDT) Almost everything GUI related must happen in this thread! Otherwise: GUI not updated, blocking or unintelligible results Exception: first static call from main or init Exception: repaint() … and listener (de-) registration Events by GUI components are always automatically on the EDT Put everything CPU or time consuming to other threads (executors) And provide callbacks for GUI updates Q: How to build up a complex GUI while staying responsive? Folie 29 Vortrag > Autor > Dokumentname > 09.11.2005
  30. 30. Threading in Swing Events by GUI components are always automatically on the EDT, e.g. public void actionPerformed(final ActionEvent evt) {} public void mouseClicked(final MouseEvent e) {} Use javax.swing.Timer to create repeating events on the EDT: final Timer timer = new Timer(200 /* ms */, new ActionListener() { public void actionPerformed(final ActionEvent evt) { button.setEnabled(!button.isEnabled()); } }); timer.setInitialDelay(0); // start immediately timer.start(); Folie 30 Vortrag > Autor > Dokumentname > 09.11.2005
  31. 31. Threading in Swing Put everything CPU or time consuming to other threads (executors) And provide callbacks for GUI updates final JButton okB = new JButton("OK"); okB.setEnabled(false); final ExecutorService thread = Executors.newSingleThreadExecutor(); thread.execute(new Runnable() { public void run() { // do some time-consuming calculations here SwingUtilities.invokeLater(new Runnable() { public void run() { okB.setEnabled(true); } }); thread.shutdown(); // commence own shutdown } }); Folie 31 Vortrag > Autor > Dokumentname > 09.11.2005
  32. 32. Threading in Swing Initialization during class load or construction is possible OK if class loaded on EDT (e.g. new GUI(); in invokeLater()) OK if initialization is only simple, fast and failsafe BUT if exceptions occur here, they are hard to track down! Folie 32 Vortrag > Autor > Dokumentname > 09.11.2005
  33. 33. Threading in Swing Question: How to build up a complex GUI while staying responsive? A: Ensure that a splash screen is shown before building GUI? A: Break down GUI creation into single work tasks queued in EDT? A: Interrupt the thread somehow? Folie 33 Vortrag > Autor > Dokumentname > 09.11.2005
  34. 34. Tools VisualVM Based on Netbeans platform Connects to VMs via JMX (really useful only since Java SE 6) Allows profiling, monitoring, recording, snapshotting Many plugins available Swing Explorer Library Detect errors in UI applications Folie 34 Vortrag > Autor > Dokumentname > 09.11.2005
  35. 35. References Enumerations http://www.javaworld.com/community/node/3125 Singleton http://www.theserverside.de/singleton-pattern-in-java/ Threading http://java.sun.com/products/jfc/tsc/articles/threads/threads1.html Java Best practices: Joshua Bloch (2008): "Effective Java. Second edition." Folie 35 Vortrag > Autor > Dokumentname > 09.11.2005
  36. 36. Questions? http://www.walle-derfilm.de/

×