Example #1
0
  /** GUIコンポーネントを初期化する。 */
  public void initComponent() {

    frame = new JFrame(ClientContext.getFrameTitle(title));
    frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
    frame.addWindowListener(
        new WindowAdapter() {
          @Override
          public void windowClosing(WindowEvent e) {
            stop();
          }
        });

    JPanel contentPane = createBrowsePane();
    contentPane.setBorder(BorderFactory.createEmptyBorder(12, 12, 11, 11));

    contentPane.setOpaque(true);
    frame.setContentPane(contentPane);
    frame.pack();

    Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
    int n = ClientContext.isMac() ? 3 : 2;
    int x = (screen.width - frame.getPreferredSize().width) / 2;
    int y = (screen.height - frame.getPreferredSize().height) / n;
    frame.setLocation(x, y);

    blockGlass = new BlockGlass();
    frame.setGlassPane(blockGlass);

    frame.setVisible(true);
  }
Example #2
0
  /** GUI コンポーネントを初期化する。 */
  private void initComponents() {

    view = new NLabTestImportView();
    setUI(view);

    String[] columnNames =
        new String[] {"ラボ", "患者ID", "カナ", "カルテ・カナ", "性別", "カルテ・性別", "検体採取日", "項目数", "登録"};
    String[] propNames =
        new String[] {
          "laboCode",
          "patientId",
          "patientName",
          "karteKanaName",
          "patientSex",
          "karteSex",
          "sampleDate",
          "numOfTestItems",
          "result"
        };
    int[] columnWidth = new int[] {50, 120, 120, 120, 50, 70, 120, 50, 80};

    tableModel = new ListTableModel<NLaboImportSummary>(columnNames, 30, propNames, null);
    view.getTable().setModel(tableModel);
    view.getTable().setRowHeight(ClientContext.getHigherRowHeight());
    view.getTable().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    view.getTable().setTransferHandler(new NLaboTestFileTransferHandler(this));

    // カラム幅を変更する
    for (int i = 0; i < columnWidth.length; i++) {
      view.getTable().getColumnModel().getColumn(i).setPreferredWidth(columnWidth[i]);
    }

    // レンダラを設定する
    view.getTable().setDefaultRenderer(Object.class, new NLaboTestImporter.LabTestRenderer());

    // カウント値0を設定する
    updateCount();
  }
Example #3
0
  public void openKarte() {

    boolean showReceiptMessage = Project.getBoolean("showReceiptMessage", true);
    if (showReceiptMessage) {
      JLabel msg1 = new JLabel("受付リストからオープンしないと診療データをレセコンに");
      JLabel msg2 = new JLabel("送信することができません。続けますか?");
      final JCheckBox cb = new JCheckBox("今後このメッセージを表示しない");
      cb.setFont(new Font("Dialog", Font.PLAIN, 10));
      cb.addActionListener(
          new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
              Project.setBoolean("showReceiptMessage", !cb.isSelected());
            }
          });
      JPanel p1 = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 3));
      p1.add(msg1);
      JPanel p2 = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 3));
      p2.add(msg2);
      JPanel p3 = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 3));
      p3.add(cb);
      JPanel box = new JPanel();
      box.setLayout(new BoxLayout(box, BoxLayout.Y_AXIS));
      box.add(p1);
      box.add(p2);
      box.add(p3);
      box.setBorder(BorderFactory.createEmptyBorder(0, 0, 11, 11));

      int option =
          JOptionPane.showConfirmDialog(
              SwingUtilities.getWindowAncestor(getUI()),
              new Object[] {box},
              ClientContext.getFrameTitle(getName()),
              JOptionPane.YES_NO_OPTION,
              JOptionPane.QUESTION_MESSAGE,
              ClientContext.getImageIcon("about_32.gif"));

      if (option != JOptionPane.YES_OPTION) {
        return;
      }
    }

    PatientModel patient = selectedLabo.getPatient();
    PatientVisitModel pvt = new PatientVisitModel();
    pvt.setNumber(number++);
    pvt.setPatientModel(patient);

    // 受け付けを通していないので診療科はユーザ登録してあるものを使用する
    // 診療科名、診療科コード、医師名、医師コード、JMARI
    // 2.0
    pvt.setDeptName(Project.getUserModel().getDepartmentModel().getDepartmentDesc());
    pvt.setDeptCode(Project.getUserModel().getDepartmentModel().getDepartment());
    pvt.setDoctorName(Project.getUserModel().getCommonName());
    if (Project.getUserModel().getOrcaId() != null) {
      pvt.setDoctorId(Project.getUserModel().getOrcaId());
    } else {
      pvt.setDoctorId(Project.getUserModel().getUserId());
    }
    pvt.setJmariNumber(Project.getString(Project.JMARI_CODE));

    // カルテコンテナを生成する
    getContext().openKarte(pvt);
  }
