Logo Search packages:      
Sourcecode: pauker version File versions  Download package

BatchListCellRenderer.java

/*
 * CardPanel.java
 *
 * Created on 5. Januar 2003, 15:48
 */

package pauker.program.gui.swing;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.text.DateFormat;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.ListCellRenderer;
import javax.swing.text.DefaultHighlighter;
import javax.swing.text.Highlighter;
import javax.swing.text.View;
import pauker.program.Card;
import pauker.program.CardSide;
import pauker.program.SearchHit;

/**
 * A renderer for cards in a batch list
 * @author Ronny.Standtke@gmx.net
 */
00035 public class BatchListCellRenderer extends JPanel implements ListCellRenderer {

    private final Color selectedColor;
    private final Color backgroundColor;
    private final PaukerFrame paukerFrame;
    private static final Logger logger =
            Logger.getLogger(BatchListCellRenderer.class.getName());
    // icons
    private static final Icon typingIcon = new ImageIcon(
            BatchListCellRenderer.class.getResource(
            "/pauker/icons/key_enter.png"));
    private static final Icon brainIcon = new ImageIcon(
            BatchListCellRenderer.class.getResource(
            "/pauker/icons/smallbrain.png"));
    // painters
    private static final Highlighter.HighlightPainter yellowPainter =
            new DefaultHighlighter.DefaultHighlightPainter(Color.yellow);
    private static final Highlighter.HighlightPainter redPainter =
            new DefaultHighlighter.DefaultHighlightPainter(Color.red);
    // some STRINGS that we use all the time
    private static final String expiredString =
            PaukerFrame.STRINGS.getString("Expired_At");
    private static final String expiresString =
            PaukerFrame.STRINGS.getString("Expires_At");
    private static final String learnedString =
            PaukerFrame.STRINGS.getString("Learned_At");
    private static final String notLearnedString =
            PaukerFrame.STRINGS.getString("Not_learned");
    private static final DateFormat dateFormat =
            DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.SHORT);
    private boolean brainIconSet;
    private boolean wasSelected;
    private boolean lineWrapping;

    /**
     * Creates new form CardPanel
     * @param paukerFrame the main Pauker frame
     * @param selectedColor the color to use for selection background
     */
00074     public BatchListCellRenderer(PaukerFrame paukerFrame, Color selectedColor) {
        this.paukerFrame = paukerFrame;
        this.selectedColor = selectedColor;
        backgroundColor = getBackground();
        initComponents();
        brainIconSet = true;
    }

    /**
     * Return a component that has been configured to display the specified
     * card.
     * @param list The JList we're painting.
     * @param object The card
     * @param index the cell index
     * @param isSelected <CODE>true</CODE>, if the cell is selected
     * @param cellHasFocus <CODE>true</CODE>, if the cell has the focus
     * @return a component that has been configured to display the specified
     * card
     */
