// -*- mode:java; encoding:utf-8 -*-
// vim:set fileencoding=utf-8:
// @homepage@

package example;

import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.net.ServerSocket;
import javax.swing.*;
// import com.sun.tools.attach.*;

public final class MainPanel extends JPanel {
  private MainPanel() {
    super(new BorderLayout());
    add(new JScrollPane(new JTree()));
    setPreferredSize(new Dimension(320, 240));
  }

  public static void main(String[] args) {
    EventQueue.invokeLater(MainPanel::createAndShowGui);
  }

  // private static final IAppInstanceCounter counter = new JVMDescriptorInstanceCounter();
  private static void createAndShowGui() {
    try {
      UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
      ex.printStackTrace();
      Toolkit.getDefaultToolkit().beep();
    }
    // if (counter.getInstanceCount() > 1) {
    //   JOptionPane.showMessageDialog(null, "An instance of the application is already running...");
    //   return;
    // }

    SecondaryLoop loop = Toolkit.getDefaultToolkit().getSystemEventQueue().createSecondaryLoop();
    // Java Swing Hacks #68
    try (ServerSocket ignored = new ServerSocket(38_765)) {
      JFrame frame = new JFrame("@title@");
      frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
      frame.getContentPane().add(new MainPanel());
      frame.pack();
      frame.setResizable(false);
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
      frame.addWindowListener(new WindowAdapter() {
        @Override public void windowClosing(WindowEvent e) {
          loop.exit();
        }
      });
      loop.enter();
    } catch (IOException ex) {
      JOptionPane.showMessageDialog(null, "An instance of the application is already running...");
    }
  }
}

// // Attach API
// // http://d.hatena.ne.jp/Kazzz/20071221/p1
// interface IAppInstanceCounter {
//   int getInstanceCount();
// }
//
// class JVMDescriptorInstanceCounter implements IAppInstanceCounter {
//   private final String mainClassName;
//   protected JVMDescriptorInstanceCounter() {
//     StackTraceElement[] traces = Thread.currentThread().getStackTrace();
//     mainClassName = traces[traces.length-1].getClassName();
//     // System.out.println(mainClassName);
//   }
//   public int getInstanceCount() {
//     return FinderUtil.findAll(
//       VirtualMachine.list(),
//       new IPredicate<VirtualMachineDescriptor>() {
//         @Override public boolean evaluate(VirtualMachineDescriptor input) {
//           return input.displayName().equals(mainClassName);
//         }
//       }).size();
//   }
// }
//
// interface IPredicate<T> {
//  boolean evaluate(T input);
// }
//
// final class FinderUtil {
//   public static final <T> List<T> findAll(List<T> list, IPredicate<T> match) {
//     List<T> temp = new ArrayList<>();
//     for (T t : list) {
//       if (match.evaluate(t)) {
//         temp.add(t);
//       }
//     }
//     return temp;
//   }
// }

// class PseudoFileSemaphoreCounter implements IAppInstanceCounter {
//   private PseudoFileSemaphore semaphore;
//   private int launchLimit;
//   protected PseudoFileSemaphoreCounter(String appName, int launchLimit) {
//     this.semaphore = new PseudoFileSemaphore(appName, launchLimit);
//     this.launchLimit = launchLimit;
//     Runtime.getRuntime().addShutdownHook(new Thread(() -> semaphore.release()));
//   }
//
//   @Override public int getInstanceCount() {
//     int result = this.semaphore.tryAcquire();
//     return result != 0 ? result : this.launchLimit + 1;
//   }
// }

@@ -268,42 +268,8 @@
 g.*;
-%0A// import com.sun.tools.attach.*;
 %0A%0Apu
@@ -567,100 +567,8 @@
  %7D%0A%0A
-  // private static final IAppInstanceCounter counter = new JVMDescriptorInstanceCounter();%0A
   pr
@@ -896,181 +896,8 @@
    %7D
-%0A    // if (counter.getInstanceCount() %3E 1) %7B%0A    //   JOptionPane.showMessageDialog(null, %22An instance of the application is already running...%22);%0A    //   return;%0A    // %7D
 %0A%0A  
@@ -1690,1785 +1690,4 @@
 %7D%0A%7D%0A
-%0A// // Attach API%0A// // http://d.hatena.ne.jp/Kazzz/20071221/p1%0A// interface IAppInstanceCounter %7B%0A//   int getInstanceCount();%0A// %7D%0A//%0A// class JVMDescriptorInstanceCounter implements IAppInstanceCounter %7B%0A//   private final String mainClassName;%0A//   protected JVMDescriptorInstanceCounter() %7B%0A//     StackTraceElement%5B%5D traces = Thread.currentThread().getStackTrace();%0A//     mainClassName = traces%5Btraces.length-1%5D.getClassName();%0A//     // System.out.println(mainClassName);%0A//   %7D%0A//   public int getInstanceCount() %7B%0A//     return FinderUtil.findAll(%0A//       VirtualMachine.list(),%0A//       new IPredicate%3CVirtualMachineDescriptor%3E() %7B%0A//         @Override public boolean evaluate(VirtualMachineDescriptor input) %7B%0A//           return input.displayName().equals(mainClassName);%0A//         %7D%0A//       %7D).size();%0A//   %7D%0A// %7D%0A//%0A// interface IPredicate%3CT%3E %7B%0A//  boolean evaluate(T input);%0A// %7D%0A//%0A// final class FinderUtil %7B%0A//   public static final %3CT%3E List%3CT%3E findAll(List%3CT%3E list, IPredicate%3CT%3E match) %7B%0A//     List%3CT%3E temp = new ArrayList%3C%3E();%0A//     for (T t : list) %7B%0A//       if (match.evaluate(t)) %7B%0A//         temp.add(t);%0A//       %7D%0A//     %7D%0A//     return temp;%0A//   %7D%0A// %7D%0A%0A// class PseudoFileSemaphoreCounter implements IAppInstanceCounter %7B%0A//   private PseudoFileSemaphore semaphore;%0A//   private int launchLimit;%0A//   protected PseudoFileSemaphoreCounter(String appName, int launchLimit) %7B%0A//     this.semaphore = new PseudoFileSemaphore(appName, launchLimit);%0A//     this.launchLimit = launchLimit;%0A//     Runtime.getRuntime().addShutdownHook(new Thread(() -%3E semaphore.release()));%0A//   %7D%0A//%0A//   @Override public int getInstanceCount() %7B%0A//     int result = this.semaphore.tryAcquire();%0A//     return result != 0 ? result : this.launchLimit + 1;%0A//   %7D%0A// %7D%0A

comment cleanup