Example #4
0
/**
 * LabTestImporter
 *
 * @author Kazushi Minagawa, Digital Globe, Inc.
 */
public class NLaboTestImporter extends AbstractMainComponent {

  private static final String NAME = "ラボレシーバ";
  private static final String SUCCESS = "成功";
  private static final String ERROR = "エラー";
  private static final Color ODD_COLOR = ClientContext.getColor("color.odd");
  private static final Color EVEN_COLOR = ClientContext.getColor("color.even");
  private static final Color UNCONSTRAINED_COLOR = new Color(255, 102, 102);

  // 選択されている患者情報
  private NLaboImportSummary selectedLabo;
  private int number = 100000;

  // View
  private ListTableModel<NLaboImportSummary> tableModel;
  private NLabTestImportView view;

  /** Creates new NLaboTestImporter */
  public NLaboTestImporter() {
    setName(NAME);
  }

  @Override
  public void start() {
    initComponents();
    connect();
    enter();
  }

  @Override
  public void enter() {
    controlMenu();
  }

  @Override
  public void stop() {}

  public JProgressBar getProgressBar() {
    return getContext().getProgressBar();
  }

  public ListTableModel<NLaboImportSummary> getTableModel() {
    return (ListTableModel<NLaboImportSummary>) view.getTable().getModel();
  }

  public NLaboImportSummary getSelectedLabo() {
    return selectedLabo;
  }

  public void setSelectedLabo(NLaboImportSummary selectedLabo) {
    this.selectedLabo = selectedLabo;
    controlMenu();
  }

