Google Tag Manager

2018/08/29

aterai

Change the tab of JTabbedPane to a flat design style

Code

UIManager.put("TabbedPane.tabInsets", new Insets(5, 10, 5, 10));
UIManager.put("TabbedPane.tabAreaInsets", new Insets(0, 0, 0, 0));
UIManager.put("TabbedPane.selectedLabelShift", 0);
UIManager.put("TabbedPane.labelShift", 0);

// UIManager.put("TabbedPane.foreground", Color.WHITE);
// UIManager.put("TabbedPane.selectedForeground", Color.WHITE);
// UIManager.put("TabbedPane.unselectedBackground", UNSELECTED_BG);
UIManager.put("TabbedPane.tabAreaBackground", UNSELECTED_BG);

JTabbedPane tabs = new JTabbedPane() {
  @Override public void updateUI() {
    super.updateUI();
    setUI(new BasicTabbedPaneUI() {
      @Override protected void paintFocusIndicator(
          Graphics g, int tabPlacement, Rectangle[] rects, int tabIndex,
          Rectangle iconRect, Rectangle textRect, boolean isSelected) {
        // Do not paint anything
      }
      @Override protected void paintTabBorder(
          Graphics g, int tabPlacement, int tabIndex,
          int x, int y, int w, int h, boolean isSelected) {
        // Do not paint anything
      }
      @Override  protected void paintTabBackground(
          Graphics g, int tabPlacement, int tabIndex,
          int x, int y, int w, int h, boolean isSelected) {
        g.setColor(isSelected ? SELECTED_BG : UNSELECTED_BG);
        g.fillRect(x, y, w, h);
      }
      @Override protected void paintContentBorderRightEdge(
          Graphics g, int tabPlacement, int selectedIndex,
          int x, int y, int w, int h) {
        g.setColor(SELECTED_BG);
        g.fillRect(x, y, w, h);
      }
      // ...
    });
    setOpaque(true);
    setForeground(Color.WHITE);
    setTabPlacement(SwingConstants.LEFT);
    setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
  }
};

References

2018/07/31

aterai

Syntax highlighting the source code in the JEditorPane

Code

// NG: color:#RGB
// OK: color:#RRGGBB
StyleSheet styleSheet = new StyleSheet();
styleSheet.addRule(".str {color:#008800}");
styleSheet.addRule(".kwd {color:#000088}");
styleSheet.addRule(".com {color:#880000}");
styleSheet.addRule(".typ {color:#660066}");
styleSheet.addRule(".lit {color:#006666}");
styleSheet.addRule(".pun {color:#666600}");
styleSheet.addRule(".pln {color:#000000}");
styleSheet.addRule(".tag {color:#000088}");
styleSheet.addRule(".atn {color:#660066}");
styleSheet.addRule(".atv {color:#008800}");
styleSheet.addRule(".dec {color:#660066}");

HTMLEditorKit htmlEditorKit = new HTMLEditorKit();
htmlEditorKit.setStyleSheet(styleSheet);
editor.setEditorKit(htmlEditorKit);
editor.setEditable(false);
// ...

private void loadFile(String path) {
  try (Stream<String> lines = Files.lines(
      Paths.get(path), Charset.forName("UTF-8"))) {
    String txt = lines.map(s -> s.replace("&", "&amp;")
                                 .replace("<", "&lt;")
                                 .replace(">", "&gt;"))
      .collect(Collectors.joining("\n"));
    editor.setText("<pre>" + prettify(engine, txt) + "\n</pre>");
  } catch (IOException ex) {
    ex.printStackTrace();
  }
}
private static ScriptEngine createEngine() {
  ScriptEngineManager manager = new ScriptEngineManager();
  ScriptEngine engine = manager.getEngineByName("JavaScript");
  try {
    Path path = Paths.get(MainPanel.class.getResource("prettify.js").toURI());
    try (Reader r = Files.newBufferedReader(path, StandardCharsets.UTF_8)) {
      engine.eval("var window={}, navigator=null;");
      engine.eval(r);
      return engine;
    }
  } catch (IOException | ScriptException | URISyntaxException ex) {
    ex.printStackTrace();
  }
  return null;
}
private static String prettify(ScriptEngine engine, String src) {
  try {
    Object w = engine.get("window");
    return (String) ((Invocable) engine).invokeMethod(
        w, "prettyPrintOne", src);
  } catch (ScriptException | NoSuchMethodException ex) {
    ex.printStackTrace();
    return "";
  }
}

References

2018/06/29

aterai

Move items by copying and pasting between JLists

Code

