001/* 002 * IzPack - Copyright 2001-2005 Julien Ponge, All Rights Reserved. 003 * 004 * http://www.izforge.com/izpack/ 005 * http://developer.berlios.de/projects/izpack/ 006 * 007 * Licensed under the Apache License, Version 2.0 (the "License"); 008 * you may not use this file except in compliance with the License. 009 * You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 */ 019package com.izforge.izpack.installer; 020 021import java.awt.Component; 022import java.awt.Font; 023import java.awt.GridBagConstraints; 024import java.awt.GridBagLayout; 025import java.awt.Insets; 026 027import javax.swing.ImageIcon; 028import javax.swing.JComponent; 029import javax.swing.JLabel; 030import javax.swing.JOptionPane; 031import javax.swing.JPanel; 032import javax.swing.LookAndFeel; 033import javax.swing.UIManager; 034import javax.swing.plaf.metal.MetalLookAndFeel; 035 036import net.n3.nanoxml.XMLElement; 037 038import com.izforge.izpack.gui.LabelFactory; 039import com.izforge.izpack.util.AbstractUIHandler; 040import com.izforge.izpack.util.MultiLineLabel; 041 042/** 043 * Defines the base class for the IzPack panels. Any panel should be a subclass of it and should 044 * belong to the <code>com.izforge.izpack.panels</code> package. 045 * 046 * @author Julien Ponge 047 */ 048public class IzPanel extends JPanel implements AbstractUIHandler 049{ 050 051 private static final long serialVersionUID = 3256442495255786038L; 052 053 /** Indicates whether grid bag layout was started or not */ 054 protected boolean gridBagLayoutStarted = false; 055 056 /** The component which should get the focus at activation */ 057 protected Component initialFocus = null; 058 059 /** 060 * The installer internal data (actually a melting-pot class with all-public fields. 061 */ 062 protected InstallData idata; 063 064 /** The parent IzPack installer frame. */ 065 protected InstallerFrame parent; 066 067 /** The default grid bag constraint. */ 068 protected GridBagConstraints defaultGridBagConstraints = new GridBagConstraints(); 069 070 /** Current x position of grid. */ 071 protected int gridxCounter = -1; 072 073 /** Current y position of grid. */ 074 protected int gridyCounter = -1; 075 076 /** i.e. "com.izforge.izpack.panels.HelloPanel" */ 077 protected String myFullClassname; 078 079 /** myClassname=i.e "FinishPanel" */ 080 protected String myClassname; 081 082 /** i.e. "FinishPanel." useFull for getString() */ 083 protected String myPrefix; 084 085 /** internal headline string */ 086 protected String headline; 087 088 /** internal layout */ 089 protected GridBagLayout izPanelLayout; 090 091 /** internal headline Label */ 092 protected JLabel headLineLabel; 093 094 /** HEADLINE = "headline" */ 095 public final static String HEADLINE = "headline"; 096 097 /** X_ORIGIN = 0 */ 098 public final static int X_ORIGIN = 0; 099 100 /** Y_ORIGIN = 0 */ 101 public final static int Y_ORIGIN = 0; 102 /** D = "." ( dot ) */ 103 public final static String D = "."; 104 105 /** d = D */ 106 public final static String d = D; 107 108 /** COLS_1 = 1 */ 109 public final static int COLS_1 = 1; 110 111 /** ROWS_1 = 1 */ 112 public final static int ROWS_1 = 1; 113 114 115 /** 116 * The constructor. 117 * 118 * @param parent The parent IzPack installer frame. 119 * @param idata The installer internal data. 120 */ 121 public IzPanel(InstallerFrame parent, InstallData idata) 122 { 123 super(); 124 init( parent, idata ); 125 } 126 127 /** 128 * Creates a new IzPanel object. 129 * 130 * @param parent the Parent Frame 131 * @param idata Installers Runtime Data Set 132 * @param iconName The Headline IconName 133 */ 134 public IzPanel( InstallerFrame parent, InstallData idata, String iconName ) 135 { 136 this( parent, idata, iconName, -1 ); 137 } 138 139 /** 140 * The constructor with Icon. 141 * 142 * @param parent The parent IzPack installer frame. 143 * @param idata The installer internal data. 144 * @param iconName A iconname to show as left oriented headline-leading Icon. 145 * @param instance An instance counter 146 */ 147 public IzPanel( InstallerFrame parent, InstallData idata, String iconName, int instance ) 148 { 149 super( ); 150 init( parent, idata ); 151 152 setLayout( ); 153 buildHeadline( iconName, instance ); 154 gridyCounter++; 155 } 156 157 /** 158 * Build the Headline 159 * 160 * @param imageIconName an Iconname 161 * @param instanceNumber an panel instance 162 * 163 * @return true if successful build 164 */ 165 protected boolean buildHeadline( String imageIconName, int instanceNumber ) 166 { 167 boolean result = false; 168 169 // TODO: proteced instancenumber 170 // TODO: is to be validated 171 // TODO: 172 // TODO: first Test if a Resource for your protected Instance exists. 173 String headline; 174 String headlineSearchBaseKey = myClassname + d + "headline"; 175 176 if( instanceNumber > -1 ) 177 { 178 String instanceSearchKey = headlineSearchBaseKey + d + Integer.toString( instanceNumber ); 179 180 String instanceHeadline = getString( instanceSearchKey ); 181 182 //System.out.println( "found headline: " + instanceHeadline + d + S + ": "+ instanceNumber ); 183 if( ! instanceSearchKey.equals( instanceHeadline ) ) 184 { 185 headline = instanceHeadline; 186 } 187 else 188 { 189 headline = getString( headlineSearchBaseKey ); 190 } 191 } 192 else 193 { 194 headline = getString( headlineSearchBaseKey ); 195 } 196 197 if( headline != null ) 198 { 199 if( ( imageIconName != null ) && ! "".equals( imageIconName ) ) 200 { 201 headLineLabel = new JLabel( headline, getImageIcon( imageIconName ), JLabel.TRAILING ); 202 } 203 else 204 { 205 headLineLabel = new JLabel( headline ); 206 } 207 208 Font font = headLineLabel.getFont( ); 209 float size = font.getSize( ); 210 int style = 0; 211 font = font.deriveFont( style, ( size * 1.5f ) ); 212 headLineLabel.setFont( font ); 213 214 GridBagConstraints gbc = getNewGridBagConstraints( X_ORIGIN, Y_ORIGIN, COLS_1, ROWS_1 ); 215 gbc.weightx = 0.0; 216 gbc.weighty = 1.0; 217 218 gbc.fill = GridBagConstraints.NONE; 219 gbc.anchor = GridBagConstraints.NORTHWEST; 220 gbc.insets = new Insets( 0, 0, 5, 0 ); 221 izPanelLayout.setConstraints( headLineLabel, gbc ); 222 headLineLabel.setName( HEADLINE ); 223 add( headLineLabel ); 224 } 225 226 return result; 227 } 228 229 /** 230 * Gets a language Resource String from the parent, which holds these global resource. 231 * 232 * @param key The Search key 233 * 234 * @return The Languageresource or the key if not found. 235 */ 236 public String getString( String key ) 237 { 238 return parent.langpack.getString( key ); 239 } 240 241 /** 242 * Gets a named image icon 243 * 244 * @param iconName a valid image icon 245 * 246 * @return the icon 247 */ 248 public ImageIcon getImageIcon( String iconName ) 249 { 250 return parent.icons.getImageIcon( iconName ); 251 } 252 253 254 255 /** 256 * Inits and sets teh internal LayoutObjects. 257 * 258 * @return true if finshed. 259 */ 260 protected boolean setLayout( ) 261 { 262 izPanelLayout = new GridBagLayout( ); 263 defaultGridBagConstraints = new GridBagConstraints( ); 264 265 setLayout( izPanelLayout ); 266 267 return true; 268 } 269 270 271 /** 272 * Gets and fills the classname fields 273 */ 274 protected void getClassName( ) 275 { 276 myFullClassname = getClass( ).getName( ); 277 myClassname = myFullClassname.substring( myFullClassname.lastIndexOf( "." ) + 1 ); 278 myPrefix = myClassname + "."; 279 } 280 281 /** 282 * Internal init method 283 * 284 * @param parent the parent frame 285 * @param idata installers runtime dataset 286 */ 287 protected void init( InstallerFrame parent, InstallData idata ) 288 { 289 getClassName( ); 290 291 this.idata = idata; 292 this.parent = parent; 293 294 gridyCounter = -1; 295 } 296 297 /** 298 * Indicates wether the panel has been validated or not. The installer won't let the user go 299 * further through the installation process until the panel is validated. Default behaviour is 300 * to return <code>true</code>. 301 * 302 * @return A boolean stating wether the panel has been validated or not. 303 */ 304 public boolean isValidated() 305 { 306 return true; 307 } 308 309 /** 310 * This method is called when the panel becomes active. Default is to do nothing : feel free to 311 * implement what you need in your subclasses. A panel becomes active when the user reaches it 312 * during the installation process. 313 */ 314 public void panelActivate() 315 { 316 } 317 318 /** 319 * This method is called when the panel gets desactivated, when the user switches to the next 320 * panel. By default it doesn't do anything. 321 */ 322 public void panelDeactivate() 323 { 324 } 325 326 /** 327 * Asks the panel to set its own XML data that can be brought back for an automated installation 328 * process. Use it as a blackbox if your panel needs to do something even in automated mode. 329 * 330 * @param panelRoot The XML root element of the panels blackbox tree. 331 */ 332 public void makeXMLData(XMLElement panelRoot) 333 { 334 } 335 336 /** 337 * Ask the user a question. 338 * 339 * @param title Message title. 340 * @param question The question. 341 * @param choices The set of choices to present. 342 * 343 * @return The user's choice. 344 * 345 * @see AbstractUIHandler#askQuestion(String, String, int) 346 */ 347 public int askQuestion(String title, String question, int choices) 348 { 349 return askQuestion(title, question, choices, -1); 350 } 351 352 /** 353 * Ask the user a question. 354 * 355 * @param title Message title. 356 * @param question The question. 357 * @param choices The set of choices to present. 358 * @param default_choice The default choice. (-1 = no default choice) 359 * 360 * @return The user's choice. 361 * @see AbstractUIHandler#askQuestion(String, String, int, int) 362 */ 363 public int askQuestion(String title, String question, int choices, int default_choice) 364 { 365 int jo_choices = 0; 366 367 if (choices == AbstractUIHandler.CHOICES_YES_NO) 368 jo_choices = JOptionPane.YES_NO_OPTION; 369 else if (choices == AbstractUIHandler.CHOICES_YES_NO_CANCEL) 370 jo_choices = JOptionPane.YES_NO_CANCEL_OPTION; 371 372 int user_choice = JOptionPane.showConfirmDialog(this, (Object) question, title, jo_choices, 373 JOptionPane.QUESTION_MESSAGE); 374 375 if (user_choice == JOptionPane.CANCEL_OPTION) return AbstractUIHandler.ANSWER_CANCEL; 376 377 if (user_choice == JOptionPane.YES_OPTION) return AbstractUIHandler.ANSWER_YES; 378 379 if (user_choice == JOptionPane.NO_OPTION) return AbstractUIHandler.ANSWER_NO; 380 381 return default_choice; 382 } 383 384 /** 385 * Notify the user about something. 386 * 387 * @param message The notification. 388 */ 389 public void emitNotification(String message) 390 { 391 JOptionPane.showMessageDialog(this, message); 392 } 393 394 /** 395 * Warn the user about something. 396 * 397 * @param message The warning message. 398 */ 399 public boolean emitWarning(String title, String message) 400 { 401 return (JOptionPane.showConfirmDialog(this, message, title, JOptionPane.WARNING_MESSAGE, 402 JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION); 403 404 } 405 406 /** 407 * Notify the user of some error. 408 * 409 * @param message The error message. 410 */ 411 public void emitError(String title, String message) 412 { 413 JOptionPane.showMessageDialog(this, message, title, JOptionPane.ERROR_MESSAGE); 414 } 415 416 /** 417 * Returns the component which should be get the focus at activation of this panel. 418 * 419 * @return the component which should be get the focus at activation of this panel 420 */ 421 public Component getInitialFocus() 422 { 423 return initialFocus; 424 } 425 426 /** 427 * Sets the component which should be get the focus at activation of this panel. 428 * 429 * @param component which should be get the focus at activation of this panel 430 */ 431 public void setInitialFocus(Component component) 432 { 433 initialFocus = component; 434 } 435 436 /** 437 * Calls the langpack of parent InstallerFrame for the String <tt>RuntimeClassName.subkey</tt>. 438 * Do not add a point infront of subkey, it is always added in this method. 439 * 440 * @param subkey the subkey for the string which should be returned 441 * @param alternateClass the short name of the class which should be used if no string is 442 * present with the runtime class name 443 * @return the founded string 444 */ 445 public String getI18nStringForClass(String subkey, String alternateClass) 446 { 447 String curClassName = this.getClass().getName(); 448 int nameStart = curClassName.lastIndexOf('.') + 1; 449 curClassName = curClassName.substring(nameStart, curClassName.length()); 450 StringBuffer buf = new StringBuffer(); 451 buf.append(curClassName).append(".").append(subkey); 452 String fullkey = buf.toString(); 453 String retval = parent.langpack.getString(fullkey); 454 if (retval == null || retval.startsWith(fullkey)) 455 { 456 buf.delete(0, buf.length()); 457 buf.append(alternateClass).append(".").append(subkey); 458 retval = parent.langpack.getString(buf.toString()); 459 } 460 return (retval); 461 } 462 463 /** 464 * Returns the parent of this IzPanel (which is a InstallerFrame). 465 * 466 * @return the parent of this IzPanel 467 */ 468 public InstallerFrame getInstallerFrame() 469 { 470 return (parent); 471 } 472 473 // ------------- Helper for common used components ----- START --- 474 475 /** 476 * Creates a label via LabelFactory using iconId, pos and method getI18nStringForClass for 477 * resolving the text to be used. If the icon id is null, the label will be created also. 478 * 479 * @param subkey the subkey which should be used for resolving the text 480 * @param alternateClass the short name of the class which should be used if no string is 481 * present with the runtime class name 482 * @param iconId id string for the icon 483 * @param pos horizontal alignment 484 * @return the newly created label 485 */ 486 public JLabel createLabel(String subkey, String alternateClass, String iconId, int pos) 487 { 488 ImageIcon ii = (iconId != null) ? parent.icons.getImageIcon(iconId) : null; 489 String msg = getI18nStringForClass(subkey, alternateClass); 490 JLabel label = LabelFactory.create(msg, ii, pos); 491 if (label != null) label.setFont(getControlTextFont()); 492 return (label); 493 494 } 495 496 /** 497 * Creates a label via LabelFactory with the given ids and the given horizontal alignment. If 498 * the icon id is null, the label will be created also. The strings are the ids for the text in 499 * langpack and the icon in icons of the installer frame. 500 * 501 * @param textId id string for the text 502 * @param iconId id string for the icon 503 * @param pos horizontal alignment 504 * @return the newly created label 505 */ 506 public JLabel createLabel(String textId, String iconId, int pos) 507 { 508 ImageIcon ii = (iconId != null) ? parent.icons.getImageIcon(iconId) : null; 509 JLabel label = LabelFactory.create(parent.langpack.getString(textId),ii, pos); 510 if (label != null) label.setFont(getControlTextFont()); 511 return (label); 512 513 } 514 /** 515 * Creates a multi line label with the language dependent text given by the text id. The strings 516 * is the id for the text in langpack of the installer frame. The horizontal alignment will be 517 * LEFT. 518 * 519 * @param textId id string for the text 520 * @return the newly created multi line label 521 */ 522 public MultiLineLabel createMultiLineLabelLang(String textId) 523 { 524 return (createMultiLineLabel(parent.langpack.getString(textId))); 525 } 526 527 /** 528 * Creates a multi line label with the given text. The horizontal alignment will be LEFT. 529 * 530 * @param text text to be used in the label 531 * @return the newly created multi line label 532 */ 533 public MultiLineLabel createMultiLineLabel(String text) 534 { 535 return (createMultiLineLabel(text, null, JLabel.LEFT)); 536 } 537 538 /** 539 * Creates a label via LabelFactory with the given text, the given icon id and the given 540 * horizontal alignment. If the icon id is null, the label will be created also. The strings are 541 * the ids for the text in langpack and the icon in icons of the installer frame. 542 * 543 * @param text text to be used in the label 544 * @param iconId id string for the icon 545 * @param pos horizontal alignment 546 * @return the created multi line label 547 */ 548 public MultiLineLabel createMultiLineLabel(String text, String iconId, int pos) 549 { 550 MultiLineLabel mll = null; 551 mll = new MultiLineLabel(text, 0, 0); 552 if (mll != null) mll.setFont(getControlTextFont()); 553 return (mll); 554 } 555 556 /** 557 * The Font of Labels in many cases 558 */ 559 public Font getControlTextFont() 560 { 561 return (getLAF() != null ? MetalLookAndFeel.getControlTextFont() : getFont()); 562 } 563 564 protected static MetalLookAndFeel getLAF() 565 { 566 LookAndFeel laf = UIManager.getLookAndFeel(); 567 if (laf instanceof MetalLookAndFeel) return ((MetalLookAndFeel) laf); 568 return (null); 569 } 570 571 // ------------- Helper for common used components ----- END --- 572 // ------------------- Layout stuff -------------------- START --- 573 /** 574 * Returns the default GridBagConstraints of this panel. 575 * 576 * @return the default GridBagConstraints of this panel 577 */ 578 public GridBagConstraints getDefaultGridBagConstraints() 579 { 580 startGridBagLayout(); 581 return defaultGridBagConstraints; 582 } 583 584 /** 585 * Sets the default GridBagConstraints of this panel to the given object. 586 * 587 * @param constraints which should be set as default for this object 588 */ 589 public void setDefaultGridBagConstraints(GridBagConstraints constraints) 590 { 591 startGridBagLayout(); 592 defaultGridBagConstraints = constraints; 593 } 594 595 /** 596 * Resets the grid counters which are used at getNextXGridBagConstraints and 597 * getNextYGridBagConstraints. 598 */ 599 public void resetGridCounter() 600 { 601 gridxCounter = -1; 602 gridyCounter = -1; 603 } 604 605 /** 606 * Returns a newly created GridBagConstraints with the given values and the values from the 607 * defaultGridBagConstraints for the other parameters. 608 * 609 * @param gridx value to be used for the new constraint 610 * @param gridy value to be used for the new constraint 611 * @return newly created GridBagConstraints with the given values and the values from the 612 * defaultGridBagConstraints for the other parameters 613 */ 614 public GridBagConstraints getNewGridBagConstraints(int gridx, int gridy) 615 { 616 GridBagConstraints retval = (GridBagConstraints) getDefaultGridBagConstraints().clone(); 617 retval.gridx = gridx; 618 retval.gridy = gridy; 619 return (retval); 620 621 } 622 623 /** 624 * Returns a newly created GridBagConstraints with the given values and the values from the 625 * defaultGridBagConstraints for the other parameters. 626 * 627 * @param gridx value to be used for the new constraint 628 * @param gridy value to be used for the new constraint 629 * @param gridwidth value to be used for the new constraint 630 * @param gridheight value to be used for the new constraint 631 * @return newly created GridBagConstraints with the given values and the values from the 632 * defaultGridBagConstraints for the other parameters 633 */ 634 public GridBagConstraints getNewGridBagConstraints(int gridx, int gridy, int gridwidth, 635 int gridheight) 636 { 637 GridBagConstraints retval = getNewGridBagConstraints(gridx, gridy); 638 retval.gridwidth = gridwidth; 639 retval.gridheight = gridheight; 640 return (retval); 641 } 642 643 /** 644 * Returns a newly created GridBagConstraints for the next column of the current layout row. 645 * 646 * @return a newly created GridBagConstraints for the next column of the current layout row 647 * 648 */ 649 public GridBagConstraints getNextXGridBagConstraints() 650 { 651 gridxCounter++; 652 GridBagConstraints retval = getNewGridBagConstraints(gridxCounter, gridyCounter); 653 return (retval); 654 } 655 656 /** 657 * Returns a newly created GridBagConstraints for the next column of the current layout row 658 * using the given parameters. 659 * 660 * @param gridwidth width for this constraint 661 * @param gridheight height for this constraint 662 * @return a newly created GridBagConstraints for the next column of the current layout row 663 * using the given parameters 664 */ 665// private GridBagConstraints getNextXGridBagConstraints(int gridwidth, int gridheight) 666// { 667// GridBagConstraints retval = getNextXGridBagConstraints(); 668// retval.gridwidth = gridwidth; 669// retval.gridheight = gridheight; 670// return (retval); 671// } 672 673 /** 674 * Returns a newly created GridBagConstraints with column 0 for the next row. 675 * 676 * @return a newly created GridBagConstraints with column 0 for the next row 677 * 678 */ 679 public GridBagConstraints getNextYGridBagConstraints() 680 { 681 gridyCounter++; 682 gridxCounter = 0; 683 GridBagConstraints retval = getNewGridBagConstraints(0, gridyCounter); 684 return (retval); 685 } 686 687 /** 688 * Returns a newly created GridBagConstraints with column 0 for the next row using the given 689 * parameters. 690 * 691 * @param gridwidth width for this constraint 692 * @param gridheight height for this constraint 693 * @return a newly created GridBagConstraints with column 0 for the next row using the given 694 * parameters 695 */ 696 public GridBagConstraints getNextYGridBagConstraints(int gridwidth, int gridheight) 697 { 698 startGridBagLayout(); 699 GridBagConstraints retval = getNextYGridBagConstraints(); 700 retval.gridwidth = gridwidth; 701 retval.gridheight = gridheight; 702 return (retval); 703 } 704 705 /** 706 * Start layout determining. If it is needed, a dummy component will be created as first row. 707 * This will be done, if the IzPack variable <code>IzPanel.LayoutType</code> has the value 708 * "BOTTOM". 709 */ 710 public void startGridBagLayout() 711 { 712 if (gridBagLayoutStarted) return; 713 gridBagLayoutStarted = true; 714 GridBagLayout layout = new GridBagLayout(); 715 defaultGridBagConstraints.insets = new Insets(0, 0, 20, 0); 716 defaultGridBagConstraints.anchor = GridBagConstraints.WEST; 717 setLayout(layout); 718 String todo = idata.getVariable("IzPanel.LayoutType"); 719 if (todo == null) // No command, no work. 720 return; 721 if (todo.equals("BOTTOM")) 722 { // Make a header to push the rest to the bottom. 723 Filler dummy = new Filler(); 724 GridBagConstraints gbConstraint = getNextYGridBagConstraints(); 725 gbConstraint.weighty = 1.0; 726 gbConstraint.fill = GridBagConstraints.BOTH; 727 gbConstraint.anchor = GridBagConstraints.WEST; 728 this.add(dummy, gbConstraint); 729 } 730 731 // TODO: impl for layout type CENTER, ... 732 } 733 734 /** 735 * Complete layout determining. If it is needed, a dummy component will be created as last row. 736 * This will be done, if the IzPack variable <code>IzPanel.LayoutType</code> has the value 737 * "TOP". 738 */ 739 public void completeGridBagLayout() 740 { 741 String todo = idata.getVariable("IzPanel.LayoutType"); 742 if (todo == null) // No command, no work. 743 return; 744 if (todo.equals("TOP")) 745 { // Make a footer to push the rest to the top. 746 Filler dummy = new Filler(); 747 GridBagConstraints gbConstraint = getNextYGridBagConstraints(); 748 gbConstraint.weighty = 1.0; 749 gbConstraint.fill = GridBagConstraints.BOTH; 750 gbConstraint.anchor = GridBagConstraints.WEST; 751 this.add(dummy, gbConstraint); 752 } 753 } 754 755 // ------------------- Layout stuff -------------------- END --- 756 757 // ------------------- Summary stuff -------------------- START --- 758 /** 759 * This method will be called from the SummaryPanel to get the summary of this class which 760 * should be placed in the SummaryPanel. The returned text should not contain a caption of this 761 * item. The caption will be requested from the method getCaption. If <code>null</code> 762 * returns, no summary for this panel will be generated. Default behaviour is to return 763 * <code>null</code>. 764 * 765 * @return the summary for this class 766 */ 767 public String getSummaryBody() 768 { 769 return null; 770 } 771 772 /** 773 * This method will be called from the SummaryPanel to get the caption for this class which 774 * should be placed in the SummaryPanel. If <code>null</code> returns, no summary for this 775 * panel will be generated. Default behaviour is to return the string given by langpack for the 776 * key <code><current class name>.summaryCaption></code> if exist, else the string 777 * "summaryCaption.<ClassName>". 778 * 779 * @return the caption for this class 780 */ 781 public String getSummaryCaption() 782 { 783 return (getI18nStringForClass("summaryCaption", this.getClass().getName())); 784 } 785 786 // ------------------- Summary stuff -------------------- END --- 787 788 // ------------------- Inner classes ------------------- START --- 789 public static class Filler extends JComponent 790 { 791 792 private static final long serialVersionUID = 3258416144414095153L; 793 794 } 795 // ------------------- Inner classes ------------------- END --- 796 797}