  public void openKarte() {

    boolean showReceiptMessage = Project.getBoolean("showReceiptMessage", true);
    if (showReceiptMessage) {
      JLabel msg1 = new JLabel("受付リストからオープンしないと診療データをレセコンに");
      JLabel msg2 = new JLabel("送信することができません。続けますか?");
      final JCheckBox cb = new JCheckBox("今後このメッセージを表示しない");
      cb.setFont(new Font("Dialog", Font.PLAIN, 10));
      cb.addActionListener(
          new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
              Project.setBoolean("showReceiptMessage", !cb.isSelected());
            }
          });
      JPanel p1 = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 3));
      p1.add(msg1);
      JPanel p2 = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 3));
      p2.add(msg2);
      JPanel p3 = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 3));
      p3.add(cb);
      JPanel box = new JPanel();
      box.setLayout(new BoxLayout(box, BoxLayout.Y_AXIS));
      box.add(p1);
      box.add(p2);
      box.add(p3);
      box.setBorder(BorderFactory.createEmptyBorder(0, 0, 11, 11));

      int option =
          JOptionPane.showConfirmDialog(
              SwingUtilities.getWindowAncestor(getUI()),
              new Object[] {box},
              ClientContext.getFrameTitle(getName()),
              JOptionPane.YES_NO_OPTION,
              JOptionPane.QUESTION_MESSAGE,
              ClientContext.getImageIcon("about_32.gif"));

      if (option != JOptionPane.YES_OPTION) {
        return;
      }
    }

    PatientModel patient = selectedLabo.getPatient();
    PatientVisitModel pvt = new PatientVisitModel();
    pvt.setNumber(number++);
    pvt.setPatientModel(patient);

    // 受け付けを通していないので診療科はユーザ登録してあるものを使用する
    // 診療科名、診療科コード、医師名、医師コード、JMARI
    // 2.0
    pvt.setDeptName(Project.getUserModel().getDepartmentModel().getDepartmentDesc());
    pvt.setDeptCode(Project.getUserModel().getDepartmentModel().getDepartment());
    pvt.setDoctorName(Project.getUserModel().getCommonName());
    if (Project.getUserModel().getOrcaId() != null) {
      pvt.setDoctorId(Project.getUserModel().getOrcaId());
    } else {
      pvt.setDoctorId(Project.getUserModel().getUserId());
    }
    pvt.setJmariNumber(Project.getString(Project.JMARI_CODE));

    // カルテコンテナを生成する
    getContext().openKarte(pvt);
  }

  /**
   * 検索結果件数を設定しステータスパネルへ表示する。
   *
   * @param cnt 件数
   */
  public void updateCount() {
    int count = getTableModel().getObjectCount();
    String text = String.valueOf(count);
    text += "件";
    view.getCountLbl().setText(text);
  }

  /** メニューを制御する */
  private void controlMenu() {

    PatientModel pvt = getSelectedLabo() != null ? getSelectedLabo().getPatient() : null;

    boolean enabled = canOpen(pvt);
    getContext().enabledAction(GUIConst.ACTION_OPEN_KARTE, enabled);
  }

  /**
   * カルテを開くことが可能かどうかを返す。
   *
   * @return 開くことが可能な時 true
   */
  private boolean canOpen(PatientModel patient) {
    if (patient == null) {
      return false;
    }

    if (isKarteOpened(patient)) {
      return false;
    }

    return true;
  }

  /**
   * カルテがオープンされているかどうかを返す。
   *
   * @return オープンされている時 true
   */
  private boolean isKarteOpened(PatientModel patient) {
    if (patient != null) {
      boolean opened = false;
      java.util.List<ChartImpl> allCharts = ChartImpl.getAllChart();
      for (ChartImpl chart : allCharts) {
        if (chart.getPatient().getId() == patient.getId()) {
          opened = true;
          break;
        }
      }
      return opened;
    }
    return false;
  }

  /** 検査結果ファイルを選択し、パースする。 */
  private void selectAndParseLabFile() {

    // 検査結果ファイルを選択する
    JFileChooser chooser = new JFileChooser();
    FileNameExtensionFilter filter =
        new FileNameExtensionFilter(
            "Lab Result File", "DAT", "dat", "DAT2", "dat2", "HL7", "hl7", "TXT", "txt");
    chooser.setFileFilter(filter);
    chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
    int returnVal = chooser.showOpenDialog(getUI());

    if (returnVal != JFileChooser.APPROVE_OPTION) {
      return;
    }

    // パースしてテーブルへ表示する
    // 登録ボタンをアクティブにする
    final File labFile = new File(chooser.getSelectedFile().getPath());

    final javax.swing.SwingWorker worker =
        new javax.swing.SwingWorker<List<NLaboImportSummary>, Void>() {

          @Override
          protected List<NLaboImportSummary> doInBackground() throws Exception {

            LabResultParser parse = LabParserFactory.getParser(labFile.getName());

            List<NLaboImportSummary> dataList = parse.parse(labFile);

            if (dataList != null && dataList.size() > 0) {

              List<String> idList = new ArrayList<String>(dataList.size());
              for (NLaboImportSummary sm : dataList) {
                idList.add(sm.getPatientId());
              }

              LaboDelegater laboDelegater = new LaboDelegater();
              List<PatientLiteModel> pList = laboDelegater.getConstrainedPatients(idList);

              // for (int i = 0; i < pList.size(); i++) {
              for (int i = 0; i < dataList.size(); i++) {
                NLaboImportSummary sm = dataList.get(i);
                PatientLiteModel pl = pList.get(i);
                if (pl != null) {
                  sm.setKarteId(pl.getPatientId());
                  sm.setKarteBirthday(pl.getBirthday());
                  sm.setKarteKanaName(pl.getKanaName());
                  sm.setKarteName(pl.getFullName());
                  sm.setKarteSex(pl.getGenderDesc());
                }
              }
            }

            return dataList;
          }

          @Override
          protected void done() {

            try {
              List<NLaboImportSummary> allModules = get();
              getTableModel().setDataProvider(allModules);

            } catch (Throwable e) {
              e.printStackTrace(System.err);
              String why = e.getMessage();
              Window parent = SwingUtilities.getWindowAncestor(getUI());
              StringBuilder sb = new StringBuilder();
              sb.append("登録できないファイルがあります。").append("\n");
              sb.append("検査結果ファイルに誤りがある可能性があります。").append("\n");
              sb.append(why);
              String message = sb.toString();
              String title = "ラボレシーバ";
              JOptionPane.showMessageDialog(
                  parent, message, ClientContext.getFrameTitle(title), JOptionPane.WARNING_MESSAGE);
            }
          }
        };

    worker.addPropertyChangeListener(
        new PropertyChangeListener() {

          @Override
          public void propertyChange(PropertyChangeEvent evt) {
            if (evt.getNewValue().equals(javax.swing.SwingWorker.StateValue.STARTED)) {
              getProgressBar().setIndeterminate(true);
            } else if (evt.getNewValue().equals(javax.swing.SwingWorker.StateValue.DONE)) {
              getProgressBar().setIndeterminate(false);
              getProgressBar().setValue(0);
              worker.removePropertyChangeListener(this);
            }
          }
        });

    worker.execute();
  }

  /** パースした検査結果を登録する。 */
  private void addLabtest() {

    final List<NLaboImportSummary> modules = getTableModel().getDataProvider();

    final javax.swing.SwingWorker worker =
        new javax.swing.SwingWorker<Void, Void>() {

          @Override
          protected Void doInBackground() throws Exception {

            LaboDelegater laboDelegater = new LaboDelegater();

            for (NLaboImportSummary summary : modules) {

              PatientModel pm = laboDelegater.putNLaboModule(summary.getModule());

              if (pm != null) {
                summary.setPatient(pm);
                summary.setResult(SUCCESS);

              } else {
                summary.setResult(ERROR);
              }

              // Table 更新
              Runnable awt =
                  new Runnable() {
                    @Override
                    public void run() {
                      getTableModel().fireTableDataChanged();
                    }
                  };
              EventQueue.invokeLater(awt);
            }

            return null;
          }
        };

    worker.addPropertyChangeListener(
        new PropertyChangeListener() {

          @Override
          public void propertyChange(PropertyChangeEvent evt) {
            if (evt.getNewValue().equals(javax.swing.SwingWorker.StateValue.STARTED)) {
              getProgressBar().setIndeterminate(true);
            } else if (evt.getNewValue().equals(javax.swing.SwingWorker.StateValue.DONE)) {
              getProgressBar().setIndeterminate(false);
              getProgressBar().setValue(0);
              worker.removePropertyChangeListener(this);
            }
          }
        });

    worker.execute();
  }

  /** コンポーンントにリスナを登録し接続する。 */
  private void connect() {

    // ファイル選択ボタン
    view.getFileBtn()
        .addActionListener(
            new ActionListener() {

              @Override
              public void actionPerformed(ActionEvent e) {
                // ファイル選択
                selectAndParseLabFile();
              }
            });

    // 登録ボタン
    view.getAddBtn()
        .addActionListener(
            new ActionListener() {

              @Override
              public void actionPerformed(ActionEvent e) {
                // 検査結果登録
                view.getAddBtn().setEnabled(false);
                addLabtest();
              }
            });
    view.getAddBtn().setEnabled(false);

    // クリアボタン
    view.getClearBtn()
        .addActionListener(
            new ActionListener() {

              @Override
              public void actionPerformed(ActionEvent e) {
                // 検査結果登録
                getTableModel().setDataProvider(null);
              }
            });
    view.getClearBtn().setEnabled(false);

    // 行選択
    view.getTable()
        .getSelectionModel()
        .addListSelectionListener(
            new ListSelectionListener() {

              @Override
              public void valueChanged(ListSelectionEvent e) {
                if (e.getValueIsAdjusting() == false) {
                  NLaboImportSummary lab =
                      getTableModel().getObject(view.getTable().getSelectedRow());
                  if (lab != null) {
                    setSelectedLabo(lab);
                  }
                }
              }
            });

    // ダブルクリック
    view.getTable()
        .addMouseListener(
            new MouseAdapter() {

              @Override
              public void mouseClicked(MouseEvent e) {
                if (e.getClickCount() == 2) {
                  NLaboImportSummary lab =
                      getTableModel().getObject(view.getTable().getSelectedRow());
                  if (lab != null && lab.getPatient() != null) {
                    openKarte();
                  }
                }
              }
            });

    // コンテキストメニューリスナを設定する
    view.getTable()
        .addMouseListener(
            new MouseAdapter() {

              @Override
              public void mousePressed(MouseEvent e) {
                mabeShowPopup(e);
              }

              @Override
              public void mouseReleased(MouseEvent e) {
                mabeShowPopup(e);
              }

              private void mabeShowPopup(MouseEvent e) {

                if (e.isPopupTrigger()) {

                  final JPopupMenu contextMenu = new JPopupMenu();

                  JTable table = view.getTable();
                  int row = table.rowAtPoint(e.getPoint());
                  Object obj = (Object) getTableModel().getObject(row);
                  int selected = table.getSelectedRow();

                  if (row == selected && obj != null) {
                    String pop1 = ClientContext.getString("watingList.popup.openKarte");
                    contextMenu.add(
                        new JMenuItem(
                            new ReflectAction(pop1, NLaboTestImporter.this, "openKarte")));
                  }
                  contextMenu.show(e.getComponent(), e.getX(), e.getY());
                }
              }
            });

    // data 件数リスナ
    getTableModel()
        .addPropertyChangeListener(
            new PropertyChangeListener() {

              @Override
              public void propertyChange(PropertyChangeEvent evt) {
                List<NLaboImportSummary> list = (List<NLaboImportSummary>) evt.getNewValue();
                boolean enabled = (list != null && list.size() > 0) ? true : false;
                boolean clearOk = enabled;
                if (enabled) {
                  for (NLaboImportSummary sm : list) {
                    if (sm.getKarteId() == null) {
                      enabled = false;
                      break;
                    }
                  }
                }
                view.getAddBtn().setEnabled(enabled);
                view.getClearBtn().setEnabled(clearOk);
                updateCount();
              }
            });
  }

  /** GUI コンポーネントを初期化する。 */
  private void initComponents() {

    view = new NLabTestImportView();
    setUI(view);

    String[] columnNames =
        new String[] {"ラボ", "患者ID", "カナ", "カルテ・カナ", "性別", "カルテ・性別", "検体採取日", "項目数", "登録"};
    String[] propNames =
        new String[] {
          "laboCode",
          "patientId",
          "patientName",
          "karteKanaName",
          "patientSex",
          "karteSex",
          "sampleDate",
          "numOfTestItems",
          "result"
        };
    int[] columnWidth = new int[] {50, 120, 120, 120, 50, 70, 120, 50, 80};

    tableModel = new ListTableModel<NLaboImportSummary>(columnNames, 30, propNames, null);
    view.getTable().setModel(tableModel);
    view.getTable().setRowHeight(ClientContext.getHigherRowHeight());
    view.getTable().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    view.getTable().setTransferHandler(new NLaboTestFileTransferHandler(this));

    // カラム幅を変更する
    for (int i = 0; i < columnWidth.length; i++) {
      view.getTable().getColumnModel().getColumn(i).setPreferredWidth(columnWidth[i]);
    }

    // レンダラを設定する
    view.getTable().setDefaultRenderer(Object.class, new NLaboTestImporter.LabTestRenderer());

    // カウント値0を設定する
    updateCount();
  }

  protected class LabTestRenderer extends DefaultTableCellRenderer {

    /** Creates new IconRenderer */
    public LabTestRenderer() {
      super();
    }

    @Override
    public Component getTableCellRendererComponent(
        JTable table, Object value, boolean isSelected, boolean isFocused, int row, int col) {

      NLaboImportSummary summary = (NLaboImportSummary) tableModel.getObject(row);

      if (isSelected) {
        this.setBackground(table.getSelectionBackground());
        this.setForeground(table.getSelectionForeground());

      } else {
        if (summary != null && summary.getKarteId() == null) {

          this.setBackground(UNCONSTRAINED_COLOR);

        } else {

          if ((row & (1)) == 0) {
            this.setBackground(EVEN_COLOR);
          } else {
            this.setBackground(ODD_COLOR);
          }
        }

        this.setForeground(table.getForeground());
      }

      if (value != null && value instanceof String) {
        this.setText((String) value);
      } else {
        this.setText(value == null ? "" : value.toString());
      }
      return this;
    }
  }
}
Example #5
0
/**
 * StampImporter
 *
 * @author Minagawa,Kazushi
 */
