1 19 20 21 package org.netbeans.modules.i18n.wizard; 22 23 24 import java.awt.BorderLayout ; 25 import java.awt.Component ; 26 import java.awt.Container ; 27 import java.awt.Dialog ; 28 import java.awt.GridBagConstraints ; 29 import java.awt.GridBagLayout ; 30 import java.awt.event.ActionEvent ; 31 import java.awt.event.ActionListener ; 32 import java.awt.event.MouseEvent ; 33 import java.awt.Insets ; 34 import java.util.ArrayList ; 35 import java.util.EventObject ; 36 import java.util.Iterator ; 37 import java.util.Map ; 38 import java.util.Set ; 39 import java.util.HashSet ; 40 import javax.swing.DefaultCellEditor ; 41 import javax.swing.DefaultComboBoxModel ; 42 import javax.swing.JButton ; 43 import javax.swing.JComponent ; 44 import javax.swing.JLabel ; 45 import javax.swing.JPanel ; 46 import javax.swing.JTable ; 47 import javax.swing.JTextField ; 48 import javax.swing.event.TableModelEvent ; 49 import javax.swing.event.TableModelListener ; 50 import javax.swing.table.AbstractTableModel ; 51 import javax.swing.table.DefaultTableCellRenderer ; 52 import javax.swing.table.TableCellEditor ; 53 import javax.swing.AbstractCellEditor ; 54 import org.netbeans.api.java.classpath.ClassPath; 55 56 import org.netbeans.modules.i18n.HardCodedString; 57 import org.netbeans.modules.i18n.I18nString; 58 import org.netbeans.modules.i18n.I18nSupport; 59 import org.netbeans.modules.i18n.I18nUtil; 60 import org.netbeans.modules.i18n.PropertyPanel; 61 62 import org.openide.DialogDescriptor; 63 import org.openide.NotifyDescriptor; 64 import org.openide.loaders.DataObject; 65 import org.openide.util.HelpCtx; 66 import org.openide.util.NbBundle; 67 import org.openide.WizardDescriptor; 68 import org.openide.DialogDisplayer; 69 70 71 81 final class HardStringWizardPanel extends JPanel { 82 83 84 private static final int COLUMN_INDEX_CHECK = 0; 85 86 private static final int COLUMN_INDEX_HARDSTRING = 1; 87 88 private static final int COLUMN_INDEX_KEY = 2; 89 90 private static final int COLUMN_INDEX_VALUE = 3; 91 92 private static final int COLUMN_INDEX_CUSTOM = 4; 93 94 95 private final Map sourceMap = Util.createWizardSourceMap(); 96 97 98 private final AbstractTableModel tableModel = new HardCodedStringTableModel(); 99 100 101 102 private HardStringWizardPanel() { 103 initComponents(); 104 105 postInitComponents(); 106 107 initTable(); 108 109 setComboModel(sourceMap); 110 111 initAccessibility(); 112 } 113 114 115 116 private void setComboModel(Map sourceMap) { 117 Object [] sources = sourceMap.keySet().toArray(); 118 119 ArrayList nonEmptySources = new ArrayList (); 120 121 for(int i = 0; i < sources.length; i++) { 122 if(!((SourceData)sourceMap.get(sources[i])).getStringMap().isEmpty()) 123 nonEmptySources.add(sources[i]); 124 } 125 126 sourceCombo.setModel(new DefaultComboBoxModel (nonEmptySources.toArray())); 127 } 128 129 130 private void postInitComponents() { 131 sourceLabel.setLabelFor(sourceCombo); 132 hardStringLabel.setLabelFor(hardStringTable); 133 } 134 135 136 public Map getSourceMap() { 137 return sourceMap; 138 } 139 140 141 public void setSourceMap(Map sourceMap) { 142 this.sourceMap.clear(); 143 this.sourceMap.putAll(sourceMap); 144 145 setComboModel(sourceMap); 146 } 147 148 149 150 private Map getStringMap() { 151 SourceData sourceData = (SourceData)sourceMap.get(sourceCombo.getSelectedItem()); 152 return sourceData == null ? null : sourceData.getStringMap(); 153 } 154 155 156 private Set getRemovedStrings() { 157 SourceData sourceData = (SourceData)sourceMap.get(sourceCombo.getSelectedItem()); 158 if(sourceData == null) 159 return null; 160 161 if(sourceData.getRemovedStrings() == null) { 162 Set removed = new HashSet (); 164 165 Map stringMap = sourceData.getStringMap(); Iterator hcsIt = stringMap.keySet().iterator(); 169 while (hcsIt.hasNext()) { 170 HardCodedString hcString = (HardCodedString)hcsIt.next(); 171 I18nString i18nString = (I18nString)stringMap.get(hcString); 172 173 if (i18nString.getKey().equals("")) 174 removed.add(hcString); 175 } 176 sourceData.setRemovedStrings(removed); 177 } 178 179 return sourceData.getRemovedStrings(); 180 } 181 182 183 private void initTable() { 184 hardStringTable.setDefaultRenderer(HardCodedString.class, new DefaultTableCellRenderer () { 185 public Component getTableCellRendererComponent(JTable table, Object value, 186 boolean isSelected, boolean hasFocus, int row, int column) { 187 188 JLabel label = (JLabel )super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); 189 190 HardCodedString hcString = (HardCodedString)value; 191 192 if(hcString != null) 193 label.setText(hcString.getText()); 194 else 195 label.setText(""); 197 return label; 198 } 199 }); 200 201 hardStringTable.setDefaultRenderer(I18nString.class, new DefaultTableCellRenderer () { 202 private final JButton dotButton = new JButton ("..."); 204 public Component getTableCellRendererComponent(JTable table, Object value, 205 boolean isSelected, boolean hasFocus, int row, int column) { 206 207 I18nString i18nString = (I18nString)value; 208 209 int modelColumn = hardStringTable.convertColumnIndexToModel(column); 210 211 if(modelColumn == COLUMN_INDEX_CUSTOM) 212 return dotButton; 213 214 JLabel label = (JLabel )super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); 215 216 if(i18nString != null) { 217 if(modelColumn == COLUMN_INDEX_KEY) { 218 label.setText(i18nString.getKey()); 219 } else { 220 label.setText(i18nString.getValue()); 221 } 222 223 } else 224 label.setText(""); 226 227 return label; 228 } 229 }); 230 231 hardStringTable.setDefaultEditor(I18nString.class, new DefaultCellEditor (new JTextField ()) { 232 233 public Component getTableCellEditorComponent( 234 JTable table, Object value, 235 boolean isSelected, 236 int row, int column) { 237 238 I18nString i18nString = (I18nString)value; 239 240 int modelColumn = hardStringTable.convertColumnIndexToModel(column); 241 242 if(modelColumn == COLUMN_INDEX_KEY) 243 value = i18nString == null ? "" : i18nString.getKey(); else if(modelColumn == COLUMN_INDEX_VALUE) 245 value = i18nString == null ? "" : i18nString.getValue(); else 247 value = ""; 249 return super.getTableCellEditorComponent(table, value, isSelected, row, column); 250 } 251 }); 252 253 Component cellSample = new DefaultTableCellRenderer () 254 .getTableCellRendererComponent( 255 hardStringTable, "N/A", false, false, 0, 0); int cellHeight = cellSample.getPreferredSize().height; 261 int rowHeight = cellHeight + hardStringTable.getRowMargin(); 262 hardStringTable.setRowHeight(Math.max(16, rowHeight)); 263 264 hardStringTable.getColumnModel().getColumn(COLUMN_INDEX_CUSTOM).setCellEditor(new CustomizeCellEditor()); 265 266 hardStringTable.getColumnModel().getColumn(COLUMN_INDEX_CHECK).setMaxWidth(30); 268 hardStringTable.getColumnModel().getColumn(COLUMN_INDEX_CUSTOM).setMaxWidth(30); 269 } 270 271 private void initAccessibility() { 272 sourceCombo.getAccessibleContext().setAccessibleDescription(NbBundle.getBundle(HardStringWizardPanel.class).getString("ACSD_sourceCombo")); 273 hardStringTable.getAccessibleContext().setAccessibleDescription(NbBundle.getBundle(HardStringWizardPanel.class).getString("ACSD_hardStringTable")); 274 } 275 276 281 private void initComponents() { 283 java.awt.GridBagConstraints gridBagConstraints; 284 285 sourceLabel = new javax.swing.JLabel (); 286 sourceCombo = new javax.swing.JComboBox (); 287 hardStringLabel = new javax.swing.JLabel (); 288 scrollPane = new javax.swing.JScrollPane (); 289 hardStringTable = new javax.swing.JTable (); 290 291 setLayout(new java.awt.GridBagLayout ()); 292 293 org.openide.awt.Mnemonics.setLocalizedText(sourceLabel, NbBundle.getBundle(HardStringWizardPanel.class).getString("LBL_Source")); gridBagConstraints = new java.awt.GridBagConstraints (); 295 gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; 296 add(sourceLabel, gridBagConstraints); 297 298 sourceCombo.setRenderer(new SourceWizardPanel.DataObjectListCellRenderer()); 299 sourceCombo.addActionListener(new java.awt.event.ActionListener () { 300 public void actionPerformed(java.awt.event.ActionEvent evt) { 301 sourceComboActionPerformed(evt); 302 } 303 }); 304 gridBagConstraints = new java.awt.GridBagConstraints (); 305 gridBagConstraints.gridx = 0; 306 gridBagConstraints.gridy = 1; 307 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; 308 gridBagConstraints.weightx = 1.0; 309 gridBagConstraints.insets = new java.awt.Insets (5, 0, 0, 0); 310 add(sourceCombo, gridBagConstraints); 311 312 org.openide.awt.Mnemonics.setLocalizedText(hardStringLabel, NbBundle.getBundle(HardStringWizardPanel.class).getString("LBL_FoundStrings")); gridBagConstraints = new java.awt.GridBagConstraints (); 314 gridBagConstraints.gridx = 0; 315 gridBagConstraints.gridy = 2; 316 gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; 317 gridBagConstraints.insets = new java.awt.Insets (11, 0, 0, 0); 318 add(hardStringLabel, gridBagConstraints); 319 320 scrollPane.setPreferredSize(new java.awt.Dimension (100, 100)); 321 322 hardStringTable.setModel(tableModel); 323 scrollPane.setViewportView(hardStringTable); 324 325 gridBagConstraints = new java.awt.GridBagConstraints (); 326 gridBagConstraints.gridx = 0; 327 gridBagConstraints.gridy = 3; 328 gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; 329 gridBagConstraints.weightx = 1.0; 330 gridBagConstraints.weighty = 1.0; 331 gridBagConstraints.insets = new java.awt.Insets (5, 0, 0, 0); 332 add(scrollPane, gridBagConstraints); 333 } 335 private void sourceComboActionPerformed(java.awt.event.ActionEvent evt) { if(((SourceData)sourceMap.get(sourceCombo.getSelectedItem())).getStringMap().isEmpty()) { 337 JLabel label = new JLabel (NbBundle.getBundle(HardStringWizardPanel.class).getString("TXT_NoHardstringsSource")); 339 label.setHorizontalAlignment(JLabel.CENTER); 340 scrollPane.setViewportView(label); 341 } else { 342 scrollPane.setViewportView(hardStringTable); 343 tableModel.fireTableDataChanged(); 344 } 345 } 347 private javax.swing.JLabel hardStringLabel; 349 private javax.swing.JTable hardStringTable; 350 private javax.swing.JScrollPane scrollPane; 351 private javax.swing.JComboBox sourceCombo; 352 private javax.swing.JLabel sourceLabel; 353 355 356 private class HardCodedStringTableModel extends AbstractTableModel { 357 358 359 public HardCodedStringTableModel() { 360 } 361 362 363 364 365 public int getColumnCount() { 366 return 5; 367 } 368 369 370 public int getRowCount() { 371 Map stringMap = getStringMap(); 372 return stringMap == null ? 0 : stringMap.size(); 373 } 374 375 376 public Object getValueAt(int rowIndex, int columnIndex) { 377 Map stringMap = getStringMap(); 378 379 if(stringMap == null) 380 return null; 381 382 if(columnIndex == COLUMN_INDEX_CHECK) { 383 if (getRemovedStrings().contains(stringMap.keySet().toArray()[rowIndex])) 384 return Boolean.FALSE ; 385 else 386 return Boolean.TRUE; 387 388 } else if(columnIndex == COLUMN_INDEX_HARDSTRING) { 389 return stringMap.keySet().toArray()[rowIndex]; 390 } else { 391 return stringMap.values().toArray()[rowIndex]; 392 } 393 } 394 395 397 public boolean isCellEditable(int rowIndex, int columnIndex) { 398 return (columnIndex != COLUMN_INDEX_HARDSTRING); 399 } 400 401 402 public void setValueAt(Object value, int rowIndex, int columnIndex) { 403 Map stringMap = getStringMap(); 404 if(stringMap == null) return; 405 406 switch (columnIndex) { 407 case COLUMN_INDEX_HARDSTRING: return; 408 case COLUMN_INDEX_CUSTOM: 409 I18nString otherValue = (I18nString)getValueAt(rowIndex, COLUMN_INDEX_KEY); 410 if (!((I18nString)value).getKey().equals("")) 411 setValueAt(Boolean.TRUE, rowIndex, COLUMN_INDEX_CHECK); 412 else 413 setValueAt(Boolean.FALSE, rowIndex, COLUMN_INDEX_CHECK); 414 break; 415 case COLUMN_INDEX_CHECK : 416 if(value instanceof Boolean ) { 417 418 if ((((Boolean )value).booleanValue()==true) && 421 ((I18nString)getValueAt(rowIndex, COLUMN_INDEX_KEY)).getKey().equals("")) 422 { String message = NbBundle.getMessage(HardStringWizardPanel.class, "MSG_CANNOT_INSERT_EMPTY_KEYS"); 424 NotifyDescriptor nd = new NotifyDescriptor.Message(message, NotifyDescriptor.Message.INFORMATION_MESSAGE); 425 DialogDisplayer.getDefault().notify(nd); 426 } else { 427 Object hardString = stringMap.keySet().toArray()[rowIndex]; 428 429 Set removedStrings = getRemovedStrings(); 430 431 if(((Boolean )value).booleanValue()) 432 removedStrings.remove(hardString); 433 else 434 removedStrings.add(hardString); 435 } 436 } 437 break; 438 case COLUMN_INDEX_KEY : { 439 I18nString i18nString = (I18nString)stringMap.values().toArray()[rowIndex]; 440 i18nString.setKey(value.toString()); 441 if (!value.toString().equals("")) 442 setValueAt(Boolean.TRUE, rowIndex, COLUMN_INDEX_CHECK); 443 else 444 setValueAt(Boolean.FALSE, rowIndex, COLUMN_INDEX_CHECK); 445 break; 446 } 447 448 case COLUMN_INDEX_VALUE: { 449 I18nString i18nString = (I18nString)stringMap.values().toArray()[rowIndex]; 450 i18nString.setValue(value.toString()); 451 if (!i18nString.getKey().equals("")) setValueAt(Boolean.TRUE, rowIndex, COLUMN_INDEX_CHECK); 452 break; 453 } 454 } 456 fireTableRowsUpdated(rowIndex, rowIndex); 457 } 458 459 461 public Class getColumnClass(int columnIndex) { 462 if(columnIndex == COLUMN_INDEX_CHECK) 463 return Boolean .class; 464 else if(columnIndex == COLUMN_INDEX_HARDSTRING) 465 return HardCodedString.class; 466 else 467 return I18nString.class; 468 } 469 470 471 public String getColumnName(int column) { 472 if(column == COLUMN_INDEX_HARDSTRING) 473 return NbBundle.getBundle(HardStringWizardPanel.class).getString("LBL_HardString"); 474 else if(column == COLUMN_INDEX_KEY) 475 return NbBundle.getBundle(HardStringWizardPanel.class).getString("LBL_Key"); 476 else if(column == COLUMN_INDEX_VALUE) 477 return NbBundle.getBundle(HardStringWizardPanel.class).getString("LBL_Value"); 478 else 479 return " "; } 481 } 483 484 489 public static class CustomizeCellEditor extends AbstractCellEditor 490 implements TableCellEditor , ActionListener { 491 492 493 private I18nString i18nString; 494 495 496 private JButton editorComponent; 497 498 499 500 public CustomizeCellEditor() { 501 editorComponent = new JButton ("..."); 503 editorComponent.addActionListener(new ActionListener () { 504 public void actionPerformed(ActionEvent evt) { 505 PropertyPanel panel = i18nString.getSupport().getPropertyPanel(); 506 I18nString clone = (I18nString) i18nString.clone(); 507 panel.setI18nString(i18nString); 508 509 String title = Util.getString("PROP_cust_dialog_name"); 510 DialogDescriptor dd = new DialogDescriptor(panel, title); 511 dd.setModal(true); 512 dd.setOptionType(DialogDescriptor.DEFAULT_OPTION); 513 514 Object options[] = new Object [] { 515 DialogDescriptor.OK_OPTION, 516 DialogDescriptor.CANCEL_OPTION, 517 }; 518 dd.setOptions(options); 519 dd.setHelpCtx(new HelpCtx(I18nUtil.PE_I18N_STRING_HELP_ID)); 521 dd.setButtonListener(CustomizeCellEditor.this); 522 523 Dialog dialog = DialogDisplayer.getDefault().createDialog(dd); 524 dialog.setVisible(true); 525 if (dd.getValue() == DialogDescriptor.CANCEL_OPTION) { 526 i18nString.become(clone); 527 } 528 } 529 }); 530 } 531 532 533 public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { 534 i18nString = (I18nString)value; 535 536 return editorComponent; 537 } 538 539 540 public Object getCellEditorValue() { 541 return i18nString; 542 } 543 544 545 public boolean isCellEditable(EventObject anEvent) { 546 if(anEvent instanceof MouseEvent ) { 547 return ((MouseEvent )anEvent).getClickCount() >= 1; 549 } 550 return true; 551 } 552 553 554 public boolean shouldSelectCell(EventObject anEvent) { 555 return true; 556 } 557 558 559 public boolean stopCellEditing() { 560 fireEditingStopped(); 561 return true; 562 } 563 564 565 public void cancelCellEditing() { 566 fireEditingCanceled(); 567 } 568 569 570 public void actionPerformed(ActionEvent evt) { 571 stopCellEditing(); 572 } 573 574 } 575 576 577 580 public static class Panel extends I18nWizardDescriptor.Panel 581 implements WizardDescriptor.FinishablePanel, I18nWizardDescriptor.ProgressMonitor { 582 583 584 private final JLabel emptyLabel; 585 586 587 private transient HardStringWizardPanel hardStringPanel; 588 589 public Panel() { 590 emptyLabel = new JLabel (NbBundle.getBundle(HardStringWizardPanel.class).getString("TXT_NoHardstrings")); 591 emptyLabel.setHorizontalAlignment(JLabel.CENTER); 592 emptyLabel.setVerticalAlignment(JLabel.CENTER); 593 } 594 595 596 598 protected Component createComponent() { 599 JPanel panel = new JPanel (); 600 601 panel.getAccessibleContext().setAccessibleDescription(NbBundle.getBundle(HardStringWizardPanel.class).getString("ACS_HardStringWizardPanel")); 602 603 Integer index; 604 605 if(I18nUtil.getOptions().isAdvancedWizard()) 606 index = new Integer (3); 607 else 608 index = new Integer (2); 609 610 panel.putClientProperty("WizardPanel_contentSelectedIndex", index); panel.setName(NbBundle.getBundle(HardStringWizardPanel.class).getString("TXT_ModifyStrings")); 612 panel.setPreferredSize(I18nWizardDescriptor.PREFERRED_DIMENSION); 613 panel.setLayout(new GridBagLayout ()); 614 GridBagConstraints constraints = new GridBagConstraints (); 615 constraints.weightx = 1.0; 616 constraints.weighty = 1.0; 617 constraints.fill = GridBagConstraints.BOTH; 618 panel.add(getUI(), constraints); 619 620 return panel; 621 } 622 623 624 public boolean isValid() { 625 return true; 626 } 627 628 630 public boolean isFinishPanel() { 631 return true; 632 } 633 634 635 public void readSettings(Object settings) { 636 super.readSettings(settings); 637 getUI().setSourceMap(getMap()); 638 639 JPanel panel = (JPanel )getComponent(); 640 if(foundStrings(getMap())) { 641 if(panel.isAncestorOf(emptyLabel)) { 642 panel.remove(emptyLabel); 643 GridBagConstraints constraints = new GridBagConstraints (); 644 constraints.weightx = 1.0; 645 constraints.weighty = 1.0; 646 constraints.fill = GridBagConstraints.BOTH; 647 panel.add(getUI(), constraints); 648 } 649 } else { 650 if(panel.isAncestorOf(getUI())) { 651 panel.remove(getUI()); 652 GridBagConstraints constraints = new GridBagConstraints (); 653 constraints.weightx = 1.0; 654 constraints.weighty = 1.0; 655 constraints.fill = GridBagConstraints.BOTH; 656 panel.add(emptyLabel, constraints); 657 } 658 } 659 } 660 661 662 public void storeSettings(Object settings) { 663 super.storeSettings(settings); 664 getMap().clear(); 666 getMap().putAll(getUI().getSourceMap()); 667 } 668 669 671 public void doLongTimeChanges() { 672 if (foundStrings(getMap())) { 674 final ProgressWizardPanel progressPanel = new ProgressWizardPanel(true); 676 progressPanel.setMainText(NbBundle.getBundle(HardStringWizardPanel.class).getString("LBL_Internationalizing")); 677 progressPanel.setMainProgress(0); 678 679 ((Container )getComponent()).remove(getUI()); 680 GridBagConstraints constraints = new GridBagConstraints (); 681 constraints.weightx = 1.0; 682 constraints.weighty = 1.0; 683 constraints.fill = GridBagConstraints.BOTH; 684 ((Container )getComponent()).add(progressPanel, constraints); 685 ((JComponent )getComponent()).revalidate(); 686 getComponent().repaint(); 687 688 Map sourceMap = getUI().getSourceMap(); 690 691 Iterator sourceIterator = sourceMap.keySet().iterator(); 692 693 for(int i=0; sourceIterator.hasNext(); i++) { 695 Object source = sourceIterator.next(); 696 697 SourceData sourceData = (SourceData)sourceMap.get(source); 699 700 I18nSupport support = sourceData.getSupport(); 702 703 Map stringMap = sourceData.getStringMap(); 705 Object [] stringEntries = stringMap.entrySet().toArray(); 706 707 Set removed = sourceData.getRemovedStrings(); 709 710 ClassPath cp = ClassPath.getClassPath( ((DataObject)source).getPrimaryFile(), ClassPath.SOURCE ); 712 progressPanel.setSubText(NbBundle.getBundle(HardStringWizardPanel.class).getString("LBL_Source")+" "+cp.getResourceName( ((DataObject)source).getPrimaryFile(), '.', false ) ); 713 714 for(int j=0; j < stringEntries.length; j++) { 715 Map.Entry e = (Map.Entry ) stringEntries[j]; 716 HardCodedString hcString = (HardCodedString) e.getKey(); 717 I18nString i18nString = (I18nString) e.getValue(); 718 719 if(removed != null && removed.contains(hcString)) 720 continue; 722 723 support.getResourceHolder().addProperty(i18nString.getKey(), i18nString.getValue(), i18nString.getComment()); 725 726 support.getReplacer().replace(hcString, i18nString); 728 729 progressPanel.setSubProgress((int)((j+1)/(float)stringMap.size() * 100)); 730 } 732 if(support.hasAdditionalCustomizer()) { 734 support.performAdditionalChanges(); 735 } 736 737 progressPanel.setMainProgress((int)((i+1)/(float)sourceMap.size() * 100)); 738 } } } 741 742 743 public void reset() {} 744 745 747 private static boolean foundStrings(Map sourceMap) { 748 Iterator it = sourceMap.keySet().iterator(); 749 750 while(it.hasNext()) { 751 SourceData sourceData = (SourceData)sourceMap.get(it.next()); 752 if(!sourceData.getStringMap().isEmpty()) 753 return true; 754 } 755 756 return false; 757 } 758 759 760 public HelpCtx getHelp() { 761 return new HelpCtx(I18nUtil.HELP_ID_WIZARD); 762 } 763 764 private synchronized HardStringWizardPanel getUI() { 765 if (hardStringPanel == null) { 766 hardStringPanel = new HardStringWizardPanel(); 767 } 768 return hardStringPanel; 769 } 770 771 } } 773 | Popular Tags |