Google Tag Manager

2011/11/28

JTable group directories first sorting

Code

// > dir /O:GN
// > ls --group-directories-first
class FileGroupComparator extends DefaultFileComparator {
  private static final long serialVersionUID = 1L;
  private final JTable table;
  public FileGroupComparator(JTable table, int column) {
    super(column);
    this.table = table;
  }

  @Override public int compare(File a, File b) {
    int flag = 1;
    List<? extends TableRowSorter.SortKey> keys =
        table.getRowSorter().getSortKeys();
    if (!keys.isEmpty()) {
      TableRowSorter.SortKey sortKey = keys.get(0);
      if (sortKey.getColumn() == column &&
          sortKey.getSortOrder() == SortOrder.DESCENDING) {
        flag = -1;
      }
    }
    if (a.isDirectory() && !b.isDirectory()) {
      return -1 * flag;
    } else if (!a.isDirectory() && b.isDirectory()) {
      return 1 * flag;
    } else {
      return super.compare(a, b);
    }
  }
}

References

2011/10/28

fixed width JButtons in bottom right corner of the JPanel

Code

private static JComponent createRightAlignButtonBox2(
  List<JButton> list, final int buttonWidth, int gap) {
  JComponent box = new JPanel() {
    @Override public void updateUI() {
      for (JButton b : list) {
        b.setPreferredSize(null);
      }
      super.updateUI();
      EventQueue.invokeLater(new Runnable() {
        @Override public void run() {
          int maxHeight = list.stream()
            .map(b -> b.getPreferredSize().height)
            .reduce(0, Integer::max);
          Dimension d = new Dimension(buttonWidth, maxHeight);
          for (JButton b : list) {
            b.setPreferredSize(d);
          }
          revalidate();
        }
      });
    }
  };
  box.setLayout(new BoxLayout(box, BoxLayout.X_AXIS));
  box.add(Box.createHorizontalGlue());
  for (JButton b : list) {
    box.add(b);
    box.add(Box.createHorizontalStrut(gap));
  }
  box.setBorder(BorderFactory.createEmptyBorder(gap, 0, gap, 0));
  return box;
}

References

2011/09/29

JProgressBar in JComboBox

Code

class ProgressCellRenderer extends DefaultListCellRenderer {
  private final JProgressBar bar = new JProgressBar() {
    @Override public Dimension getPreferredSize() {
      return ProgressCellRenderer.this.getPreferredSize();
    }
  };

  @Override public Component getListCellRendererComponent(
      JList list, Object value, int index,
      boolean isSelected, boolean cellHasFocus) {
    if (index < 0 && worker != null && !worker.isDone()) {
      bar.setFont(list.getFont());
      bar.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
      bar.setValue(count);
      return bar;
    } else {
      return super.getListCellRendererComponent(
        list, value, index, isSelected, cellHasFocus);
    }
  }

  @Override public void updateUI() {
    super.updateUI();
    if (bar != null) {
      SwingUtilities.updateComponentTreeUI(bar);
    }
  }
}

// ...
button = new JButton(new AbstractAction("load") {
  @Override public void actionPerformed(ActionEvent e) {
    button.setEnabled(false);
    combo.setEnabled(false);
    combo.removeAllItems();
    worker = new SwingWorker<String, String>() {
      private int max = 30;
      @Override public String doInBackground() throws InterruptedException {
        int current = 0;
        while (current <= max && !isCancelled()) {
          Thread.sleep(50);
          // setProgress(100 * current / max);
          count = 100 * current / max;
          publish("test: "+current);
          current++;
        }
        return "Done";
      }

      @Override protected void process(List<String> chunks) {
        DefaultComboBoxModel m = (DefaultComboBoxModel) combo.getModel();
        for (String s: chunks) {
          m.addElement(s);
        }
        combo.setSelectedIndex(-1);
        combo.repaint();
      }

      @Override public void done() {
        String text = null;
        if (!isCancelled()) {
          combo.setSelectedIndex(0);
        }
        combo.setEnabled(true);
        button.setEnabled(true);
        count = 0;
      }
    };
    worker.execute();
  }
});

References

2011/08/29

FileSystemTree with JCheckBox

Code

class CheckBoxNodeEditor extends TriStateCheckBox implements TreeCellEditor {
  private final FileSystemView fileSystemView;
  private final JPanel panel = new JPanel(new BorderLayout());
  private DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer();
  private File file;

  public CheckBoxNodeEditor(FileSystemView fileSystemView) {
    super();
    this.fileSystemView = fileSystemView;
    this.addActionListener(new ActionListener() {
      @Override public void actionPerformed(ActionEvent e) {
        stopCellEditing();
      }
    });
    panel.setFocusable(false);
    panel.setRequestFocusEnabled(false);
    panel.setOpaque(false);
    panel.add(this, BorderLayout.WEST);
    this.setOpaque(false);
  }