public class StampImporter {

  private static final String[] COLUMN_NAMES = {"名  称", "カテゴリ", "公開者", "説  明", "公開先", "インポート"};
  private static final String[] METHOD_NAMES = {
    "name", "category", "partyName", "description", "publishType", "isImported"
  };
  private static final Class[] CLASSES = {
    String.class, String.class, String.class, String.class, String.class, Boolean.class
  };
  private static final int[] COLUMN_WIDTH = {120, 90, 170, 270, 40, 40};
  private static final Color ODD_COLOR = ClientContext.getColor("color.odd");
  private static final Color EVEN_COLOR = ClientContext.getColor("color.even");
  private static final ImageIcon WEB_ICON = ClientContext.getImageIcon("web_16.gif");
  private static final ImageIcon HOME_ICON = ClientContext.getImageIcon("home_16.gif");
  private static final ImageIcon FLAG_ICON = ClientContext.getImageIcon("flag_16.gif");

  private String title = "スタンプインポート";
  private JFrame frame;
  private BlockGlass blockGlass;
  private JTable browseTable;
  private ListTableModel<PublishedTreeModel> tableModel;
  private JButton importBtn;
  private JButton deleteBtn;
  private JButton cancelBtn;
  private JLabel publicLabel;
  private JLabel localLabel;
  private JLabel importedLabel;