00093     public java.awt.Component getListCellRendererComponent(
            JList list, Object object,
            int index, boolean isSelected, boolean cellHasFocus) {
        Card card = (Card) object;

        // front side
        CardSide frontSide = card.getFrontSide();
        PaukerFrame.fillTextComponentWithCardSide(frontSide,
                frontSideTextArea, false);

        // reverse side
        CardSide reverseSide = card.getReverseSide();
        PaukerFrame.fillTextComponentWithCardSide(reverseSide,
                reverseSideTextArea, false);

        // set RED & YELLOW search marks
        highLight(card, Card.Element.FRONT_SIDE, frontSideTextArea);
        highLight(card, Card.Element.REVERSE_SIDE, reverseSideTextArea);

        // lazy change of background color
        if (isSelected) {
            if (!wasSelected) {
                setBackgroundColor(selectedColor);
                wasSelected = true;
            }
        } else {
            if (wasSelected) {
                setBackgroundColor(backgroundColor);
                wasSelected = false;
            }
        }

        if (card.isLearned()) {
            int longTermBatchNumber = card.getLongTermBatchNumber();
            String longTermBatchString =
                    String.valueOf(longTermBatchNumber + 1);
            PaukerFrame.lazyStringChange(
                    batchNumberTextField, longTermBatchString);
            if (isSelected) {
                lazyBackgroundChange(batchNumberTextField, selectedColor);
            } else {
                lazyBackgroundChange(batchNumberTextField, backgroundColor);
            }
            long now = System.currentTimeMillis();
            long expirationTime = card.getExpirationTime();
            if (expirationTime < now) {
                // the card is expired
                if (isSelected) {
                    lazyBackgroundChange(learnedLabel, selectedColor);
                    lazyBackgroundChange(learnedDateTextField, selectedColor);
                } else {
                    lazyBackgroundChange(learnedLabel, backgroundColor);
                    lazyBackgroundChange(learnedDateTextField, backgroundColor);
                }
                PaukerFrame.lazyStringChange(expiredLabel, expiredString);
                lazyBackgroundChange(expiredLabel, PaukerFrame.BLUE);
                lazyBackgroundChange(expirationTextField, PaukerFrame.BLUE);

            } else {
                // the card is not expired
                PaukerFrame.lazyStringChange(expiredLabel, expiresString);
                lazyBackgroundChange(learnedLabel, PaukerFrame.GREEN);
                lazyBackgroundChange(learnedDateTextField, PaukerFrame.GREEN);
                if (isSelected) {
                    lazyBackgroundChange(expiredLabel, selectedColor);
                    lazyBackgroundChange(expirationTextField, selectedColor);
                } else {
                    lazyBackgroundChange(expiredLabel, backgroundColor);
                    lazyBackgroundChange(expirationTextField, backgroundColor);
                }
            }
            PaukerFrame.lazyStringChange(learnedLabel, learnedString);

            // the following textfields have always different values
            // (no need for "lazy" changes...)
            Date learnedDate = new Date(card.getLearnedTimestamp());
            learnedDateTextField.setText(dateFormat.format(learnedDate));
            expirationTextField.setText(dateFormat.format(expirationTime));

        } else {
            // the card is not learned
            PaukerFrame.lazyStringChange(
                    batchNumberTextField, notLearnedString);
            lazyBackgroundChange(batchNumberTextField, PaukerFrame.RED);
            PaukerFrame.lazyStringChange(learnedLabel, "");
            PaukerFrame.lazyStringChange(learnedDateTextField, "");
            // learnedDateTextField background is set above depending on
            // "isSelected"
            PaukerFrame.lazyStringChange(expiredLabel, "");
            PaukerFrame.lazyStringChange(expirationTextField, "");
            if (isSelected) {
                lazyBackgroundChange(learnedDateTextField, selectedColor);
                lazyBackgroundChange(expirationTextField, selectedColor);
            } else {
                lazyBackgroundChange(learnedDateTextField, backgroundColor);
                lazyBackgroundChange(expirationTextField, backgroundColor);
            }
        }

        // set repeating icon
        if (card.isRepeatedByTyping()) {
            if (brainIconSet) {
                repeatByTypingLabel.setIcon(typingIcon);
                brainIconSet = false;
            }
        } else {
            if (!brainIconSet) {
                repeatByTypingLabel.setIcon(brainIcon);
                brainIconSet = true;
            }
        }

        // Scheisse! Why do I always have to fix that Swing crap!?
        if (lineWrapping) {
            String frontSideText = frontSide.getText();
            int frontTextLenth =
                    getUnWrappedTextWidth(frontSideTextArea, frontSideText);
            String reverseSideText = reverseSide.getText();
            int reverseTextLenth =
                    getUnWrappedTextWidth(reverseSideTextArea, reverseSideText);
            int textLengthSum = frontTextLenth + reverseTextLenth;
            int listWidth = list.getWidth();
            // 23 = 3 + 3 + 3 + 5 + 3 + 3 + 3 
            // (insets, border, border, insets, border, border, insets)
            int widthForText = listWidth - 23;

            if (frontTextLenth > reverseTextLenth) {
                // layout reverse side first
                layoutTextAreas(widthForText, textLengthSum,
                        reverseTextLenth, reverseSideTextArea,
                        frontTextLenth, frontSideTextArea);
            } else {
                // layout front side first
                layoutTextAreas(widthForText, textLengthSum,
                        frontTextLenth, frontSideTextArea,
                        reverseTextLenth, reverseSideTextArea);
            }
        }

        return this;
    }

    /**
     * determines, if the renderer should automatically line wrap
     * @param lineWrap <CODE>true</CODE>, if the renderer should automatically
     * line wrap,
     * <CODE>false</CODE> otherwise
     */