class ListPopupMenu extends JPopupMenu {
  private final JMenuItem cutItem;
  private final JMenuItem copyItem;
  protected ListPopupMenu(JList list) {
    super();
    Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
    TransferHandler handler = list.getTransferHandler();
    cutItem = add("cut");
    cutItem.addActionListener(e -> {
      handler.exportToClipboard(list, clipboard, TransferHandler.MOVE);
    });
    copyItem = add("copy");
    copyItem.addActionListener(e -> {
      handler.exportToClipboard(list, clipboard, TransferHandler.COPY);
    });
    add("paste").addActionListener(e -> {
      handler.importData(list, clipboard.getContents(null));
    });
    addSeparator();
    add("clearSelection").addActionListener(e -> list.clearSelection());
  }
  @Override public void show(Component c, int x, int y) {
    if (c instanceof JList) {
      boolean isSelected = !((JList) c).isSelectionEmpty();
      cutItem.setEnabled(isSelected);
      copyItem.setEnabled(isSelected);
      super.show(c, x, y);
    }
  }
}

// ...
private static int getIndex(TransferHandler.TransferSupport info) {
  JList target = (JList) info.getComponent();
  int index; // = dl.getIndex();
  if (info.isDrop()) { // Mouse Drag & Drop
    System.out.println("Mouse Drag & Drop");
    TransferHandler.DropLocation tdl = info.getDropLocation();
    if (tdl instanceof JList.DropLocation) {
      index = ((JList.DropLocation) tdl).getIndex();
    } else {
      index = target.getSelectedIndex();
    }
  } else { // Keyboard Copy & Paste
    index = target.getSelectedIndex();
  }
  DefaultListModel listModel = (DefaultListModel) target.getModel();
  // boolean insert = dl.isInsert();
  int max = listModel.getSize();
  // int index = dl.getIndex();
  index = index < 0 ? max : index; // If it is out of range, it is appended to the end
  index = Math.min(index, max);
  return index;
}

References

2018/05/25

aterai

Use JTable instead of JList as a drop down list of JComboBox

Code

class DropdownTableComboBox<E extends Vector<Object>> extends JComboBox<E> {
  protected final transient HighlightListener highlighter = new HighlightListener();
  protected final JTable table = new JTable() {
    @Override public Component prepareRenderer(
          TableCellRenderer renderer, int row, int column) {
      Component c = super.prepareRenderer(renderer, row, column);
      c.setForeground(Color.BLACK);
      if (highlighter.isHighlightableRow(row)) {
        c.setBackground(new Color(255, 200, 200));
      } else if (isRowSelected(row)) {
        c.setBackground(Color.CYAN);
      } else {
        c.setBackground(Color.WHITE);
      }
      return c;
    }
    @Override public void updateUI() {
      removeMouseListener(highlighter);
      removeMouseMotionListener(highlighter);
      super.updateUI();
      addMouseListener(highlighter);
      addMouseMotionListener(highlighter);
      getTableHeader().setReorderingAllowed(false);
    }
  };
  protected final List<E> list;

  protected DropdownTableComboBox(List<E> list, DefaultTableModel model) {
    super();
    this.list = list;
    table.setModel(model);
    list.forEach(this::addItem);
    list.forEach(model::addRow);
  }

  @Override public void updateUI() {
    super.updateUI();
    EventQueue.invokeLater(() -> {
      setUI(new MetalComboBoxUI() {
        @Override protected ComboPopup createPopup() {
          return new ComboTablePopup(comboBox, table);
        }
      });
      setEditable(false);
    });
  }
  public List<Object> getSelectedRow() {
    return list.get(getSelectedIndex());
  }
}

References

2018/04/26

aterai

Move large numbers of items to another JList as fast as possible

Code

private static <E> void move1(JList<E> from, JList<E> to) {
  ListSelectionModel sm = from.getSelectionModel();
  int[] selectedIndices = from.getSelectedIndices();

  DefaultListModel<E> fromModel = (DefaultListModel<E>) from.getModel();
  DefaultListModel<E> toModel = (DefaultListModel<E>) to.getModel();
  List<E> unselectedValues = new ArrayList<>();
  for (int i = 0; i < fromModel.getSize(); i++) {
    if (!sm.isSelectedIndex(i)) {
      unselectedValues.add(fromModel.getElementAt(i));
    }
  }
  if (selectedIndices.length > 0) {
    for (int i: selectedIndices) {
      toModel.addElement(fromModel.get(i));
    }
    fromModel.clear();
    unselectedValues.forEach(fromModel::addElement);
  }
}

References