  private StampBoxPlugin stampBox;
  private List<Long> importedTreeList;

  // timerTask 関連
  private javax.swing.Timer taskTimer;
  private ProgressMonitor monitor;
  private int delayCount;
  private int maxEstimation = 90 * 1000; // 90 秒
  private int delay = 300; // 300 mmsec

  public StampImporter(StampBoxPlugin stampBox) {
    this.stampBox = stampBox;
    importedTreeList = stampBox.getImportedTreeList();
  }

  /** 公開されているTreeのリストを取得しテーブルへ表示する。 */
  public void start() {

    final SimpleWorker worker =
        new SimpleWorker<List<PublishedTreeModel>, Void>() {

          @Override
          protected List<PublishedTreeModel> doInBackground() throws Exception {
            StampDelegater sdl = new StampDelegater();
            List<PublishedTreeModel> result = sdl.getPublishedTrees();
            return result;
          }

          @Override
          protected void succeeded(List<PublishedTreeModel> result) {
            // DBから取得が成功したらGUIコンポーネントを生成する
            initComponent();
            if (importedTreeList != null && importedTreeList.size() > 0) {
              for (PublishedTreeModel model : result) {
                for (Long id : importedTreeList) {
                  if (id.longValue() == model.getId()) {
                    model.setImported(true);
                    break;
                  }
                }
              }
            }
            tableModel.setDataProvider(result);
          }

          @Override
          protected void failed(java.lang.Throwable cause) {
            JOptionPane.showMessageDialog(
                frame,
                cause.getMessage(),
                ClientContext.getFrameTitle(title),
                JOptionPane.WARNING_MESSAGE);
            ClientContext.getBootLogger().warn(cause.getMessage());
          }

          @Override
          protected void startProgress() {
            delayCount = 0;
            taskTimer.start();
          }

          @Override
          protected void stopProgress() {
            taskTimer.stop();
            monitor.close();
            taskTimer = null;
            monitor = null;
          }
        };

    String message = "スタンプインポート";
    String note = "公開スタンプを取得しています...";
    Component c = frame;
    monitor = new ProgressMonitor(c, message, note, 0, maxEstimation / delay);

    taskTimer =
        new Timer(
            delay,
            new ActionListener() {

              @Override
              public void actionPerformed(ActionEvent e) {
                delayCount++;

                if (monitor.isCanceled() && (!worker.isCancelled())) {
                  // no cancel
                } else if (delayCount >= monitor.getMaximum() && (!worker.isCancelled())) {
                  worker.cancel(true);

                } else {
                  monitor.setProgress(delayCount);
                }
              }
            });

    worker.execute();
  }