00241     public void setLineWrap(boolean lineWrap) {
        lineWrapping = lineWrap;
        frontSideTextArea.setLineWrap(lineWrap);
        reverseSideTextArea.setLineWrap(lineWrap);
        if (!lineWrap) {
            reverseSideTextArea.setPreferredSize(null);
            frontSideTextArea.setPreferredSize(null);
            setPreferredSize(null);
        }
    }

    /**
     * hides the info panel at the bottom of the renderer (e.g. when used in the
     * list
     * of similar words)
     */
00257     public void disableInfoPanel() {
        infoPanel.setVisible(false);
    }

    private static int getUnWrappedTextWidth(JTextArea textArea, String text) {
        FontMetrics fontMetrics = textArea.getFontMetrics(textArea.getFont());
        return fontMetrics.stringWidth(text);
    }

    private static void layoutTextAreas(int widthForText, int textLengthSum,
            int shortTextWidth, JTextArea shortTextArea,
            int longTextWidth, JTextArea longTextArea) {

        /***** short side ****/
        // determine how much x-space we can use for the short side
        int xAxisSpan = (widthForText * shortTextWidth) / textLengthSum;
        // enforce at least one character width (depends on font size)
        FontMetrics fontMetrics =
                shortTextArea.getFontMetrics(shortTextArea.getFont());
        int charWidth = fontMetrics.charWidth('m');
        if (xAxisSpan < charWidth) {
            xAxisSpan = charWidth;
        }
        setPreferredSize(shortTextArea, xAxisSpan);

        /***** long side ****/
        int remainingWidth = widthForText - xAxisSpan;
        if (longTextWidth > remainingWidth) {
            longTextWidth = remainingWidth;
        }
        setPreferredSize(longTextArea, longTextWidth);
    }

    private static void setPreferredSize(JTextArea textArea, int xAxisSpan) {
        View view = textArea.getUI().getRootView(textArea);
        view.setSize(xAxisSpan, Float.MAX_VALUE);
        int preferredYSpan = (int) view.getPreferredSpan(View.Y_AXIS);
        // 6 = 3 + 3 (border, border)
        textArea.setPreferredSize(new Dimension(xAxisSpan, preferredYSpan + 6));
    }

    private void lazyBackgroundChange(JComponent component, Color color) {
        if (!component.getBackground().equals(color)) {
            component.setBackground(color);
        }
    }

    private void setBackgroundColor(Color color) {
        setBackground(color);
        contentsPanel.setBackground(color);
        infoPanel.setBackground(color);
        learnedLabel.setBackground(color);
        learnedDateTextField.setBackground(color);
        expiredLabel.setBackground(color);
        expirationTextField.setBackground(color);
    }

    private void highLight(
            Card card, Card.Element cardSide, JTextArea textArea) {

        Highlighter highlighter = textArea.getHighlighter();
        highlighter.removeAllHighlights();

        List<SearchHit> searchHits = null;
        if (cardSide == Card.Element.FRONT_SIDE) {
            searchHits = card.getFrontSide().getSearchHits();
        } else {
            searchHits = card.getReverseSide().getSearchHits();
        }

        if (searchHits != null && paukerFrame != null) {
            try {
                int patternLength = paukerFrame.getSearchPatternLength();

                // do the RED highlight if we are there
                SearchHit currentSearchHit = paukerFrame.getCurrentSearchHit();
                if ((currentSearchHit != null) &&
                        (currentSearchHit.getCard() == card) &&
                        (currentSearchHit.getCardSide() == cardSide)) {
                    int index = currentSearchHit.getCardSideIndex();
                    highlighter.addHighlight(
                            index, index + patternLength, redPainter);
                }

                // do all YELLOW highlights
                for (SearchHit searchHit : searchHits) {
                    int index = searchHit.getCardSideIndex();
                    highlighter.addHighlight(
                            index, index + patternLength, yellowPainter);
                }
            } catch (Exception e) {
                logger.log(Level.SEVERE, null, e);
            }
        }
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc=" Erzeugter Quelltext ">//GEN-BEGIN:initComponents
00359     private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        contentsPanel = new javax.swing.JPanel();
        frontSideTextArea = new javax.swing.JTextArea();
        reverseSideTextArea = new javax.swing.JTextArea();
        infoPanel = new javax.swing.JPanel();
        batchNumberLabel = new javax.swing.JLabel();
        batchNumberTextField = new javax.swing.JTextField();
        learnedLabel = new javax.swing.JLabel();
        learnedDateTextField = new javax.swing.JTextField();
        repeatByTypingLabel = new javax.swing.JLabel();
        expiredLabel = new javax.swing.JLabel();
        expirationTextField = new javax.swing.JTextField();
        jSeparator1 = new javax.swing.JSeparator();

        setLayout(new java.awt.GridBagLayout());

        contentsPanel.setLayout(new java.awt.GridBagLayout());

        frontSideTextArea.setWrapStyleWord(true);
        frontSideTextArea.setBorder(javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createLineBorder(null), javax.swing.BorderFactory.createEmptyBorder(2, 2, 2, 2)));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        contentsPanel.add(frontSideTextArea, gridBagConstraints);

        reverseSideTextArea.setWrapStyleWord(true);
        reverseSideTextArea.setBorder(javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createLineBorder(null), javax.swing.BorderFactory.createEmptyBorder(2, 2, 2, 2)));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0);
        contentsPanel.add(reverseSideTextArea, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(3, 3, 3, 3);
        add(contentsPanel, gridBagConstraints);

        infoPanel.setLayout(new java.awt.GridBagLayout());

        batchNumberLabel.setFont(new java.awt.Font("Dialog", 0, 10));
        java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("pauker/Strings"); // NOI18N
        batchNumberLabel.setText(bundle.getString("Batch")); // NOI18N
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(3, 4, 0, 0);
        infoPanel.add(batchNumberLabel, gridBagConstraints);

        batchNumberTextField.setEditable(false);
        batchNumberTextField.setFont(new java.awt.Font("Dialog", 0, 10));
        batchNumberTextField.setBorder(null);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(3, 10, 0, 0);
        infoPanel.add(batchNumberTextField, gridBagConstraints);

        learnedLabel.setFont(new java.awt.Font("Dialog", 0, 10));
        learnedLabel.setText(bundle.getString("Learned_At")); // NOI18N
        learnedLabel.setOpaque(true);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(3, 10, 0, 0);
        infoPanel.add(learnedLabel, gridBagConstraints);

        learnedDateTextField.setEditable(false);
        learnedDateTextField.setFont(new java.awt.Font("Dialog", 0, 10));
        learnedDateTextField.setBorder(null);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(3, 10, 0, 3);
        infoPanel.add(learnedDateTextField, gridBagConstraints);

        repeatByTypingLabel.setFont(new java.awt.Font("Dialog", 0, 10));
        repeatByTypingLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/pauker/icons/smallbrain.png")));
        repeatByTypingLabel.setText(bundle.getString("Repeating_Method_Colon")); // NOI18N
        repeatByTypingLabel.setHorizontalTextPosition(javax.swing.SwingConstants.LEADING);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.insets = new java.awt.Insets(1, 4, 0, 0);
        infoPanel.add(repeatByTypingLabel, gridBagConstraints);

        expiredLabel.setFont(new java.awt.Font("Dialog", 0, 10));
        expiredLabel.setText(bundle.getString("Expires_At")); // NOI18N
        expiredLabel.setOpaque(true);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(1, 10, 0, 0);
        infoPanel.add(expiredLabel, gridBagConstraints);

        expirationTextField.setEditable(false);
        expirationTextField.setFont(new java.awt.Font("Dialog", 0, 10));
        expirationTextField.setBorder(null);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(1, 10, 0, 3);
        infoPanel.add(expirationTextField, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(0, 3, 3, 3);
        add(infoPanel, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        add(jSeparator1, gridBagConstraints);

    }// </editor-fold>//GEN-END:initComponents
    // Variablendeklaration - nicht modifizieren//GEN-BEGIN:variables
    private javax.swing.JLabel batchNumberLabel;
    private javax.swing.JTextField batchNumberTextField;
    private javax.swing.JPanel contentsPanel;
    private javax.swing.JTextField expirationTextField;
    private javax.swing.JLabel expiredLabel;
    private javax.swing.JTextArea frontSideTextArea;
    private javax.swing.JPanel infoPanel;
    private javax.swing.JSeparator jSeparator1;
    private javax.swing.JTextField learnedDateTextField;
    private javax.swing.JLabel learnedLabel;
    private javax.swing.JLabel repeatByTypingLabel;
    private javax.swing.JTextArea reverseSideTextArea;
    // Ende der Variablendeklaration//GEN-END:variables
}

Generated by  Doxygen 1.6.0   Back to index