// Copyright 2004-2014 Jim Voris // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // package com.qumasoft.guitools.compare; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.Font; import javax.swing.ImageIcon; import javax.swing.JPanel; import javax.swing.JList; import javax.swing.JLabel; import javax.swing.ListCellRenderer; import javax.swing.SwingConstants; class FileContentsList extends JList { private static final long serialVersionUID = -4251349514486534916L; private static final int NUMBER_WIDTH = 80; private static final int DEFAULT_FONT_SIZE = 12; private static final Color NORMAL_COLOR = new Color(0, 0, 0); private static final Color INSERT_COLOR = new Color(0, 125, 110); private static final Color DELETE_COLOR = new Color(255, 10, 0); private static final Color REPLACE_COLOR = new Color(0, 10, 255); private static final Color CHANGE_BACKGROUND_COLOR = new Color(210, 210, 210); private static FileContentsList lastClick = null; private final FileContentsListModel fileContentsListModel; private final ImageIcon emptyIcon = new ImageIcon(ClassLoader.getSystemResource("images/ClearTriRight.png")); private final ImageIcon currentDiffMarkerIcon = new ImageIcon(ClassLoader.getSystemResource("images/RedTriRight.png")); private final MouseClickListener mouseClickListener = new MouseClickListener(); private int maximumContentWidth = 0; private int height; private final CellRenderer cellRenderer; private final Font contentFont; FileContentsList(FileContentsListModel model, CompareFrame parentFrame) { super(model); this.contentFont = new Font("monospaced", Font.PLAIN, DEFAULT_FONT_SIZE); // m_ParentFrame = parentFrame; fileContentsListModel = model; cellRenderer = new CellRenderer(this); addMouseListener(mouseClickListener); if (lastClick == null) { lastClick = this; } setFont(new Font("monospaced", Font.PLAIN, DEFAULT_FONT_SIZE)); // Trap CTRL-C so we can use that to copy to clipboard. javax.swing.KeyStroke keyCopyToClipBoard = javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_C, java.awt.event.InputEvent.CTRL_DOWN_MASK); getInputMap(WHEN_FOCUSED).put(keyCopyToClipBoard, "copyToClipboardKeyAction"); getActionMap().put("copyToClipboardKeyAction", parentFrame.getEditCopyAction()); } @Override public ListCellRenderer getCellRenderer() { return cellRenderer; } static Color getNormalColor() { return NORMAL_COLOR; } static Color getInsertColor() { return INSERT_COLOR; } static Color getDeleteColor() { return DELETE_COLOR; } static Color getReplaceColor() { return REPLACE_COLOR; } static FileContentsList getLastFocus() { return lastClick; } int getRowHeight() { return height; } class CellRenderer extends JPanel implements ListCellRenderer { private static final long serialVersionUID = 3311420399900950454L; private ContentRow contentRow; private final JLabel lineNumber; private final JList jList; private static final int CELL_PADDING = 5; CellRenderer(JList list) { super(); this.lineNumber = new JLabel(); jList = list; setLayout(new BorderLayout(0, 0)); lineNumber.setForeground(NORMAL_COLOR); lineNumber.setHorizontalTextPosition(SwingConstants.RIGHT); lineNumber.setHorizontalAlignment(SwingConstants.RIGHT); height = jList.getFont().getSize() + CELL_PADDING; lineNumber.setPreferredSize(new Dimension(NUMBER_WIDTH, height)); lineNumber.setOpaque(true); setOpaque(true); } @Override public java.awt.Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { Color bkColor; removeAll(); contentRow = (ContentRow) getModel().getElementAt(index); if (contentRow.getRowType() != ContentRow.ROWTYPE_BLANK) { ContentRow row = contentRow; lineNumber.setText(row.getLineNumber()); if (row.getRowType() == ContentRow.ROWTYPE_DELETE) { contentRow.setForeground(DELETE_COLOR); bkColor = CHANGE_BACKGROUND_COLOR; } else if (row.getRowType() == ContentRow.ROWTYPE_REPLACE) { contentRow.setForeground(REPLACE_COLOR); bkColor = CHANGE_BACKGROUND_COLOR; } else if (row.getRowType() == ContentRow.ROWTYPE_INSERT) { contentRow.setForeground(INSERT_COLOR); bkColor = CHANGE_BACKGROUND_COLOR; } else { contentRow.setForeground(NORMAL_COLOR); bkColor = list.getBackground(); } int currentWidth = contentRow.getFontMetrics(contentRow.getFont()).stringWidth(contentRow.getText()); if (currentWidth > maximumContentWidth) { maximumContentWidth = currentWidth; } } else { contentRow.setForeground(NORMAL_COLOR); contentRow.setText(" "); lineNumber.setText(" "); bkColor = CHANGE_BACKGROUND_COLOR; } if (index == fileContentsListModel.getCurrentDifferenceIndex()) { lineNumber.setIcon(currentDiffMarkerIcon); } else { lineNumber.setIcon(emptyIcon); } add(BorderLayout.WEST, lineNumber); add(BorderLayout.CENTER, contentRow); if (isSelected) { contentRow.setBackground(list.getSelectionBackground()); contentRow.setForeground(list.getSelectionForeground()); lineNumber.setBackground(list.getSelectionBackground()); lineNumber.setForeground(list.getSelectionForeground()); } else { contentRow.setBackground(bkColor); lineNumber.setBackground(CHANGE_BACKGROUND_COLOR); lineNumber.setForeground(list.getForeground()); } contentRow.setEnabled(list.isEnabled()); contentRow.setFont(contentFont); contentRow.setOpaque(true); lineNumber.setFont(list.getFont()); return this; } @Override public int getWidth() { int width = lineNumber.getWidth() + contentRow.getWidth(); return width; } @Override public Dimension getPreferredSize() { Dimension preferredSize = new Dimension(NUMBER_WIDTH + maximumContentWidth, height); return preferredSize; } } class MouseClickListener extends MouseAdapter { @Override public void mouseClicked(MouseEvent e) { lastClick = FileContentsList.this; } } }