package org.chartsy.stockscanpro.ui; import java.awt.Color; import java.awt.Component; import java.awt.Graphics; import java.awt.Insets; import java.awt.Rectangle; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.Writer; import java.util.ArrayList; import java.util.List; import javax.swing.BorderFactory; import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.ListCellRenderer; import javax.swing.ListSelectionModel; import org.chartsy.main.utils.FileUtils; import org.openide.util.NbBundle; /** * * @author Viorel */ public class JCheckList extends JList { public Color rowColors[] = new Color[2]; private boolean drawStripes = true; private JLabel listener; private int selectedItems = 0; private String selectedExcg = ""; public JCheckList() { setListData(createData()); setSelectionMode(ListSelectionModel.SINGLE_SELECTION); setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); addMouseListener(new MouseListener() { public void mouseClicked(MouseEvent e) {} public void mousePressed(MouseEvent e) { int index = JCheckList.this.locationToIndex(e.getPoint()); CheckableItem item = (CheckableItem) JCheckList.this.getModel().getElementAt(index); boolean selected = !item.isSelected(); item.setSelected(selected); Rectangle rectangle = JCheckList.this.getCellBounds(index, index); JCheckList.this.repaint(rectangle); if (selected) { selectedItems++; if (selectedItems > JCheckList.this.getModel().getSize()) selectedItems = JCheckList.this.getModel().getSize(); } else { selectedItems--; if (selectedItems < 0) selectedItems = 0; } fireExchangeChange(); } public void mouseReleased(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} }); if (getModel().getSize() > 0) setSelectedIndex(0); } public void setExchangeListener(JLabel label) { this.listener = label; } public void fireExchangeChange() { StringBuilder builder = new StringBuilder(); for (int i = 0; i < getModel().getSize(); i++) { CheckableItem item = (CheckableItem) getModel().getElementAt(i); if (item.isSelected()) { builder.append(item.getExchange()).append(":"); } } if (builder.length() > 1) { builder.deleteCharAt(builder.length() - 1); writeSelectedXcg(builder.toString()); } if (listener != null) { listener.setText(selectedItems + " exchange(s) are selected."); listener.repaint(listener.getBounds()); } } public @Override Object[] getSelectedValues() { List<Object> list = new ArrayList<Object>(); for (int i = 0; i < getModel().getSize(); i++) { Object obj = getModel().getElementAt(i); if (obj instanceof CheckableItem) if (((CheckableItem) obj).isSelected()) list.add(obj); } return list.toArray(new Object[list.size()]); } public int getSelectedItems() { return selectedItems; } public @Override int getVisibleRowCount() { return Math.min(getModel().getSize(), 10); } public @Override boolean isOpaque() { return true; } private String readSelectedXcg() { File file = FileUtils.stockScanFile("selxcg.txt"); if (!file.exists()) { FileUtils.createFile(file.getAbsolutePath()); return ""; } try { StringBuilder contents = new StringBuilder(); BufferedReader input = new BufferedReader(new FileReader(file)); String line = null; while ((line = input.readLine()) != null) { contents.append(line); } input.close(); return contents.toString(); } catch (IOException ex) { return ""; } } private void writeSelectedXcg(String contents) { File file = FileUtils.stockScanFile("selxcg.txt"); if (!file.exists()) FileUtils.createFile(file.getAbsolutePath()); try { Writer output = new BufferedWriter(new FileWriter(file)); output.write(contents); output.close(); } catch (IOException ex) {} } private CheckableItem[] createData() { String defaultExchanges = NbBundle.getMessage(JCheckList.class, "DFLT_Exchange"); String selectedExchanges = readSelectedXcg(); if (selectedExchanges.isEmpty()) { selectedItems = defaultExchanges.split(":").length; selectedExcg = defaultExchanges; } else { selectedItems = selectedExchanges.split(":").length; selectedExcg = selectedExchanges; } int length = NbBundle.getMessage(JCheckList.class, "LIST_Exchange").split(":").length; CheckableItem[] list = new CheckableItem[length]; for (int i = 0; i < length; i++) { CheckableItem item = new CheckableItem(NbBundle.getMessage(JCheckList.class, "LIST_Exchange").split(":")[i]); if (isDefault(item.getExchange())) item.setSelected(true); list[i] = item; } return list; } private boolean isDefault(String exchange) { return selectedExcg.contains(exchange); } protected @Override void paintComponent(Graphics g) { if (!drawStripes) { super.paintComponent(g); return; } updateZebraColors(); final Insets insets = getInsets(); final int width = getWidth() - insets.left - insets.right; final int height = getHeight() - insets.top - insets.bottom; final int x = insets.left; int y = insets.top; int nRows = 0; int startRow = 0; int rowHeight = getFixedCellHeight(); if (rowHeight > 0) nRows = height / rowHeight; else { final int nItems = getModel().getSize(); rowHeight = 17; for (int i = 0; i < nItems; i++) { rowHeight = getCellBounds(i, i).height; g.setColor(rowColors[i&1]); g.fillRect(x, y, width, rowHeight); } nRows = nItems + (insets.top + height - y) / rowHeight; startRow = nItems; } for (int i = startRow; i < nRows; i++, y += rowHeight) { g.setColor(rowColors[i&1]); g.fillRect(x, y, width, rowHeight); } final int remainder = insets.top + height - y; if (remainder > 0) { g.setColor(rowColors[nRows&1]); g.fillRect(x, y, width, remainder); } setOpaque(false); super.paintComponent(g); setOpaque(true); } class CheckableItem { private String exchange; private boolean isSelected; public CheckableItem(String string) { this.exchange = string; this.isSelected = false; } public String getExchange() { return exchange; } public String getTooltip() { return NbBundle.getMessage(JCheckList.class, exchange + "_Desc"); } public void setSelected(boolean b) { isSelected = b; } public boolean isSelected() { return isSelected; } public @Override String toString() { return exchange + " (" + NbBundle.getMessage(JCheckList.class, exchange + "_Desc") + ")"; } } class JCheckListRenderer implements ListCellRenderer { public ListCellRenderer ren = null; public JCheckListRenderer() {} public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { final JCheckBox box = new JCheckBox(); CheckableItem item = (CheckableItem) value; box.setSelected(item.isSelected()); box.setText(item.toString()); box.setToolTipText(item.getTooltip()); box.setOpaque(true); if (!isSelected && drawStripes) box.setBackground(rowColors[index&1]); if (isSelected) { box.setBackground(Color.decode("0x6BBA70")); box.setForeground(Color.decode("0xFFFFFF")); } return box; } } private JCheckListRenderer wrapper = null; public @Override ListCellRenderer getCellRenderer() { final ListCellRenderer ren = super.getCellRenderer(); if (ren == null) return null; if (wrapper == null) wrapper = new JCheckListRenderer(); wrapper.ren = ren; return wrapper; } private void updateZebraColors() { if ((rowColors[0] = getBackground()) == null) { rowColors[0] = rowColors[1] = java.awt.Color.white; return; } final java.awt.Color sel = getSelectionBackground(); if (sel == null) { rowColors[1] = rowColors[0]; return; } final float[] bgHSB = java.awt.Color.RGBtoHSB( rowColors[0].getRed(), rowColors[0].getGreen(), rowColors[0].getBlue(), null); final float[] selHSB = java.awt.Color.RGBtoHSB( sel.getRed(), sel.getGreen(), sel.getBlue(), null ); rowColors[1] = java.awt.Color.getHSBColor( (selHSB[1]==0.0||selHSB[2]==0.0) ? bgHSB[0] : selHSB[0], 0.1f * selHSB[1] + 0.9f * bgHSB[1], bgHSB[2] + ((bgHSB[2]<0.5f) ? 0.05f : -0.05f)); } }