  @Override public Component getTreeCellEditorComponent(
      JTree tree, Object value, boolean isSelected, boolean expanded,
      boolean leaf, int row) {
    JLabel l = (JLabel) renderer.getTreeCellRendererComponent(
      tree, value, true, expanded, leaf, row, true);
    l.setFont(tree.getFont());
    setOpaque(false);
    if (value instanceof DefaultMutableTreeNode) {
      this.setEnabled(tree.isEnabled());
      this.setFont(tree.getFont());
      Object userObject = ((DefaultMutableTreeNode) value).getUserObject();
      if (userObject instanceof CheckBoxNode) {
        CheckBoxNode node = (CheckBoxNode) userObject;
        if (node.status == Status.INDETERMINATE) {
          setIcon(new IndeterminateIcon());
        } else {
          setIcon(null);
        }
        file = node.file;
        l.setIcon(fileSystemView.getSystemIcon(file));
        l.setText(fileSystemView.getSystemDisplayName(file));
        setSelected(node.status == Status.SELECTED);
      }
      // panel.add(this, BorderLayout.WEST);
      panel.add(l);
      return panel;
    }
    return l;
  }

  @Override public Object getCellEditorValue() {
    return new CheckBoxNode(file, isSelected() ? Status.SELECTED : Status.DESELECTED);
  }

  @Override public boolean isCellEditable(EventObject e) {
    if (e instanceof MouseEvent && e.getSource() instanceof JTree) {
      MouseEvent me = (MouseEvent) e;
      JTree tree = (JTree) e.getSource();
      TreePath path = tree.getPathForLocation(me.getX(), me.getY());
      Rectangle r = tree.getPathBounds(path);
      if (r == null) {
        return false;
      }
      Dimension d = getPreferredSize();
      r.setSize(new Dimension(d.width, r.height));
      if (r.contains(me.getX(), me.getY())) {
        // if (file == null && System.getProperty("java.version").startsWith("1.7.0")) {
        //   System.out.println("XXX: Java 7, only on first run\n" + getBounds());
        //   setBounds(new Rectangle(0, 0, d.width, r.height));
        // }
        return true;
      }
    }
    return false;
  }

  @Override public void updateUI() {
    super.updateUI();
    if (panel != null) {
      panel.updateUI();
    }
    // 1.6.0_24 bug??? @see 1.7.0 DefaultTreeCellRenderer#updateUI()
    renderer = new DefaultTreeCellRenderer();
  }
// ...

References

2011/07/29

Pause and Resume SwingWorker

Code

class RunAction extends AbstractAction {
  public RunAction() {
    super("run");
  }

  @Override public void actionPerformed(ActionEvent evt) {
    JProgressBar bar1 = new JProgressBar(0, 100);
    JProgressBar bar2 = new JProgressBar(0, 100);
    runButton.setEnabled(false);
    canButton.setEnabled(true);
    pauseButton.setEnabled(true);
    statusPanel.removeAll();
    statusPanel.add(bar1, BorderLayout.NORTH);
    statusPanel.add(bar2, BorderLayout.SOUTH);
    statusPanel.revalidate();
    worker = new SwingWorker<String, Progress>() {
      private final Random r = new Random();
      @Override public String doInBackground() {
        int current = 0;
        int lengthOfTask = 12; //filelist.size();
        publish(new Progress(Component.LOG, "Length Of Task: " + lengthOfTask));
        publish(new Progress(Component.LOG, "\n---------------------------\n"));
        while (current < lengthOfTask && !isCancelled()) {
          publish(new Progress(Component.LOG, "*"));
          if (!bar1.isDisplayable()) {
            return "Disposed";
          }
          try {
            convertFileToSomething();
          } catch (InterruptedException ie) {
            return "Interrupted";
          }
          publish(new Progress(Component.TOTAL, 100 * current / lengthOfTask));
          current++;
        }
        publish(new Progress(Component.LOG, "\n"));
        return "Done";
      }

      private void convertFileToSomething() throws InterruptedException {
        boolean flag = false;
        int current = 0;
        int lengthOfTask = 10 + r.nextInt(50);
        while (current <= lengthOfTask && !isCancelled()) {
          if (isPaused) {
            try {
              Thread.sleep(500);
            } catch (InterruptedException ie) {
              return;
            }
            publish(new Progress(Component.PAUSE, flag));
            flag ^= true;
            continue;
          }
          int iv = 100 * current / lengthOfTask;
          Thread.sleep(20);
          publish(new Progress(Component.FILE, iv + 1));
          current++;
        }
      }

      @Override protected void process(java.util.List<Progress> chunks) {
        for (Progress s: chunks) {
          switch (s.component) {
            case TOTAL: bar1.setValue((Integer) s.value); break;
            case FILE:  bar2.setValue((Integer) s.value); break;
            case LOG:   area.append((String) s.value); break;
            case PAUSE: {
              if ((Boolean) s.value) {
                area.append("*");
              } else {
                try {
                  Document doc = area.getDocument();
                  doc.remove(doc.getLength() - 1, 1);
                } catch (Exception ex) {
                  ex.printStackTrace();
                }
              }
              break;
            }
          }
        }
      }

      @Override public void done() {
        // ...
      }
    };
    worker.execute();
  }
}

// ...
private boolean isPaused = false;
class PauseAction extends AbstractAction {
  public PauseAction() {
    super("pause");
  }

  @Override public void actionPerformed(ActionEvent evt) {
    isPaused = (worker != null && !worker.isCancelled() && !isPaused);
    JButton b = (JButton) evt.getSource();
    b.setText(isPaused ? "resume" : "pause");
  }
}

References