  /** GUIコンポーネントを初期化する。 */
  public void initComponent() {

    frame = new JFrame(ClientContext.getFrameTitle(title));
    frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
    frame.addWindowListener(
        new WindowAdapter() {
          @Override
          public void windowClosing(WindowEvent e) {
            stop();
          }
        });

    JPanel contentPane = createBrowsePane();
    contentPane.setBorder(BorderFactory.createEmptyBorder(12, 12, 11, 11));

    contentPane.setOpaque(true);
    frame.setContentPane(contentPane);
    frame.pack();

    Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
    int n = ClientContext.isMac() ? 3 : 2;
    int x = (screen.width - frame.getPreferredSize().width) / 2;
    int y = (screen.height - frame.getPreferredSize().height) / n;
    frame.setLocation(x, y);

    blockGlass = new BlockGlass();
    frame.setGlassPane(blockGlass);

    frame.setVisible(true);
  }

  /** 終了する。 */
  public void stop() {
    frame.setVisible(false);
    frame.dispose();
  }

  /** 公開スタンプブラウズペインを生成する。 */
  private JPanel createBrowsePane() {

    JPanel browsePane = new JPanel();

    tableModel = new ListTableModel<PublishedTreeModel>(COLUMN_NAMES, 10, METHOD_NAMES, CLASSES);
    browseTable = new JTable(tableModel);
    for (int i = 0; i < COLUMN_WIDTH.length; i++) {
      browseTable.getColumnModel().getColumn(i).setPreferredWidth(COLUMN_WIDTH[i]);
    }
    browseTable.setDefaultRenderer(Object.class, new OddEvenRowRenderer());

    importBtn = new JButton("インポート");
    importBtn.setEnabled(false);
    cancelBtn = new JButton("閉じる");
    deleteBtn = new JButton("削除");
    deleteBtn.setEnabled(false);
    publicLabel = new JLabel("グローバル", WEB_ICON, SwingConstants.CENTER);
    localLabel = new JLabel("院内", HOME_ICON, SwingConstants.CENTER);
    importedLabel = new JLabel("インポート済", FLAG_ICON, SwingConstants.CENTER);

    JScrollPane tableScroller = new JScrollPane(browseTable);
    tableScroller.getViewport().setPreferredSize(new Dimension(730, 380));

    // レイアウトする
    browsePane.setLayout(new BorderLayout(0, 17));
    JPanel flagPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 7, 5));
    flagPanel.add(localLabel);
    flagPanel.add(publicLabel);
    flagPanel.add(importedLabel);
    JPanel cmdPanel =
        GUIFactory.createCommandButtonPanel(new JButton[] {cancelBtn, deleteBtn, importBtn});
    browsePane.add(flagPanel, BorderLayout.NORTH);
    browsePane.add(tableScroller, BorderLayout.CENTER);
    browsePane.add(cmdPanel, BorderLayout.SOUTH);

    // レンダラを設定する
    PublishTypeRenderer pubTypeRenderer = new PublishTypeRenderer();
    browseTable.getColumnModel().getColumn(4).setCellRenderer(pubTypeRenderer);
    ImportedRenderer importedRenderer = new ImportedRenderer();
    browseTable.getColumnModel().getColumn(5).setCellRenderer(importedRenderer);

    // BrowseTableをシングルセレクションにする
    browseTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    ListSelectionModel sleModel = browseTable.getSelectionModel();
    sleModel.addListSelectionListener(
        new ListSelectionListener() {

          @Override
          public void valueChanged(ListSelectionEvent e) {
            if (e.getValueIsAdjusting() == false) {
              int row = browseTable.getSelectedRow();
              PublishedTreeModel model = tableModel.getObject(row);
              if (model != null) {
                if (model.isImported()) {
                  importBtn.setEnabled(false);
                  deleteBtn.setEnabled(true);
                } else {
                  importBtn.setEnabled(true);
                  deleteBtn.setEnabled(false);
                }
              } else {
                importBtn.setEnabled(false);
                deleteBtn.setEnabled(false);
              }
            }
          }
        });

    // import
    importBtn.addActionListener(
        new ActionListener() {

          @Override
          public void actionPerformed(ActionEvent e) {
            importPublishedTree();
          }
        });

    // remove
    deleteBtn.addActionListener(
        new ActionListener() {

          @Override
          public void actionPerformed(ActionEvent e) {
            removeImportedTree();
          }
        });

    // キャンセル
    cancelBtn.addActionListener(
        new ActionListener() {

          @Override
          public void actionPerformed(ActionEvent e) {
            stop();
          }
        });

    return browsePane;
  }

  /** ブラウザテーブルで選択した公開Treeをインポートする。 */
  public void importPublishedTree() {

    // テーブルはシングルセレクションである
    int row = browseTable.getSelectedRow();
    final PublishedTreeModel importTree = tableModel.getObject(row);

    if (importTree == null) {
      return;
    }

    // Import 済みの場合
    if (importTree.isImported()) {
      return;
    }

    try {
      importTree.setTreeXml(new String(importTree.getTreeBytes(), "UTF-8"));
    } catch (Exception e) {
      e.printStackTrace(System.err);
    }

    // サブスクライブリストに追加する
    SubscribedTreeModel sm = new SubscribedTreeModel();
    sm.setUserModel(Project.getUserModel());
    sm.setTreeId(importTree.getId());
    final List<SubscribedTreeModel> subscribeList = new ArrayList<SubscribedTreeModel>(1);
    subscribeList.add(sm);

    final SimpleWorker worker =
        new SimpleWorker<Void, Void>() {

          @Override
          protected Void doInBackground() throws Exception {
            StampDelegater sdl = new StampDelegater();
            sdl.subscribeTrees(subscribeList);
            return null;
          }

          @Override
          protected void succeeded(Void result) {
            // スタンプボックスへインポートする
            stampBox.importPublishedTree(importTree);
            // Browser表示をインポート済みにする
            importTree.setImported(true);
            tableModel.fireTableDataChanged();
          }

          @Override
          protected void cancelled() {
            ClientContext.getBootLogger().debug("Task cancelled");
          }

          @Override
          protected void failed(java.lang.Throwable cause) {
            JOptionPane.showMessageDialog(
                frame,
                cause.getMessage(),
                ClientContext.getFrameTitle(title),
                JOptionPane.WARNING_MESSAGE);
            ClientContext.getBootLogger().warn(cause.getMessage());
          }

          @Override
          protected void startProgress() {
            delayCount = 0;
            blockGlass.block();
            taskTimer.start();
          }

          @Override
          protected void stopProgress() {
            taskTimer.stop();
            monitor.close();
            blockGlass.unblock();
            taskTimer = null;
            monitor = null;
          }
        };

    String message = "スタンプインポート";
    String note = "インポートしています...";
    Component c = frame;
    monitor = new ProgressMonitor(c, message, note, 0, maxEstimation / delay);

    taskTimer =
        new Timer(
            delay,
            new ActionListener() {

              @Override
              public void actionPerformed(ActionEvent e) {
                delayCount++;

                if (monitor.isCanceled() && (!worker.isCancelled())) {
                  // worker.cancel(true);
                  // No cancel

                } else if (delayCount >= monitor.getMaximum() && (!worker.isCancelled())) {
                  worker.cancel(true);

                } else {
                  monitor.setProgress(delayCount);
                }
              }
            });

    worker.execute();
  }

  /** インポートしているスタンプを削除する。 */
  public void removeImportedTree() {

    // 削除するTreeを取得する
    int row = browseTable.getSelectedRow();
    final PublishedTreeModel removeTree = tableModel.getObject(row);

    if (removeTree == null) {
      return;
    }

    SubscribedTreeModel sm = new SubscribedTreeModel();
    sm.setTreeId(removeTree.getId());
    sm.setUserModel(Project.getUserModel());
    final List<SubscribedTreeModel> list = new ArrayList<SubscribedTreeModel>(1);
    list.add(sm);

    // Unsubscribeタスクを実行する

    final SimpleWorker worker =
        new SimpleWorker<Void, Void>() {

          @Override
          protected Void doInBackground() throws Exception {
            StampDelegater sdl = new StampDelegater();
            sdl.unsubscribeTrees(list);
            return null;
          }

          @Override
          protected void succeeded(Void result) {
            // スタンプボックスから削除する
            stampBox.removeImportedTree(removeTree.getId());
            // ブラウザ表示を変更する
            removeTree.setImported(false);
            tableModel.fireTableDataChanged();
          }

          @Override
          protected void cancelled() {
            ClientContext.getBootLogger().debug("Task cancelled");
          }

          @Override
          protected void failed(java.lang.Throwable cause) {
            JOptionPane.showMessageDialog(
                frame,
                cause.getMessage(),
                ClientContext.getFrameTitle(title),
                JOptionPane.WARNING_MESSAGE);
            ClientContext.getBootLogger().warn(cause.getMessage());
          }

          @Override
          protected void startProgress() {
            delayCount = 0;
            blockGlass.block();
            taskTimer.start();
          }

          @Override
          protected void stopProgress() {
            taskTimer.stop();
            monitor.close();
            blockGlass.unblock();
            taskTimer = null;
            monitor = null;
          }
        };

    String message = "スタンプインポート";
    String note = "インポート済みスタンプを削除しています...";
    Component c = frame;
    monitor = new ProgressMonitor(c, message, note, 0, maxEstimation / delay);

    taskTimer =
        new Timer(
            delay,
            new ActionListener() {

              @Override
              public void actionPerformed(ActionEvent e) {
                delayCount++;

                if (monitor.isCanceled() && (!worker.isCancelled())) {
                  // worker.cancel(true);
                  // No cancel

                } else if (delayCount >= monitor.getMaximum() && (!worker.isCancelled())) {
                  worker.cancel(true);

                } else {
                  monitor.setProgress(delayCount);
                }
              }
            });

    worker.execute();
  }

  class PublishTypeRenderer extends DefaultTableCellRenderer {

    /** Creates new IconRenderer */
    public PublishTypeRenderer() {
      super();
      setOpaque(true);
      setHorizontalAlignment(JLabel.CENTER);
    }

    @Override
    public Component getTableCellRendererComponent(
        JTable table, Object value, boolean isSelected, boolean isFocused, int row, int col) {

      if (isSelected) {
        setBackground(table.getSelectionBackground());
        setForeground(table.getSelectionForeground());
      } else {
        setForeground(table.getForeground());
        if (row % 2 == 0) {
          setBackground(EVEN_COLOR);
        } else {
          setBackground(ODD_COLOR);
        }
      }

      if (value != null && value instanceof String) {

        String pubType = (String) value;

        if (pubType.equals(IInfoModel.PUBLISHED_TYPE_GLOBAL)) {
          setIcon(WEB_ICON);
        } else {
          setIcon(HOME_ICON);
        }
        this.setText("");

      } else {
        setIcon(null);
        this.setText(value == null ? "" : value.toString());
      }
      return this;
    }
  }

  class ImportedRenderer extends DefaultTableCellRenderer {

    /** Creates new IconRenderer */
    public ImportedRenderer() {
      super();
      setOpaque(true);
      setHorizontalAlignment(JLabel.CENTER);
    }

    @Override
    public Component getTableCellRendererComponent(
        JTable table, Object value, boolean isSelected, boolean isFocused, int row, int col) {

      if (isSelected) {
        setBackground(table.getSelectionBackground());
        setForeground(table.getSelectionForeground());
      } else {
        setForeground(table.getForeground());
        if (row % 2 == 0) {
          setBackground(EVEN_COLOR);
        } else {
          setBackground(ODD_COLOR);
        }
      }

      if (value != null && value instanceof Boolean) {

        Boolean imported = (Boolean) value;

        if (imported.booleanValue()) {
          this.setIcon(FLAG_ICON);
        } else {
          this.setIcon(null);
        }
        this.setText("");

      } else {
        setIcon(null);
        this.setText(value == null ? "" : value.toString());
      }
      return this;
    }
  }
}