1 /*
   2  * $Id$
   3  *
   4  * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
   5  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   6  *
   7  * This code is free software; you can redistribute it and/or modify it
   8  * under the terms of the GNU General Public License version 2 only, as
   9  * published by the Free Software Foundation.  Oracle designates this
  10  * particular file as subject to the "Classpath" exception as provided
  11  * by Oracle in the LICENSE file that accompanied this code.
  12  *
  13  * This code is distributed in the hope that it will be useful, but WITHOUT
  14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  15  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  16  * version 2 for more details (a copy is included in the LICENSE file that
  17  * accompanied this code).
  18  *
  19  * You should have received a copy of the GNU General Public License version
  20  * 2 along with this work; if not, write to the Free Software Foundation,
  21  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  22  *
  23  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  24  * or visit www.oracle.com if you need additional information or have any
  25  * questions.
  26  */
  27 package com.sun.interview.wizard;
  28 
  29 import java.awt.event.ActionEvent;
  30 import java.awt.event.ActionListener;
  31 import javax.swing.JComponent;
  32 import javax.swing.JLabel;
  33 import javax.swing.JPanel;
  34 import java.awt.Dimension;
  35 
  36 import com.sun.interview.ChoiceQuestion;
  37 import com.sun.interview.Question;
  38 import java.awt.BorderLayout;
  39 import java.awt.Component;
  40 import java.awt.Toolkit;
  41 import javax.swing.AbstractCellEditor;
  42 import javax.swing.ButtonGroup;
  43 import javax.swing.CellEditor;
  44 import javax.swing.JRadioButton;
  45 import javax.swing.JScrollPane;
  46 import javax.swing.JTable;
  47 import javax.swing.table.AbstractTableModel;
  48 import javax.swing.table.TableCellEditor;
  49 import javax.swing.table.TableCellRenderer;
  50 import javax.swing.table.TableColumn;
  51 import javax.swing.table.TableModel;
  52 
  53 public class ChoiceQuestionRenderer
  54         implements QuestionRenderer
  55 {
  56 
  57     public JComponent getQuestionRendererComponent(Question qq, ActionListener listener) {
  58         q = (ChoiceQuestion)qq;
  59         displayChoices = q.getDisplayChoices();
  60         values = q.getChoices();
  61         starts_from = values[0] == null ? 1 : 0;
  62         editedListener = listener;
  63 
  64         return createChoiceTable();
  65     }
  66 
  67     public String getInvalidValueMessage(Question q) {
  68         return null;
  69     }
  70 
  71 
  72     protected JComponent createChoiceTable() {
  73 
  74         TableModel tm = createTableModel();
  75         final JTable tbl = new JTable(tm);
  76         tbl.setOpaque(false);
  77 
  78 
  79         rb = new JRadioButton[displayChoices.length - starts_from];
  80         ButtonGroup bg = new ButtonGroup();
  81 
  82         String v = q.getValue();
  83         for(int i = 0; i < rb.length; i++) {
  84 
  85             rb[i] = new JRadioButton(displayChoices[i + starts_from],
  86                                                 (values[i + starts_from] == v));
  87             rb[i].setActionCommand(values[i + starts_from]);
  88 
  89             rb[i].setName("chc.btn." + values[i + starts_from]);
  90             if (i < 10)
  91                 rb[i].setMnemonic('0' + i);
  92 
  93             rb[i].setToolTipText(i18n.getString("chc.btn.tip"));
  94             rb[i].getAccessibleContext().setAccessibleName(rb[i].getName());
  95             rb[i].getAccessibleContext().setAccessibleDescription(rb[i].getToolTipText());
  96 
  97             rb[i].setBackground(tbl.getBackground());
  98             rb[i].setOpaque(false);
  99 
 100             rb[i].setFocusPainted(false);
 101             bg.add(rb[i]);
 102 
 103             rb[i].addActionListener(new ActionListener() {
 104                public void actionPerformed(ActionEvent e) {
 105                    CellEditor editor = tbl.getCellEditor();
 106                    if (editor != null) {
 107                        editor.stopCellEditing();
 108                    }
 109                }
 110             });
 111         }
 112 
 113         tbl.setPreferredScrollableViewportSize(new Dimension(DOTS_PER_INCH, DOTS_PER_INCH));
 114         tbl.setShowHorizontalLines(false);
 115         tbl.setShowVerticalLines(false);
 116         tbl.setTableHeader(null);
 117 
 118         tbl.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
 119         tbl.setRowSelectionAllowed(false);
 120         tbl.setColumnSelectionAllowed(false);
 121         tbl.setToolTipText(i18n.getString("chcArr.tbl.tip"));
 122 
 123         TableColumn col0 = tbl.getColumnModel().getColumn(0);
 124         TableCellRenderer r = createCellRenderer();
 125         col0.setCellRenderer(r);
 126         TableCellEditor e = createCellEditor();
 127         col0.setCellEditor(e);
 128 
 129         col0.setPreferredWidth(getColumnWidth(tbl, 0) + 20);
 130 
 131         final JScrollPane sp = new JScrollPane(tbl);
 132         sp.setName("chcArr.sp");
 133         sp.getViewport().setBackground(tbl.getBackground());
 134 
 135         JLabel lbl = new JLabel(i18n.getString("chcArr.tbl.lbl"));
 136         lbl.setName("chcArr.tbl.lbl");
 137         lbl.setDisplayedMnemonic(i18n.getString("chcArr.tbl.mne").charAt(0));
 138         lbl.setToolTipText(i18n.getString("chcArr.tbl.tip"));
 139         lbl.setLabelFor(sp);
 140 
 141         tbl.setRowHeight(getRowHeight());
 142 
 143         JPanel result = new JPanel(new BorderLayout());
 144         result.add(lbl, BorderLayout.NORTH);
 145         result.add(sp, BorderLayout.CENTER);
 146 
 147         return result;
 148     }
 149 
 150 
 151     protected int getColumnWidth(JTable table, int colIndex) {
 152         int width = -1;
 153 
 154         TableModel model = table.getModel();
 155         int rowCount = model.getRowCount();
 156 
 157         for(int i = 0; i < rowCount; i++) {
 158             TableCellRenderer r = table.getCellRenderer(i, colIndex);
 159             Component c = r.getTableCellRendererComponent(table,
 160                 model.getValueAt(i, colIndex),
 161                 false, false, i, colIndex);
 162             width = Math.max(width, c.getPreferredSize().width);
 163         }
 164 
 165         return width;
 166     }
 167 
 168     protected int getRowHeight() {
 169         return 22;
 170     }
 171 
 172     protected static final int DOTS_PER_INCH = Toolkit.getDefaultToolkit().getScreenResolution();
 173 
 174     protected void fireEditedEvent(Object src, ActionListener l) {
 175         ActionEvent e = new ActionEvent(src,
 176                                         ActionEvent.ACTION_PERFORMED,
 177                                         EDITED);
 178         l.actionPerformed(e);
 179     }
 180 
 181 
 182     protected TableModel createTableModel() {
 183         return new TestTableModel();
 184     }
 185 
 186     protected class TestTableModel extends AbstractTableModel {
 187 
 188         public Class<?> getColumnClass(int c) {
 189             return String.class;
 190         }
 191 
 192         public int getColumnCount() {
 193             return 1;
 194         }
 195 
 196         public int getRowCount() {
 197             return displayChoices.length - starts_from;
 198         }
 199 
 200         public Object getValueAt(int r, int c) {
 201             return values[r + starts_from];
 202         }
 203 
 204         public void setValueAt(Object o, int r, int c) {
 205             if (c == 0) {
 206                 q.setValue(values[r + starts_from]);
 207                 fireEditedEvent(this, editedListener);
 208             }
 209         }
 210 
 211         public boolean isCellEditable(int r, int c) {
 212             return true;
 213         }
 214 
 215     };
 216 
 217     protected TableCellRenderer createCellRenderer() {
 218         return new TestTableRenderer();
 219     }
 220 
 221     protected class TestTableRenderer implements TableCellRenderer {
 222 
 223         public Component getTableCellRendererComponent(JTable table, Object value,
 224                 boolean isSelected, boolean hasFocus, int row, int column) {
 225 
 226             return rb[row];
 227         }
 228     };
 229 
 230     protected TableCellEditor createCellEditor() {
 231         return new TestTableEditor();
 232     }
 233 
 234     protected class TestTableEditor extends AbstractCellEditor
 235             implements TableCellEditor {
 236         public Object getCellEditorValue() {
 237             return null;
 238         }
 239         public Component getTableCellEditorComponent(JTable table, Object value,
 240                 boolean isSelected, int row, int column) {
 241 
 242             rb[row].setSelected(true);
 243             return rb[row];
 244         }
 245     };
 246 
 247 
 248     protected ChoiceQuestion q;
 249     protected String[] displayChoices;
 250     protected String[] values;
 251     protected int starts_from;
 252     protected ActionListener editedListener;
 253     protected JRadioButton[] rb;
 254 
 255     private static final I18NResourceBundle i18n = I18NResourceBundle.getDefaultBundle();
 256 
 257 }