ComponentFactory.java
     1: //========================================================================================
     2: //  ComponentFactory.java
     3: //    en:Component factory -- It creates and changes components.
     4: //    ja:コンポーネントファクトリー -- コンポーネントの作成と変更を行います。
     5: //  Copyright (C) 2003-2017 Makoto Kamada
     6: //
     7: //  This file is part of the XEiJ (X68000 Emulator in Java).
     8: //  You can use, modify and redistribute the XEiJ if the conditions are met.
     9: //  Read the XEiJ License for more details.
    10: //  http://stdkmd.com/xeij/
    11: //========================================================================================
    12: 
    13: package xeij;
    14: 
    15: import java.awt.*;  //BasicStroke,BorderLayout,BoxLayout,Color,Component,Container,Cursor,Desktop,Dimension,Font,FlowLayout,Frame,Graphics,Graphics2D,GraphicsDevice,GraphicsEnvironment,GridLayout,Image,Insets,Paint,Point,Rectangle,RenderingHints,Robot,Shape,Stroke,TexturePaint,Toolkit
    16: import java.awt.event.*;  //ActionEvent,ActionListener,ComponentAdapter,ComponentEvent,ComponentListener,FocusAdapter,FocusEvent,FocusListener,InputEvent,KeyAdapter,KeyEvent,KeyListener,MouseAdapter,MouseEvent,MouseListener,MouseMotionAdapter,MouseWheelEvent,WindowAdapter,WindowEvent,WindowListener,WindowStateListener
    17: import java.awt.image.*;  //BufferedImage,DataBuffer,DataBufferByte,DataBufferInt,IndexColorModel
    18: import java.lang.*;  //Boolean,Character,Class,Comparable,Double,Exception,Float,IllegalArgumentException,Integer,InterruptedException,Long,Math,Number,Object,Runnable,SecurityException,String,StringBuilder,System
    19: import java.net.*;  //MalformedURLException,URI,URL
    20: import java.util.*;  //ArrayList,Arrays,Calendar,GregorianCalendar,HashMap,Map,Map.Entry,LinkedList,TimeZone,Timer,TimerTask,TreeMap
    21: import java.util.regex.*;  //Matcher,Pattern
    22: import javax.swing.*;  //AbstractButton,AbstractSpinnerModel,Box,ButtonGroup,DefaultListModel,ImageIcon,JApplet,JButton,JCheckBox,JCheckBoxMenuItem,JComponent,JDialog,JFileChooser,JFrame,JLabel,JList,JMenu,JMenuBar,JMenuItem,JPanel,JRadioButton,JScrollPane,JSpinner,JTextArea,JTextField,JTextPane,JViewport,ScrollPaneConstants,SpinnerListModel,SpinnerNumberModel,SwingConstants,SwingUtilities,UIManager,UIDefaults,UnsupportedLookAndFeelException
    23: import javax.swing.border.*;  //Border,CompoundBorder,EmptyBorder,EtchedBorder,LineBorder,TitledBorder
    24: import javax.swing.event.*;  //CaretEvent,CaretListener,ChangeEvent,ChangeListener,DocumentEvent,DocumentListener,ListSelectionListener
    25: import javax.swing.plaf.metal.*;  //MetalLookAndFeel,MetalTheme,OceanTheme
    26: import javax.swing.text.*;  //AbstractDocument,BadLocationException,DefaultCaret,Document,DocumentFilter,JTextComponent,ParagraphView,Style,StyleConstants,StyleContext,StyledDocument
    27: 
    28: public class ComponentFactory {
    29: 
    30: 
    31:   //--------------------------------------------------------------------------------
    32:   //コンポーネントにリスナーを追加する
    33: 
    34:   //button = addListener (button, listener)
    35:   //  ボタンにアクションリスナーを追加する
    36:   public static <T extends AbstractButton> T addListener (T button, ActionListener listener) {
    37:     if (listener != null) {
    38:       button.addActionListener (listener);
    39:     }
    40:     return button;
    41:   }  //addListener(T extends AbstractButton,ActionListener)
    42: 
    43:   //comboBox = addListener (comboBox, listener)
    44:   //  コンボボックスにアクションリスナーを追加する
    45:   public static <T extends JComboBox<String>> T addListener (T comboBox, ActionListener listener) {
    46:     if (listener != null) {
    47:       comboBox.addActionListener (listener);
    48:     }
    49:     return comboBox;
    50:   }  //addListener(T extends JComboBox,ActionListener)
    51: 
    52:   //slider = addListener (slider, listener)
    53:   //  スライダーにチェンジリスナーを追加する
    54:   public static <T extends JSlider> T addListener (T slider, ChangeListener listener) {
    55:     if (listener != null) {
    56:       slider.addChangeListener (listener);
    57:     }
    58:     return slider;
    59:   }  //addListener(T extends JSlider,ActionListener)
    60: 
    61:   //spinner = addListener (spinner, listener)
    62:   //  スピナーにチェンジリスナーを追加する
    63:   public static <T extends JSpinner> T addListener (T spinner, ChangeListener listener) {
    64:     if (listener != null) {
    65:       spinner.addChangeListener (listener);
    66:     }
    67:     return spinner;
    68:   }  //addListener(T extends JSpinner,ChangeListener)
    69: 
    70:   //scrollList = addListener (scrollList, listener)
    71:   //  スクロールリストにリストセレクションリスナーを追加する
    72:   public static <T extends ScrollList> T addListener (T scrollList, ListSelectionListener listener) {
    73:     if (listener != null) {
    74:       scrollList.addListSelectionListener (listener);
    75:     }
    76:     return scrollList;
    77:   }  //addListener(T extends ScrollList,ListSelectionListener)
    78: 
    79:   //component = addListener (component, listener)
    80:   //  コンポーネントにフォーカスリスナーを追加する
    81:   public static <T extends Component> T addListener (T component, FocusListener listener) {
    82:     if (listener != null) {
    83:       component.addFocusListener (listener);
    84:     }
    85:     return component;
    86:   }  //addListener(T extends Component,FocusListener)
    87: 
    88:   //component = addListener (component, listener)
    89:   //  コンポーネントにキーリスナーを追加する
    90:   public static <T extends Component> T addListener (T component, KeyListener listener) {
    91:     if (listener != null) {
    92:       component.addKeyListener (listener);
    93:     }
    94:     return component;
    95:   }  //addListener(T extends Component,KeyListener)
    96: 
    97:   //component = addListener (component, listener)
    98:   //  コンポーネントにコンポーネントリスナーを追加する
    99:   public static <T extends Component> T addListener (T component, ComponentListener listener) {
   100:     if (listener != null) {
   101:       component.addComponentListener (listener);
   102:     }
   103:     return component;
   104:   }  //addListener(T extends Component,ComponentListener)
   105: 
   106:   //component = addListener (component, listener)
   107:   //  コンポーネントにマウスリスナー、マウスモーションリスナー、マウスホイールリスナーを追加する
   108:   public static <T extends Component> T addListener (T component, MouseAdapter listener) {
   109:     if (listener != null) {
   110:       component.addMouseListener (listener);
   111:       component.addMouseMotionListener (listener);
   112:       component.addMouseWheelListener (listener);
   113:     }
   114:     return component;
   115:   }  //addListener(T extends Component,MouseAdapter)
   116: 
   117:   //component = addListener (component, listener)
   118:   //  コンポーネントにマウスリスナーを追加する
   119:   public static <T extends Component> T addListener (T component, MouseListener listener) {
   120:     if (listener != null) {
   121:       component.addMouseListener (listener);
   122:     }
   123:     return component;
   124:   }  //addListener(T extends Component,MouseListener)
   125: 
   126:   //component = addListener (component, listener)
   127:   //  コンポーネントにマウスモーションリスナーを追加する
   128:   public static <T extends Component> T addListener (T component, MouseMotionListener listener) {
   129:     if (listener != null) {
   130:       component.addMouseMotionListener (listener);
   131:     }
   132:     return component;
   133:   }  //addListener(T extends Component,MouseMotionListener)
   134: 
   135:   //component = addListener (component, listener)
   136:   //  コンポーネントにマウスホイールリスナーを追加する
   137:   public static <T extends Component> T addListener (T component, MouseWheelListener listener) {
   138:     if (listener != null) {
   139:       component.addMouseWheelListener (listener);
   140:     }
   141:     return component;
   142:   }  //addListener(T extends Component,MouseWheelListener)
   143: 
   144:   //window = addListener (window, listener)
   145:   //  ウインドウにウインドウリスナー、ウインドウステートリスナー、ウインドウフォーカスリスナーを追加する
   146:   public static <T extends Window> T addListener (T window, WindowAdapter listener) {
   147:     if (listener != null) {
   148:       window.addWindowListener (listener);
   149:       window.addWindowStateListener (listener);
   150:       window.addWindowFocusListener (listener);
   151:     }
   152:     return window;
   153:   }  //addListener(T extends Window,WindowAdapter)
   154: 
   155:   //window = addListener (window, listener)
   156:   //  ウインドウにウインドウリスナーを追加する
   157:   public static <T extends Window> T addListener (T window, WindowListener listener) {
   158:     if (listener != null) {
   159:       window.addWindowListener (listener);
   160:     }
   161:     return window;
   162:   }  //addListener(T extends Window,WindowListener)
   163: 
   164:   //window = addListener (window, listener)
   165:   //  ウインドウにウインドウステートリスナーを追加する
   166:   public static <T extends Window> T addListener (T window, WindowStateListener listener) {
   167:     if (listener != null) {
   168:       window.addWindowStateListener (listener);
   169:     }
   170:     return window;
   171:   }  //addListener(T extends Window,WindowStateListener)
   172: 
   173:   //window = addListener (window, listener)
   174:   //  ウインドウにウインドウフォーカスリスナーを追加する
   175:   public static <T extends Window> T addListener (T window, WindowFocusListener listener) {
   176:     if (listener != null) {
   177:       window.addWindowFocusListener (listener);
   178:     }
   179:     return window;
   180:   }  //addListener(T extends Window,WindowFocusListener)
   181: 
   182:   //textComponent = addListener (textComponent, listener)
   183:   //  テキストコンポーネントにキャレットリスナーを追加する
   184:   public static <T extends JTextComponent> T addListener (T textComponent, CaretListener listener) {
   185:     if (listener != null) {
   186:       textComponent.addCaretListener (listener);
   187:     }
   188:     return textComponent;
   189:   }  //addListener(T extends JTextComponent,CaretListener)
   190: 
   191: 
   192:   //--------------------------------------------------------------------------------
   193:   //コンポーネントに属性を追加する
   194:   //  ジェネリクスを用いてパラメータのコンポーネントをクラスを変えずにそのまま返すメソッドを定義する
   195:   //  コンポーネントのインスタンスメソッドがコンポーネント自身を返してくれると、
   196:   //  メソッドチェーンが組めて括弧をネストする必要がなくなりコードが読みやすくなるのだが、
   197:   //  元のクラスのまま利用できなければ既存のメソッドの返却値をいちいちキャストしなければならず、
   198:   //  結局括弧が増えることになる
   199: 
   200:   //component = setToolTipText (component, toolTipText)
   201:   public static <T extends JComponent> T setToolTipText (T component, String toolTipText) {
   202:     component.setToolTipText (toolTipText);
   203:     return component;
   204:   }  //setToolTipText(T extends JComponent,String)
   205: 
   206:   //component = setName (component, name)
   207:   public static <T extends Component> T setName (T component, String name) {
   208:     component.setName (name);
   209:     return component;
   210:   }  //setName(T extends Component,String)
   211: 
   212:   //component = setVisible (component, visible)
   213:   public static <T extends Component> T setVisible (T component, boolean visible) {
   214:     component.setVisible (visible);
   215:     return component;
   216:   }  //setVisible(T extends Component,boolean)
   217: 
   218:   //component = setColor (component, foreground, background)
   219:   public static <T extends Component> T setColor (T component, Color foreground, Color background) {
   220:     component.setBackground (background);
   221:     component.setForeground (foreground);
   222:     return component;
   223:   }  //setColor(T extends Component,Color,Color)
   224: 
   225:   //component = setFont (component, font)
   226:   public static <T extends Component> T setFont (T component, Font font) {
   227:     component.setFont (font);
   228:     return component;
   229:   }  //setFont(T extends Component,Font)
   230: 
   231:   //component = bold (component)
   232:   //component = italic (component)
   233:   //component = boldItalic (component)
   234:   public static <T extends Component> T bold (T component) {
   235:     return setFont (component, component.getFont ().deriveFont (Font.BOLD));
   236:   }  //bold(T extends Component)
   237:   public static <T extends Component> T italic (T component) {
   238:     return setFont (component, component.getFont ().deriveFont (Font.ITALIC));
   239:   }  //italic(T extends Component)
   240:   public static <T extends Component> T boldItalic (T component) {
   241:     return setFont (component, component.getFont ().deriveFont (Font.BOLD | Font.ITALIC));
   242:   }  //boldItalic(T extends Component)
   243: 
   244:   //component = setEnabled (component, enabled)
   245:   //  コンポーネントが有効かどうか指定する
   246:   public static <T extends Component> T setEnabled (T component, boolean enabled) {
   247:     component.setEnabled (enabled);
   248:     return component;
   249:   }  //setEnabled(T extends Component,boolean)
   250: 
   251:   //component = setMaximumSize (component, width, height)
   252:   //  コンポーネントの最大サイズを指定する
   253:   public static <T extends Component> T setMaximumSize (T component, int width, int height) {
   254:     component.setMaximumSize (new Dimension (width, height));
   255:     return component;
   256:   }  //setMaximumSize(T extends Component,int,int)
   257: 
   258:   //component = setMinimumSize (component, width, height)
   259:   //  コンポーネントの最小サイズを指定する
   260:   public static <T extends Component> T setMinimumSize (T component, int width, int height) {
   261:     component.setMinimumSize (new Dimension (width, height));
   262:     return component;
   263:   }  //setMinimumSize(T extends Component,int,int)
   264: 
   265:   //component = setPreferredSize (component, width, height)
   266:   //  コンポーネントの推奨サイズを指定する
   267:   public static <T extends Component> T setPreferredSize (T component, int width, int height) {
   268:     component.setPreferredSize (new Dimension (width, height));
   269:     return component;
   270:   }  //setPreferredSize(T extends Component,int,int)
   271: 
   272:   //component = setFixedSize (component, width, height)
   273:   //  コンポーネントの固定サイズを指定する
   274:   public static <T extends Component> T setFixedSize (T component, int width, int height) {
   275:     Dimension d = new Dimension (width, height);
   276:     component.setMinimumSize (d);
   277:     component.setMaximumSize (d);
   278:     component.setPreferredSize (d);
   279:     return component;
   280:   }  //setFixedSize(T extends Component,int,int)
   281: 
   282:   //component = setEmptyBorder (component, top, left, bottom, right)
   283:   //  コンポーネントに透過ボーダーを付ける
   284:   public static <T extends JComponent> T setEmptyBorder (T component, int top, int left, int bottom, int right) {
   285:     component.setBorder (new EmptyBorder (top, left, bottom, right));
   286:     return component;
   287:   }  //setEmptyBorder(T extends JComponent,int,int,int,int)
   288: 
   289:   //component = setTitledLineBorder (component, title)
   290:   //  コンポーネントにタイトル付きラインボーダーを付ける
   291:   public static <T extends JComponent> T setTitledLineBorder (T component, String title) {
   292:     component.setBorder (new TitledBorder (new LineBorder (MetalLookAndFeel.getSeparatorForeground (), 1), title));  //primary1
   293:     return component;
   294:   }  //setTitledLineBorder(T extends JComponent,String)
   295: 
   296:   //component = setTitledEtchedBorder (component, title)
   297:   //  コンポーネントにタイトル付きエッチングボーダーを付ける
   298:   public static <T extends JComponent> T setTitledEtchedBorder (T component, String title) {
   299:     component.setBorder (new TitledBorder (new EtchedBorder (), title));
   300:     return component;
   301:   }  //setTitledEtchedBorder(T extends JComponent,String)
   302: 
   303:   //parent = addComponents (parent, component, ...)
   304:   //  コンポーネントにコンポーネントを追加する
   305:   public static <T extends JComponent> T addComponents (T parent, Component... components) {
   306:     for (Component component : components) {
   307:       if (component != null) {
   308:         parent.add (component);
   309:       }
   310:     }
   311:     return parent;
   312:   }  //addComponents(T extends JComponent,Component...)
   313: 
   314:   //parent = removeComponents (parent, child, ...)
   315:   //  コンポーネントからコンポーネントを取り除く
   316:   public static <T extends JComponent> T removeComponents (T parent, Component... components) {
   317:     for (Component component : components) {
   318:       if (component != null) {
   319:         parent.remove (component);
   320:       }
   321:     }
   322:     return parent;
   323:   }  //removeComponents(T extends JComponent,Component...)
   324: 
   325:   //ボタン
   326: 
   327:   //button = setText (button, text)
   328:   public static <T extends AbstractButton> T setText (T button, String text) {
   329:     button.setText (text);
   330:     return button;
   331:   }  //setText(T extends AbstractButton,String)
   332: 
   333:   //button = setHorizontalAlignment (button, alignment)
   334:   //  SwingConstants.RIGHT
   335:   //  SwingConstants.LEFT
   336:   //  SwingConstants.CENTER (デフォルト)
   337:   //  SwingConstants.LEADING
   338:   //  SwingConstants.TRAILING
   339:   public static <T extends AbstractButton> T setHorizontalAlignment (T button, int alignment) {
   340:     button.setHorizontalAlignment (alignment);
   341:     return button;
   342:   }  //setHorizontalAlignment(T extends AbstractButton,int)
   343: 
   344:   //button = setVerticalAlignment (button, alignment)
   345:   //  SwingConstants.CENTER (デフォルト)
   346:   //  SwingConstants.TOP
   347:   //  SwingConstants.BOTTOM
   348:   public static <T extends AbstractButton> T setVerticalAlignment (T button, int alignment) {
   349:     button.setVerticalAlignment (alignment);
   350:     return button;
   351:   }  //setVerticalAlignment(T extends AbstractButton,int)
   352: 
   353:   //テキストフィールド
   354: 
   355:   //button = setHorizontalAlignment (textField, alignment)
   356:   //  JTextField.RIGHT
   357:   //  JTextField.LEFT (デフォルト)
   358:   //  JTextField.CENTER
   359:   //  JTextField.LEADING
   360:   //  JTextField.TRAILING
   361:   public static <T extends JTextField> T setHorizontalAlignment (T textField, int alignment) {
   362:     textField.setHorizontalAlignment (alignment);
   363:     return textField;
   364:   }  //setHorizontalAlignment(T extends JTextField,int)
   365: 
   366:   //テキストコンポーネント
   367: 
   368:   //component = setEditable (component, enabled)
   369:   //  コンポーネントが編集可能かどうか指定する
   370:   public static <T extends JTextComponent> T setEditable (T component, boolean enabled) {
   371:     component.setEditable (enabled);
   372:     return component;
   373:   }  //setEditable(T extends JTextComponent,boolean)
   374: 
   375: 
   376:   //--------------------------------------------------------------------------------
   377:   //フレームとダイアログを作る
   378:   //  ウインドウリスナー
   379:   //    ウインドウを開いたとき  activated,opened
   380:   //    フォーカスを失ったとき  deactivated
   381:   //    フォーカスを取得したとき  activated
   382:   //    ウインドウをアイコン化したとき  iconified,[deactivated]
   383:   //    ウインドウを元のサイズに戻したとき  deiconified,activated
   384:   //    ウインドウを閉じたとき  closing,[deactivated],closed
   385: 
   386:   //frame = createFrame (title, mnbMenuBar, component)
   387:   //  フレームを作る
   388:   //  すぐに開く
   389:   //  デフォルトのクローズボタンの動作はEXIT_ON_CLOSE
   390:   //  クローズボタンがクリックされたとき後始末を行なってから終了するとき
   391:   //    frame = createFrame (title, mnbMenuBar, component);
   392:   //    frame.setDefaultCloseOperation (WindowConstants.DISPOSE_ON_CLOSE);
   393:   //    frame.addWindowListener (new WindowAdapter () {
   394:   //      @Override public void windowClosed (WindowEvent we) {
   395:   //        後始末;
   396:   //        System.exit (0);
   397:   //      }
   398:   //    });
   399:   public static JFrame createFrame (String title, JMenuBar mnbMenuBar, JComponent component) {
   400:     JFrame frame = new JFrame (title);
   401:     frame.setUndecorated (true);  //ウインドウの枠を消す
   402:     frame.getRootPane().setWindowDecorationStyle (JRootPane.FRAME);  //飾り枠を描く
   403:     //frame.setLocationByPlatform (true);
   404:     frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
   405:     if (mnbMenuBar != null) {
   406:       frame.setJMenuBar (mnbMenuBar);
   407:     }
   408:     //frame.getContentPane ().add (component, BorderLayout.CENTER);
   409:     component.setOpaque (true);
   410:     frame.setContentPane (component);
   411:     frame.pack ();
   412:     frame.setVisible (true);
   413:     return frame;
   414:   }  //createFrame(String,JMenuBar,JComponent)
   415: 
   416:   public static JFrame createSubFrame (String title, JMenuBar mnbMenuBar, JComponent component) {
   417:     JFrame frame = new JFrame (title);
   418:     frame.setUndecorated (true);  //ウインドウの枠を消す
   419:     frame.getRootPane().setWindowDecorationStyle (JRootPane.FRAME);  //飾り枠を描く
   420:     frame.setLocationByPlatform (true);
   421:     frame.setDefaultCloseOperation (JFrame.HIDE_ON_CLOSE);
   422:     if (mnbMenuBar != null) {
   423:       frame.setJMenuBar (mnbMenuBar);
   424:     }
   425:     //frame.getContentPane ().add (component, BorderLayout.CENTER);
   426:     component.setOpaque (true);
   427:     frame.setContentPane (component);
   428:     frame.pack ();
   429:     return frame;
   430:   }  //createSubFrame(String,JMenuBar,JComponent)
   431: 
   432:   public static JFrame createRestorableFrame (String key, String title, JMenuBar mnbMenuBar, JComponent component) {
   433:     JFrame frame = new RestorableFrame (key, title);
   434:     frame.setUndecorated (true);  //ウインドウの枠を消す
   435:     frame.getRootPane().setWindowDecorationStyle (JRootPane.FRAME);  //飾り枠を描く
   436:     //frame.setLocationByPlatform (true);
   437:     frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
   438:     if (mnbMenuBar != null) {
   439:       frame.setJMenuBar (mnbMenuBar);
   440:     }
   441:     //frame.getContentPane ().add (component, BorderLayout.CENTER);
   442:     component.setOpaque (true);
   443:     frame.setContentPane (component);
   444:     frame.pack ();
   445:     frame.setVisible (true);
   446:     return frame;
   447:   }  //createRestorableFrame(String,String,JMenuBar,JComponent)
   448: 
   449:   public static JFrame createRestorableSubFrame (String key, String title, JMenuBar mnbMenuBar, JComponent component) {
   450:     JFrame frame = new RestorableFrame (key, title);
   451:     frame.setUndecorated (true);  //ウインドウの枠を消す
   452:     frame.getRootPane().setWindowDecorationStyle (JRootPane.FRAME);  //飾り枠を描く
   453:     //frame.setLocationByPlatform (true);
   454:     frame.setDefaultCloseOperation (JFrame.HIDE_ON_CLOSE);
   455:     if (mnbMenuBar != null) {
   456:       frame.setJMenuBar (mnbMenuBar);
   457:     }
   458:     //frame.getContentPane ().add (component, BorderLayout.CENTER);
   459:     component.setOpaque (true);
   460:     frame.setContentPane (component);
   461:     frame.pack ();
   462:     return frame;
   463:   }  //createRestorableSubFrame(String,String,JMenuBar,JComponent)
   464: 
   465:   //dialog = createModalDialog (owner, title, component)
   466:   //dialog = createModelessDialog (owner, title, component)
   467:   //dialog = createDialog (owner, title, component, modal)
   468:   //  ダイアログを作る(ownerを指定する)
   469:   //  まだ開かない
   470:   //  デフォルトのクローズボタンの動作はHIDE_ON_CLOSE
   471:   //  閉じてもdialog.setVisible(true)で再表示できる
   472:   public static JDialog createModalDialog (Frame owner, String title, JComponent component) {
   473:     return createDialog (owner, title, true, component);
   474:   }  //createModalDialog(Frame,String,JComponent)
   475:   public static JDialog createModelessDialog (Frame owner, String title, JComponent component) {
   476:     return createDialog (owner, title, false, component);
   477:   }  //createModelessDialog(Frame,String,JComponent)
   478:   public static JDialog createDialog (Frame owner, String title, boolean modal, JComponent component) {
   479:     JDialog dialog = new JDialog (owner, title, modal);
   480:     dialog.setUndecorated (true);  //ウインドウの枠を消す
   481:     dialog.getRootPane ().setWindowDecorationStyle (JRootPane.FRAME);  //飾り枠を描く
   482:     dialog.setAlwaysOnTop (modal);  //モーダルのときは常に手前に表示、モードレスのときは奥に移動できる
   483:     dialog.setLocationByPlatform (true);
   484:     dialog.setDefaultCloseOperation (WindowConstants.HIDE_ON_CLOSE);
   485:     dialog.getContentPane ().add (component, BorderLayout.CENTER);
   486:     dialog.pack ();
   487:     dialog.setVisible (false);
   488:     return dialog;
   489:   }  //createDialog(Frame,String,boolean,JComponent)
   490: 
   491: 
   492:   //--------------------------------------------------------------------------------
   493:   //パネルを作る
   494: 
   495:   //box = createHorizontalBox (component, ...)
   496:   //  コンポーネントを横に並べるボックスを作る
   497:   public static Box createHorizontalBox (Component... components) {
   498:     return addComponents (Box.createHorizontalBox (), components);
   499:   }  //createHorizontalBox(Component...)
   500: 
   501:   //box = createVerticalBox (component, ...)
   502:   //  コンポーネントを縦に並べるボックスを作る
   503:   public static Box createVerticalBox (Component... components) {
   504:     return addComponents (Box.createVerticalBox (), components);
   505:   }  //createVerticalBox(Component...)
   506: 
   507:   //box = createGlueBox (component)
   508:   //box = createGlueBox (orientation, component)
   509:   //  コンポーネントを引き伸ばさず指定された方向に寄せて表示する
   510:   //  component自身がmaximumSizeを持っていること
   511:   //  componentがBorderLayoutでCENTERがmaximumSizeを持っているのではダメ
   512:   //  orientation
   513:   //    SwingConstants.NORTH_WEST SwingConstants.NORTH  SwingConstants.NORTH_EAST
   514:   //    SwingConstants.WEST       SwingConstants.CENTER SwingConstants.EAST
   515:   //    SwingConstants.SOUTH_WEST SwingConstants.SOUTH  SwingConstants.SOUTH_EAST
   516:   public static Box createGlueBox (JComponent component) {
   517:     return createGlueBox (SwingConstants.CENTER, component);
   518:   }  //createGlueBox(JComponent)
   519:   public static Box createGlueBox (int orientation, JComponent component) {
   520:     Box box = (orientation == SwingConstants.NORTH_WEST ||
   521:                orientation == SwingConstants.WEST ||
   522:                orientation == SwingConstants.SOUTH_WEST ?
   523:                createHorizontalBox (component, Box.createHorizontalGlue ()) :
   524:                orientation == SwingConstants.NORTH_EAST ||
   525:                orientation == SwingConstants.EAST ||
   526:                orientation == SwingConstants.SOUTH_EAST ?
   527:                createHorizontalBox (Box.createHorizontalGlue (), component) :
   528:                createHorizontalBox (Box.createHorizontalGlue (), component, Box.createHorizontalGlue ()));
   529:     return (orientation == SwingConstants.NORTH_WEST ||
   530:             orientation == SwingConstants.NORTH ||
   531:             orientation == SwingConstants.NORTH_EAST ?
   532:             createVerticalBox (box, Box.createVerticalGlue ()) :
   533:             orientation == SwingConstants.SOUTH_WEST ||
   534:             orientation == SwingConstants.SOUTH ||
   535:             orientation == SwingConstants.SOUTH_EAST ?
   536:             createVerticalBox (Box.createVerticalGlue (), box) :
   537:             createVerticalBox (Box.createVerticalGlue (), box, Box.createVerticalGlue ()));
   538:   }  //createGlueBox(int,JComponent)
   539: 
   540:   //panel = createFlowPanel (component, ...)
   541:   //panel = createFlowPanel (align, component, ...)
   542:   //panel = createFlowPanel (hgap ,vgap, component, ...)
   543:   //panel = createFlowPanel (align, hgap, vgap, component, ...)
   544:   //  FlowLayoutのパネルを作る
   545:   //  align
   546:   //    FlowLayout.CENTER  中央揃え
   547:   //    FlowLayout.LEFT    左揃え
   548:   //    FlowLayout.RIGHT   右揃え
   549:   public static JPanel createFlowPanel (Component... components) {
   550:     return createFlowPanel (FlowLayout.LEFT, 0, 0, components);
   551:   }  //createFlowPanel(Component...)
   552:   public static JPanel createFlowPanel (int align, Component... components) {
   553:     return createFlowPanel (align, 0, 0, components);
   554:   }  //createFlowPanel(int,Component...)
   555:   public static JPanel createFlowPanel (int hgap, int vgap, Component... components) {
   556:     return createFlowPanel (FlowLayout.LEFT, hgap, vgap, components);
   557:   }  //createFlowPanel(int,int,Component...)
   558:   public static JPanel createFlowPanel (int align, int hgap, int vgap, Component... components) {
   559:     JPanel panel = new JPanel (new FlowLayout (align, hgap, vgap));
   560:     panel.setOpaque (true);
   561:     return addComponents (panel, components);
   562:   }  //createFlowPanel(int,int,int,Component...)
   563: 
   564:   //panel = createBorderPanel (component, ...)
   565:   //panel = createBorderPanel (hgap, vgap, component, ...)
   566:   //  BorderLayoutのパネルを作る
   567:   //  コンポーネントをCENTER,NORTH,WEST,SOUTH,EASTの順序で指定する
   568:   //  末尾のコンポーネントを省略するか途中のコンポーネントにnullを指定するとその部分は設定されない
   569:   public static JPanel createBorderPanel (JComponent... components) {
   570:     return createBorderPanel (0, 0, components);
   571:   }  //createBorderPanel(JComponent...)
   572:   public static JPanel createBorderPanel (int hgap, int vgap, JComponent... components) {
   573:     JPanel panel = new JPanel (new BorderLayout (hgap, vgap));
   574:     panel.setOpaque (true);
   575:     if (components.length >= 1) {
   576:       if (components[0] != null) {
   577:         panel.add (components[0], BorderLayout.CENTER);
   578:       }
   579:       if (components.length >= 2) {
   580:         if (components[1] != null) {
   581:           panel.add (components[1], BorderLayout.NORTH);
   582:         }
   583:         if (components.length >= 3) {
   584:           if (components[2] != null) {
   585:             panel.add (components[2], BorderLayout.WEST);
   586:           }
   587:           if (components.length >= 4) {
   588:             if (components[3] != null) {
   589:               panel.add (components[3], BorderLayout.SOUTH);
   590:             }
   591:             if (components.length >= 5 && components[4] != null) {
   592:               panel.add (components[4], BorderLayout.EAST);
   593:             }
   594:           }
   595:         }
   596:       }
   597:     }
   598:     return panel;
   599:   }  //createBorderPanel(int,int,JComponent...)
   600: 
   601:   //panel = createGridPanel (colCount, rowCount, gridStyles, colStyless, rowStyless, cellStyless, objectArray, ...)
   602:   //  GridBagLayoutのパネルを作る
   603:   //    colCount          列数
   604:   //    rowCount          行数
   605:   //    gridStyles        すべてのセルの共通のスタイル
   606:   //    colStyles         列毎の共通のスタイル。列の区切りは";"。スタイルの区切りは","
   607:   //    rowStyles         行毎の共通のスタイル。行の区切りは";"。スタイルの区切りは","
   608:   //    cellStyles        個々のセルのスタイル。セルの区切りは";"。スタイルの区切りは","。上または左のセルが重なっているセルは含まない
   609:   //                      colSpan        列数
   610:   //                      rowSpan        行数
   611:   //                      width          幅
   612:   //                      height         高さ
   613:   //                      widen          幅をいっぱいまで伸ばす
   614:   //                      lengthen       高さをいっぱいまで伸ばす
   615:   //                      center         左右に寄せない
   616:   //                      left           左に寄せる
   617:   //                      right          右に寄せる
   618:   //                      middle         上下に寄せない
   619:   //                      top            上に寄せる
   620:   //                      bottom         下に寄せる
   621:   //                      paddingTop     上端のパディング
   622:   //                      paddingRight   右端のパディング
   623:   //                      paddingBottom  下端のパディング
   624:   //                      paddingLeft    左端のパディング
   625:   //                      bold           ボールド
   626:   //                      italic         イタリック
   627:   //    objectArray, ...  セルに表示するオブジェクトの配列。長さが列数×行数よりも少ないときは上または左のセルが重なっているセルが詰められていると判断される。このときcellStylesも詰められたインデックスで参照される
   628:   //  gridStyles;colStyles;rowStyles;cellStylesの順序で個々のセルに対応するスタイルが連結される
   629:   //  同時に指定できないスタイルは後から指定した方が優先される
   630:   public static JPanel createGridPanel (int colCount, int rowCount, String gridStyles, String colStyless, String rowStyless, String cellStyless, Object... objectArray) {
   631:     String[] colStylesArray = (colStyless != null ? colStyless : "").split (";");
   632:     String[] rowStylesArray = (rowStyless != null ? rowStyless : "").split (";");
   633:     String[] cellStylesArray = (cellStyless != null ? cellStyless : "").split (";");
   634:     int cellCount = colCount * rowCount;
   635:     //Component[] componentArray = new Component[cellCount];  //セルのオブジェクト。上または左のセルが重なっているセルは含まない
   636:     boolean[] cellFilledArray = new boolean[cellCount];  //セルが充填済みかどうか。colCount*rowCountのセルをすべて含む
   637:     GridBagLayout gridbag = new GridBagLayout ();
   638:     JPanel panel = new JPanel (gridbag);
   639:     GridBagConstraints c = new GridBagConstraints ();
   640:     int objectIndex = 0;  //objectArrayとcellStylesArrayの詰められたインデックス
   641:     boolean objectClosed = objectArray.length < cellCount;  //objectArrayとcellStylesArrayが詰められている(上または左のセルが重なっているセルを含まない)。objectArray[objectClosed?objectIndex:cellIndex]
   642:     for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) {
   643:       for (int colIndex = 0; colIndex < colCount; colIndex++) {
   644:         int cellIndex = colIndex + colCount * rowIndex;  //セルのインデックス。colCount*rowCountのセルをすべて含む
   645:         if (cellFilledArray[cellIndex]) {  //充填済み
   646:           continue;
   647:         }
   648:         int colSpan = 1;
   649:         int rowSpan = 1;
   650:         int width = 1;
   651:         int height = 1;
   652:         int fill = 0;  //1=widen,2=lengthen
   653:         int anchor = 0;  //1=left,2=right,4=top,8=bottom
   654:         int paddingTop = 0;
   655:         int paddingRight = 0;
   656:         int paddingBottom = 0;
   657:         int paddingLeft = 0;
   658:         int fontStyle = 0;  //1=bold,2=italic
   659:         for (String style : ((gridStyles != null ? gridStyles : "") + "," +
   660:                              (colIndex < colStylesArray.length ? colStylesArray[colIndex] : "") + "," +
   661:                              (rowIndex < rowStylesArray.length ? rowStylesArray[rowIndex] : "") + "," +
   662:                              ((objectClosed ? objectIndex : cellIndex) < cellStylesArray.length ? cellStylesArray[objectClosed ? objectIndex : cellIndex] : "")).split (",")) {
   663:           String[] keyValue = style.split ("=");
   664:           String key = keyValue.length < 1 ? "" : keyValue[0].trim ();
   665:           int value = keyValue.length < 2 ? 1 : Integer.parseInt (keyValue[1]);
   666:           switch (key) {
   667:           case "colSpan":  //列数
   668:             colSpan = value;
   669:             break;
   670:           case "rowSpan":  //行数
   671:             rowSpan = value;
   672:             break;
   673:           case "width":  //幅
   674:             width = value;
   675:             break;
   676:           case "height":  //高さ
   677:             height = value;
   678:             break;
   679:           case "widen":  //幅をいっぱいまで伸ばす
   680:             fill |= 1;
   681:             break;
   682:           case "lengthen":  //高さをいっぱいまで伸ばす
   683:             fill |= 2;
   684:             break;
   685:           case "center":  //左右に寄せない
   686:             anchor &= ~0b0011;
   687:             break;
   688:           case "left":  //左に寄せる
   689:             anchor = anchor & ~0b0011 | 0b0001;
   690:             break;
   691:           case "right":  //右に寄せる
   692:             anchor = anchor & ~0b0011 | 0b0010;
   693:             break;
   694:           case "middle":  //上下に寄せない
   695:             anchor &= ~0b1100;
   696:             break;
   697:           case "top":  //上に寄せる
   698:             anchor = anchor & ~0b1100 | 0b0100;
   699:             break;
   700:           case "bottom":  //下に寄せる
   701:             anchor = anchor & ~0b1100 | 0b1000;
   702:             break;
   703:           case "paddingTop":  //上端のパディング
   704:             paddingTop = value;
   705:             break;
   706:           case "paddingRight":  //右端のパディング
   707:             paddingRight = value;
   708:             break;
   709:           case "paddingBottom":  //下端のパディング
   710:             paddingBottom = value;
   711:             break;
   712:           case "paddingLeft":  //左端のパディング
   713:             paddingLeft = value;
   714:             break;
   715:           case "bold":  //ボールド
   716:             fontStyle |= 1;
   717:             break;
   718:           case "italic":  //イタリック
   719:             fontStyle |= 2;
   720:             break;
   721:           }
   722:         }
   723:         c.gridx = colIndex;
   724:         c.gridy = rowIndex;
   725:         c.gridwidth = colSpan;
   726:         c.gridheight = rowSpan;
   727:         c.weightx = 0.0;
   728:         c.weighty = 0.0;
   729:         c.fill = (fill == 1 ? GridBagConstraints.HORIZONTAL :
   730:                   fill == 2 ? GridBagConstraints.VERTICAL :
   731:                   fill == 3 ? GridBagConstraints.BOTH :
   732:                   GridBagConstraints.NONE);
   733:         c.anchor = (anchor == 0b0001 ? GridBagConstraints.WEST :
   734:                     anchor == 0b0010 ? GridBagConstraints.EAST :
   735:                     anchor == 0b0100 ? GridBagConstraints.NORTH :
   736:                     anchor == 0b1000 ? GridBagConstraints.SOUTH :
   737:                     anchor == 0b0101 ? GridBagConstraints.NORTHWEST :
   738:                     anchor == 0b0110 ? GridBagConstraints.NORTHEAST :
   739:                     anchor == 0b1001 ? GridBagConstraints.SOUTHWEST :
   740:                     anchor == 0b1010 ? GridBagConstraints.SOUTHEAST :
   741:                     GridBagConstraints.CENTER);
   742:         c.insets = new Insets (paddingTop, paddingLeft, paddingBottom, paddingRight);
   743:         Object object = (objectClosed ? objectIndex : cellIndex) < objectArray.length ? objectArray[objectClosed ? objectIndex : cellIndex] : null;
   744:         Component component;
   745:         if (object == null) {
   746:           component = new JPanel ();
   747:         } else if (object instanceof String) {
   748:           String string = (String) object;
   749:           component = string.startsWith ("http://") ? createAnchor (string, string) : createLabel ((String) object);
   750:         } else if (object instanceof Component) {
   751:           component = (Component) object;
   752:         } else {
   753:           component = new JPanel ();
   754:         }
   755:         if (component instanceof JLabel) {
   756:           JLabel label = (JLabel) component;
   757:           if (fontStyle == 1) {
   758:             bold (label);
   759:           } else if (fontStyle == 2) {
   760:             italic (label);
   761:           } else if (fontStyle == 3) {
   762:             boldItalic (label);
   763:           }
   764:         }
   765: 
   766:         component.setMinimumSize (new Dimension (width, height));
   767:         if (width > 1 || height > 1) {
   768:           component.setPreferredSize (new Dimension (width, height));
   769:         }
   770:         gridbag.setConstraints (component, c);
   771:         panel.add (component);
   772:         //componentArray[objectIndex] = component;
   773:         for (int y = 0; y < rowSpan; y++) {
   774:           for (int x = 0; x < colSpan; x++) {
   775:             cellFilledArray[(colIndex + x) + colCount * (rowIndex + y)] = true;
   776:           }
   777:         }
   778: 
   779:         objectIndex++;
   780:       }  //for colIndex
   781:     }  //for rowIndex
   782:     return panel;
   783:   }  //createGridPanel(int,int,String,String,String,String,Object...)
   784: 
   785:   //scrollPane = createScrollPane (view)
   786:   //scrollPane = createScrollPane (view, vsbPolicy, hsbPolicy)
   787:   //  スクロールペインを作る
   788:   //  推奨サイズが必要なので通常はsetPreferredSize (createScrollPane (view), width, height)の形式で作る
   789:   //  vsbPolicy
   790:   //    ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED
   791:   //    ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER
   792:   //    ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS
   793:   //  hsbPolicy
   794:   //    ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED
   795:   //    ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER
   796:   //    ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS
   797:   public static JScrollPane createScrollPane (Component view) {
   798:     return createScrollPane (view,
   799:                              ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
   800:                              ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
   801:   }  //createScrollPane(Component)
   802:   public static JScrollPane createScrollPane (Component view, int vsbPolicy, int hsbPolicy) {
   803:     return new JScrollPane (view, vsbPolicy, hsbPolicy);
   804:   }  //createScrollPane(Component,int,int)
   805: 
   806:   //splitPane = createHorizontalSplitPane (component, ...)
   807:   //splitPane = createVerticalSplitPane (component, ...)
   808:   //splitPane = createSplitPane (orientation, component, ...)
   809:   //  スプリットペインを作る
   810:   //  orientation
   811:   //    JSplitPane.HORIZONTAL_SPLIT
   812:   //    JSplitPane.VERTICAL_SPLIT
   813:   public static JSplitPane createHorizontalSplitPane (Component... components) {
   814:     return createSplitPane (JSplitPane.HORIZONTAL_SPLIT, components);
   815:   }  //createHorizontalSplitPane(Component...)
   816:   public static JSplitPane createVerticalSplitPane (Component... components) {
   817:     return createSplitPane (JSplitPane.VERTICAL_SPLIT, components);
   818:   }  //createVerticalSplitPane(Component...)
   819:   public static JSplitPane createSplitPane (int orientation, Component... components) {
   820:     JSplitPane splitPane = new JSplitPane (orientation, true, components[0], components[1]);
   821:     for (int i = 2; i < components.length; i++) {
   822:       splitPane = new JSplitPane (orientation, true, splitPane, components[i]);  //((0,1),2)...
   823:     }
   824:     return splitPane;
   825:   }  //createSplitPane(int,Component...)
   826: 
   827: 
   828:   //--------------------------------------------------------------------------------
   829:   //セパレータを作る
   830: 
   831:   //separator = createHorizontalSeparator ()
   832:   //separator = createVerticalSeparator ()
   833:   //  セパレータを作る
   834:   public static JSeparator createHorizontalSeparator () {
   835:     return new JSeparator (SwingConstants.HORIZONTAL);
   836:   }  //createHorizontalSeparator()
   837:   public static JSeparator createVerticalSeparator () {
   838:     return new JSeparator (SwingConstants.VERTICAL);
   839:   }  //createVerticalSeparator()
   840: 
   841: 
   842:   //--------------------------------------------------------------------------------
   843:   //ラベルを作る
   844: 
   845:   //label = createLabel (enText)
   846:   //label = createLabel (enText, alignment)
   847:   //  ラベルを作る
   848:   public static JLabel createLabel (String enText) {
   849:     return createLabel (enText, SwingConstants.CENTER);
   850:   }  //createLabel(String)
   851:   public static JLabel createLabel (String enText, int alignment) {
   852:     JLabel label = new JLabel (enText);
   853:     label.setForeground (MetalLookAndFeel.getBlack ());  //black
   854:     if (alignment == SwingConstants.NORTH_WEST ||
   855:         alignment == SwingConstants.NORTH ||
   856:         alignment == SwingConstants.NORTH_EAST ||
   857:         alignment == SwingConstants.TOP) {
   858:       label.setVerticalAlignment (SwingConstants.TOP);
   859:     } else if (alignment == SwingConstants.SOUTH_WEST ||
   860:         alignment == SwingConstants.SOUTH ||
   861:         alignment == SwingConstants.SOUTH_EAST ||
   862:         alignment == SwingConstants.BOTTOM) {
   863:       label.setVerticalAlignment (SwingConstants.BOTTOM);
   864:     } else if (alignment == SwingConstants.CENTER) {
   865:       label.setVerticalAlignment (SwingConstants.CENTER);
   866:     }
   867:     if (alignment == SwingConstants.NORTH_WEST ||
   868:         alignment == SwingConstants.WEST ||
   869:         alignment == SwingConstants.SOUTH_WEST ||
   870:         alignment == SwingConstants.LEFT) {
   871:       label.setHorizontalAlignment (SwingConstants.LEFT);
   872:     } else if (alignment == SwingConstants.NORTH_EAST ||
   873:         alignment == SwingConstants.EAST ||
   874:         alignment == SwingConstants.SOUTH_EAST ||
   875:         alignment == SwingConstants.RIGHT) {
   876:       label.setHorizontalAlignment (SwingConstants.RIGHT);
   877:     } else if (alignment == SwingConstants.CENTER) {
   878:       label.setHorizontalAlignment (SwingConstants.CENTER);
   879:     }
   880:     return label;
   881:   }  //createLabel(String,int)
   882: 
   883:   //label = createIconLabel (image)
   884:   //  アイコンラベルを作る
   885:   public static JLabel createIconLabel (Image image) {
   886:     JLabel label = new JLabel (new ImageIcon (image));
   887:     label.setBorder (new EmptyBorder (1, 1, 1, 1));  //アイコンボタンと同じサイズにする
   888:     return label;
   889:   }  //createIconLabel(Image)
   890: 
   891: 
   892:   //--------------------------------------------------------------------------------
   893:   //アンカーを作る
   894:   //  下線付きラベル
   895:   //  マウスカーソルは手の形
   896:   //  クリックされたらあらかじめ設定されたURIをブラウザに渡す
   897: 
   898:   //label = createAnchor (enText, uri)
   899:   //  アンカーを作る
   900:   public static boolean isObsoleteURI (String uri) {
   901:     return uri.startsWith ("http://www.nifty.ne.jp/forum/");  //"fsharp/"。リンク先が存在しないURI
   902:   }  //isObsoleteURI(String)
   903:   public static JLabel createAnchor (String enText, String uri) {
   904:     JLabel label = new UnderlinedLabel (enText);  //下線付きラベル
   905:     label.setForeground (MetalLookAndFeel.getBlack ());  //black
   906:     if (uri != null) {
   907:       if (isObsoleteURI (uri)) {
   908:         uri = "http://web.archive.org/web/" + "*" + "/" + uri;
   909:       }
   910:       label.setCursor (Cursor.getPredefinedCursor (Cursor.HAND_CURSOR));  //マウスカーソルは手の形
   911:       label.setToolTipText (uri);
   912:       label.addMouseListener (new AnchorAdapter (uri));  //クリックされたらあらかじめ設定されたURIをブラウザに渡す
   913:     }
   914:     return label;
   915:   }  //createAnchor(String,String)
   916: 
   917: 
   918:   //--------------------------------------------------------------------------------
   919:   //テキストフィールドを作る
   920: 
   921:   //textField = createTextField (text, columns)
   922:   //  テキストフィールドを作る
   923:   public static JTextField createTextField (String text, int columns) {
   924:     return new JTextField (text, columns);
   925:   }  //createTextField(String,int)
   926: 
   927:   //textField = createNumberField (text, columns)
   928:   //  数値入力用のテキストフィールドを作る
   929:   public static JTextField createNumberField (String text, int columns) {
   930:     return setHorizontalAlignment (
   931:       setFixedSize (
   932:         setFont (
   933:           new JTextField (text),  //columnを指定すると幅を調節できなくなる
   934:           new Font ("Monospaced", Font.PLAIN, 12)),
   935:         10 + 6 * columns, 16),
   936:       JTextField.RIGHT);
   937:   }  //createNumberField(int,int)
   938: 
   939: 
   940:   //--------------------------------------------------------------------------------
   941:   //スクロールテキストエリアを作る
   942: 
   943:   //scrollTextArea = createScrollTextArea (text, width, height)
   944:   //scrollTextArea = createScrollTextArea (text, width, height, editable)
   945:   //  スクロールテキストエリアを作る
   946:   public static ScrollTextArea createScrollTextArea (String text, int width, int height) {
   947:     return createScrollTextArea (text, width, height, false);
   948:   }  //createScrollTextArea(String,int,int)
   949:   public static ScrollTextArea createScrollTextArea (String text, int width, int height, boolean editable) {
   950:     ScrollTextArea scrollTextArea = setPreferredSize (
   951:       setFont (new ScrollTextArea (), new Font ("Monospaced", Font.PLAIN, 12)),
   952:       width, height);
   953:     setEmptyBorder (scrollTextArea, 0, 0, 0, 0);
   954:     scrollTextArea.setMargin (new Insets (2, 4, 2, 4));  //グリッドを更新させるためJTextAreaではなくScrollTextAreaに設定する必要がある
   955:     JTextArea textArea = scrollTextArea.getTextArea ();
   956:     textArea.setEditable (editable);
   957:     scrollTextArea.setText (text);
   958:     scrollTextArea.setCaretPosition (0);
   959:     return scrollTextArea;
   960:   }  //createScrollTextArea(String,int,int,boolean)
   961: 
   962: 
   963:   //--------------------------------------------------------------------------------
   964:   //スクロールテキストペインを作る
   965: 
   966:   //scrollTextPane = createScrollTextPane (text, width, height)
   967:   //  スクロールテキストペインを作る
   968:   //  http://~の部分がハイパーリンクになる
   969:   //    許諾条件.txtの中に"(http://www.nifty.ne.jp/forum/fsharp/)"という部分がある
   970:   //    ')'はURIに使える文字なので正しい方法では分離することができない
   971:   //    ここではhttp://の直前に'('があるときは')'をURIに使えない文字とみなすことにする
   972:   public static JScrollPane createScrollTextPane (String text, int width, int height) {
   973:     JTextPane textPane = new JTextPane ();
   974:     StyledDocument document = textPane.getStyledDocument ();
   975:     Style defaultStyle = document.addStyle ("default", StyleContext.getDefaultStyleContext ().getStyle (StyleContext.DEFAULT_STYLE));
   976:     int anchorNumber = 0;
   977:     //  http://user:passwd@host:port/path?query#hash → http://host/path?query
   978:     //Matcher matcher = Pattern.compile ("\\bhttp://[-.0-9A-Za-z]*(?:/(?:[!$&-;=?-Z_a-z~]|%[0-9A-Fa-f]{2})*)?").matcher (text);
   979:     Matcher matcher = Pattern.compile ("\\b" +
   980:                                        "(?:" +
   981:                                        "(?<!\\()http://[-.0-9A-Za-z]*(?:/(?:[!$&-;=?-Z_a-z~]|%[0-9A-Fa-f]{2})*)?" +
   982:                                        "|" +
   983:                                        "(?<=\\()http://[-.0-9A-Za-z]*(?:/(?:[!$&-(*-;=?-Z_a-z~]|%[0-9A-Fa-f]{2})*)?" +
   984:                                        ")").matcher (text);
   985:     try {
   986:       int start = 0;
   987:       while (matcher.find ()) {
   988:         int end = matcher.start ();  //ハイパーリンクの開始位置
   989:         if (start < end) {
   990:           document.insertString (document.getLength (), text.substring (start, end), defaultStyle);  //ハイパーリンクの手前のテキスト
   991:         }
   992:         String anchorHref = matcher.group ();  //ハイパーリンク
   993:         Style anchorStyle = document.addStyle ("anchor" + anchorNumber++, defaultStyle);
   994:         JLabel anchorLabel = createAnchor (anchorHref, anchorHref);
   995:         Dimension anchorSize = anchorLabel.getPreferredSize ();
   996:         anchorLabel.setAlignmentY ((float) anchorLabel.getBaseline (anchorSize.width, anchorSize.height) / (float) anchorSize.height);  //JLabelのベースラインをテキストに合わせる
   997:         StyleConstants.setComponent (anchorStyle, anchorLabel);
   998:         document.insertString (document.getLength (), anchorHref, anchorStyle);
   999:         start = matcher.end ();  //ハイパーリンクの終了位置
  1000:       }
  1001:       document.insertString (document.getLength (), text.substring (start), defaultStyle);  //残りのテキスト
  1002:     } catch (BadLocationException ble) {
  1003:     }
  1004:     textPane.setMargin (new Insets (2, 4, 2, 4));
  1005:     textPane.setEditable (false);
  1006:     textPane.setCaretPosition (0);
  1007:     JScrollPane scrollPane = new JScrollPane (textPane);
  1008:     scrollPane.setPreferredSize (new Dimension (width, height));
  1009:     return scrollPane;
  1010:   }  //createScrollTextPane(String,int,int)
  1011: 
  1012: 
  1013:   //--------------------------------------------------------------------------------
  1014:   //ボタンを作る
  1015: 
  1016:   //button = createButton (enText, listener)
  1017:   //button = createButton (enText, mnemonic, listener)
  1018:   //  テキストのボタンを作る
  1019:   public static JButton createButton (String enText, ActionListener listener) {
  1020:     return createButton (enText, KeyEvent.VK_UNDEFINED, listener);
  1021:   }  //createButton(String,ActionListener)
  1022:   public static JButton createButton (String enText, int mnemonic, ActionListener listener) {
  1023:     JButton button = new JButton ();
  1024:     return setButtonCommons (button, enText, mnemonic, listener);  //ボタンの共通の設定
  1025:   }  //createButton(String,int,ActionListener)
  1026: 
  1027:   //button = createButton (image, enText, listener)
  1028:   //button = createButton (image, enText, mnemonic, listener)
  1029:   //button = createButton (image, disabledImage, enText, listener)
  1030:   //button = createButton (image, disabledImage, enText, mnemonic, listener)
  1031:   //  アイコンとテキストのボタンを作る
  1032:   public static JButton createButton (Image image, String enText, ActionListener listener) {
  1033:     return createButton (image, null, enText, KeyEvent.VK_UNDEFINED, listener);
  1034:   }  //createButton(Image,String,ActionListener)
  1035:   public static JButton createButton (Image image, String enText, int mnemonic, ActionListener listener) {
  1036:     return createButton (image, null, enText, mnemonic, listener);
  1037:   }  //createButton(Image,String,int,ActionListener)
  1038:   public static JButton createButton (Image image, Image disabledImage, String enText, ActionListener listener) {
  1039:     return createButton (image, disabledImage, enText, KeyEvent.VK_UNDEFINED, listener);
  1040:   }  //createButton(Image,Image,String,ActionListener)
  1041:   public static JButton createButton (Image image, Image disabledImage, String enText, int mnemonic, ActionListener listener) {
  1042:     JButton button = new JButton (new ImageIcon (image));
  1043:     if (disabledImage != null) {
  1044:       button.setDisabledIcon (new ImageIcon (disabledImage));
  1045:     }
  1046:     button.setBorder (new EmptyBorder (1, 1, 1, 1));
  1047:     button.setIconTextGap (3);
  1048:     return setButtonCommons (button, enText, mnemonic, listener);  //ボタンの共通の設定
  1049:   }  //createButton(Image,Image,String,int,ActionListener)
  1050: 
  1051:   //button = createIconButton (icon, enToolTipText, listener)
  1052:   //button = createIconButton (icon, disabledIcon, enToolTipText, listener)
  1053:   //button = createImageButton (image, enToolTipText, listener)
  1054:   //button = createImageButton (image, disabledImage, enToolTipText, listener)
  1055:   //  アイコンのみのボタンを作る
  1056:   //  ツールチップテキストをそのままアクションコマンドにする
  1057:   public static JButton createIconButton (ImageIcon icon, String enToolTipText, ActionListener listener) {
  1058:     return createIconButton (icon, null, enToolTipText, listener);
  1059:   }  //createIconButton(ImageIcon,String,ActionListener)
  1060:   public static JButton createIconButton (ImageIcon icon, ImageIcon disabledIcon, String enToolTipText, ActionListener listener) {
  1061:     JButton button = new JButton (icon);
  1062:     if (disabledIcon != null) {
  1063:       button.setDisabledIcon (disabledIcon);
  1064:     }
  1065:     //button.setContentAreaFilled (false);
  1066:     button.setBorder (new EmptyBorder (1, 1, 1, 1));
  1067:     //button.setBorderPainted (false);
  1068:     //button.setMargin (new Insets (0, 0, 0, 0));
  1069:     if (enToolTipText != null) {
  1070:       button.setToolTipText (enToolTipText);
  1071:       button.setActionCommand (enToolTipText);
  1072:     }
  1073:     return addListener (button, listener);
  1074:   }  //createIconButton(ImageIcon,ImageIcon,String,ActionListener)
  1075:   public static JButton createImageButton (Image image, String enToolTipText, ActionListener listener) {
  1076:     return createImageButton (image, null, enToolTipText, listener);
  1077:   }  //createImageButton(Image,String,ActionListener)
  1078:   public static JButton createImageButton (Image image, Image disabledImage, String enToolTipText, ActionListener listener) {
  1079:     JButton button = new JButton (new ImageIcon (image));
  1080:     if (disabledImage != null) {
  1081:       button.setDisabledIcon (new ImageIcon (disabledImage));
  1082:     }
  1083:     //button.setContentAreaFilled (false);
  1084:     button.setBorder (new EmptyBorder (1, 1, 1, 1));
  1085:     //button.setBorderPainted (false);
  1086:     //button.setMargin (new Insets (0, 0, 0, 0));
  1087:     if (enToolTipText != null) {
  1088:       button.setToolTipText (enToolTipText);
  1089:       button.setActionCommand (enToolTipText);
  1090:     }
  1091:     return addListener (button, listener);
  1092:   }  //createImageButton(Image,Image,String,ActionListener)
  1093: 
  1094:   //button = createCheckBox (selected, enText, listener)
  1095:   //button = createCheckBox (selected, enText, mnemonic, listener)
  1096:   //  チェックボックスを作る
  1097:   public static JCheckBox createCheckBox (boolean selected, String enText, ActionListener listener) {
  1098:     return createCheckBox (selected, enText, KeyEvent.VK_UNDEFINED, listener);
  1099:   }  //createCheckBox(boolean,String,ActionListener)
  1100:   public static JCheckBox createCheckBox (boolean selected, String enText, int mnemonic, ActionListener listener) {
  1101:     JCheckBox button = new JCheckBox ();
  1102:     button.setBorder (new EmptyBorder (0, 0, 0, 0));
  1103:     button.setSelected (selected);
  1104:     return setButtonCommons (button, enText, mnemonic, listener);  //ボタンの共通の設定
  1105:   }  //createCheckBox(boolean,String,int,ActionListener)
  1106: 
  1107:   //button = createIconCheckBox (selected, image, selectedImage, enToolTipText, listener)
  1108:   //button = createIconCheckBox (selected, image, selectedImage, disabledImage, disabledSelectedImage, enToolTipText, listener)
  1109:   //  アイコンチェックボックスを作る
  1110:   //  ツールチップテキストをそのままアクションコマンドにする
  1111:   public static JCheckBox createIconCheckBox (boolean selected, Image image, Image selectedImage, String enToolTipText, ActionListener listener) {
  1112:     return createIconCheckBox (selected, image, selectedImage, null, null, enToolTipText, listener);
  1113:   }  //createIconCheckBox(boolean,Image,Image,String,ActionListener)
  1114:   public static JCheckBox createIconCheckBox (boolean selected, Image image, Image selectedImage, Image disabledImage, Image disabledSelectedImage, String enToolTipText, ActionListener listener) {
  1115:     JCheckBox button = new JCheckBox (new ImageIcon (image));
  1116:     button.setBorder (new EmptyBorder (1, 1, 1, 1));
  1117:     button.setSelected (selected);
  1118:     button.setSelectedIcon (new ImageIcon (selectedImage));
  1119:     if (disabledImage != null) {
  1120:       button.setDisabledIcon (new ImageIcon (disabledImage));
  1121:     }
  1122:     if (disabledSelectedImage != null) {
  1123:       button.setDisabledSelectedIcon (new ImageIcon (disabledSelectedImage));
  1124:     }
  1125:     if (enToolTipText != null) {
  1126:       button.setToolTipText (enToolTipText);
  1127:       button.setActionCommand (enToolTipText);
  1128:     }
  1129:     return addListener (button, listener);
  1130:   }  //createIconCheckBox(boolean,Image,Image,Image,Image,String,ActionListener)
  1131: 
  1132:   //radioButton = createRadioButton (group, selected, enText, listener)
  1133:   //radioButton = createRadioButton (group, selected, enText, mnemonic, listener)
  1134:   //  ラジオボタンを作る
  1135:   public static JRadioButton createRadioButton (ButtonGroup group, boolean selected, String enText, ActionListener listener) {
  1136:     return createRadioButton (group, selected, enText, KeyEvent.VK_UNDEFINED, listener);
  1137:   }  //createRadioButton(ButtonGroup,boolean,String,ActionListener)
  1138:   public static JRadioButton createRadioButton (ButtonGroup group, boolean selected, String enText, int mnemonic, ActionListener listener) {
  1139:     JRadioButton button = new JRadioButton ();
  1140:     button.setBorder (new EmptyBorder (0, 0, 0, 0));
  1141:     group.add (button);
  1142:     button.setSelected (selected);
  1143:     return setButtonCommons (button, enText, mnemonic, listener);  //ボタンの共通の設定
  1144:   }  //createRadioButton(ButtonGroup,boolean,String,int,ActionListener)
  1145: 
  1146:   //button = createIconRadioButton (group, selected, image, selectedImage, enToolTipText, listener)
  1147:   //  アイコンラジオボタンを作る
  1148:   //  ツールチップテキストをそのままアクションコマンドにする
  1149:   public static JRadioButton createIconRadioButton (ButtonGroup group, boolean selected, Image image, Image selectedImage, String enToolTipText, ActionListener listener) {
  1150:     JRadioButton button = new JRadioButton (new ImageIcon (image));
  1151:     button.setBorder (new EmptyBorder (1, 1, 1, 1));
  1152:     group.add (button);
  1153:     button.setSelected (selected);
  1154:     button.setSelectedIcon (new ImageIcon (selectedImage));
  1155:     if (enToolTipText != null) {
  1156:       button.setToolTipText (enToolTipText);
  1157:       button.setActionCommand (enToolTipText);
  1158:     }
  1159:     return addListener (button, listener);
  1160:   }  //createIconRadioButton(ButtonGroup,boolean,Image,Image,String,int,ActionListener)
  1161: 
  1162: 
  1163:   //--------------------------------------------------------------------------------
  1164:   //コンボボックスを作る
  1165: 
  1166:   //comboBox = createComboBox (selectedIndex, enToolTipText, listener, text, ...)
  1167:   //  コンボボックスを作る
  1168:   public static JComboBox<String> createComboBox (int selectedIndex, String enToolTipText, ActionListener listener, String... texts) {
  1169:     JComboBox<String> comboBox = new JComboBox<String> (texts);
  1170:     comboBox.setBorder (new EmptyBorder (0, 0, 0, 0));
  1171:     comboBox.setSelectedIndex (selectedIndex);
  1172:     if (enToolTipText != null) {
  1173:       comboBox.setToolTipText (enToolTipText);
  1174:       comboBox.setActionCommand (enToolTipText);
  1175:     }
  1176:     return addListener (comboBox, listener);
  1177:   }  //createComboBox(int,String,ActionListener,String...)
  1178: 
  1179: 
  1180:   //--------------------------------------------------------------------------------
  1181:   //スライダーを作る
  1182: 
  1183:   //slider = createHorizontalSlider (min, max, value, major, minor, texts, listener)
  1184:   //  ラベルのテキストを指定してスライダーを作る
  1185:   public static JSlider createHorizontalSlider (int min, int max, int value, int major, int minor, String[] texts, ChangeListener listener) {
  1186:     JSlider slider = createHorizontalSlider (min, max, value, major, minor, listener);
  1187:     Hashtable<Integer,JComponent> table = new Hashtable<Integer,JComponent> ();
  1188:     for (int i = min; i <= max; i++) {
  1189:       if (i % major == 0 && texts[i - min] != null) {  //メジャー目盛りの位置だけ書く
  1190:         table.put (i, createLabel (texts[i - min]));
  1191:       }
  1192:     }
  1193:     slider.setLabelTable (table);
  1194:     return slider;
  1195:   }  //createHorizontalSlider(int,int,int,int,int,String[],ChangeListener)
  1196: 
  1197:   //slider = createHorizontalSlider (min, max, value, major, minor, listener)
  1198:   //  スライダーを作る
  1199:   public static JSlider createHorizontalSlider (int min, int max, int value, int major, int minor, ChangeListener listener) {
  1200:     JSlider slider = new JSlider (SwingConstants.HORIZONTAL, min, max, value);
  1201:     if (major != 0) {
  1202:       slider.setLabelTable (slider.createStandardLabels (major));
  1203:       slider.setPaintLabels (true);
  1204:       slider.setMajorTickSpacing (major);
  1205:       if (minor != 0) {
  1206:         slider.setMinorTickSpacing (minor);
  1207:       }
  1208:       slider.setPaintTicks (true);
  1209:       slider.setSnapToTicks (true);
  1210:     }
  1211:     return addListener (slider, listener);
  1212:   }  //createHorizontalSlider(int,int,int,int,int,ChangeListener)
  1213: 
  1214: 
  1215:   //--------------------------------------------------------------------------------
  1216:   //メニューを作る
  1217: 
  1218:   //menuBar = createMenuBar (component, ...)
  1219:   //  メニューバーを作る
  1220:   //  メニューアイテムを並べる
  1221:   //  nullは何も表示しない
  1222:   //  Box.createHorizontalGlue()を追加すると残りのメニューを右に寄せることができる
  1223:   public static JMenuBar createMenuBar (Component... components) {
  1224:     JMenuBar bar = new JMenuBar ();
  1225:     for (Component component : components) {
  1226:       if (component != null) {
  1227:         bar.add (component);
  1228:       }
  1229:     }
  1230:     return bar;
  1231:   }  //createMenuBar(Component...)
  1232: 
  1233:   //menu = createMenu (enText, item, ...)
  1234:   //menu = createMenu (enText, mnemonic, item, ...)
  1235:   //  メニューを作る
  1236:   //  メニューアイテムを並べる
  1237:   //  nullは何も表示しない
  1238:   //  セパレータを入れるときはcreateHorizontalSeparator()を使う
  1239:   //  JSeparatorを受け付けるためJMenuItem...ではなくJComponent...にする
  1240:   public static JMenu createMenu (String enText, JComponent... items) {
  1241:     return createMenu (enText, KeyEvent.VK_UNDEFINED, items);
  1242:   }  //createMenu(String,JComponent...)
  1243:   public static JMenu createMenu (String enText, int mnemonic, JComponent... items) {
  1244:     JMenu menu = new JMenu ();
  1245:     for (JComponent item : items) {
  1246:       if (item != null) {
  1247:         menu.add (item);
  1248:       }
  1249:     }
  1250:     //menu.setAccelerator()は実行時エラーになる
  1251:     //  java.lang.Error: setAccelerator() is not defined for JMenu.  Use setMnemonic() instead.
  1252:     return setButtonCommons (menu, enText, mnemonic, null);  //ボタンの共通の設定
  1253:   }  //createMenu(String,int,JComponent...)
  1254: 
  1255:   //popupMenu = createPopupMenu (item, ...)
  1256:   //  ポップアップメニューを作る
  1257:   //  メニューアイテムを並べる
  1258:   //  nullは何も表示しない
  1259:   //  セパレータを入れるときはcreateHorizontalSeparator()を使う
  1260:   //  JSeparatorを受け付けるためJMenuItem...ではなくJComponent...にする
  1261:   public static JPopupMenu createPopupMenu (JComponent... items) {
  1262:     JPopupMenu popupMenu = new JPopupMenu ();
  1263:     for (JComponent item : items) {
  1264:       if (item != null) {
  1265:         popupMenu.add (item);
  1266:       }
  1267:     }
  1268:     return popupMenu;
  1269:   }  //createPopupMenu(JComponent...)
  1270: 
  1271:   //item = createMenuItem (enText, listener)
  1272:   //item = createMenuItem (enText, mnemonic, listener)
  1273:   //  メニューアイテムを作る
  1274:   public static JMenuItem createMenuItem (String enText, ActionListener listener) {
  1275:     return createMenuItem (enText, KeyEvent.VK_UNDEFINED, listener);
  1276:   }  //createMenuItem(String,ActionListener)
  1277:   public static JMenuItem createMenuItem (String enText, int mnemonic, ActionListener listener) {
  1278:     return createMenuItem (enText, mnemonic, 0, listener);
  1279:   }  //createMenuItem(String,int,ActionListener)
  1280:   public static JMenuItem createMenuItem (String enText, int mnemonic, int modifiers, ActionListener listener) {
  1281:     JMenuItem item = new JMenuItem ();
  1282:     if (modifiers != 0) {
  1283:       item.setAccelerator (KeyStroke.getKeyStroke (mnemonic, modifiers));
  1284:       mnemonic = KeyEvent.VK_UNDEFINED;
  1285:     }
  1286:     return setButtonCommons (item, enText, mnemonic, listener);  //ボタンの共通の設定
  1287:   }  //createMenuItem(String,int,int,ActionListener)
  1288: 
  1289:   //item = createCheckBoxMenuItem (selected, enText, listener)
  1290:   //item = createCheckBoxMenuItem (selected, enText, mnemonic, listener)
  1291:   //  チェックボックスメニューアイテムを作る
  1292:   public static JCheckBoxMenuItem createCheckBoxMenuItem (boolean selected, String enText, ActionListener listener) {
  1293:     return createCheckBoxMenuItem (selected, enText, KeyEvent.VK_UNDEFINED, listener);
  1294:   }  //createCheckBoxMenuItem(boolean,String,ActionListener)
  1295:   public static JCheckBoxMenuItem createCheckBoxMenuItem (boolean selected, String enText, int mnemonic, ActionListener listener) {
  1296:     return createCheckBoxMenuItem (selected, enText, mnemonic, 0, listener);
  1297:   }  //createCheckBoxMenuItem(boolean,String,int,ActionListener)
  1298:   public static JCheckBoxMenuItem createCheckBoxMenuItem (boolean selected, String enText, int mnemonic, int modifiers, ActionListener listener) {
  1299:     JCheckBoxMenuItem item = new JCheckBoxMenuItem ();
  1300:     item.setSelected (selected);
  1301:     if (modifiers != 0) {
  1302:       item.setAccelerator (KeyStroke.getKeyStroke (mnemonic, modifiers));
  1303:       mnemonic = KeyEvent.VK_UNDEFINED;
  1304:     }
  1305:     return setButtonCommons (item, enText, mnemonic, listener);  //ボタンの共通の設定
  1306:   }  //createCheckBoxMenuItem(boolean,String,int,int,ActionListener)
  1307: 
  1308:   //item = createRadioButtonMenuItem (group, selected, enText, listener)
  1309:   //item = createRadioButtonMenuItem (group, selected, enText, mnemonic, listener)
  1310:   //  ラジオボタンメニューアイテムを作る
  1311:   public static JRadioButtonMenuItem createRadioButtonMenuItem (ButtonGroup group, boolean selected, String enText, ActionListener listener) {
  1312:     return createRadioButtonMenuItem (group, selected, enText, KeyEvent.VK_UNDEFINED, listener);
  1313:   }  //createRadioButtonMenuItem(ButtonGroup,boolean,String,ActionListener)
  1314:   public static JRadioButtonMenuItem createRadioButtonMenuItem (ButtonGroup group, boolean selected, String enText, int mnemonic, ActionListener listener) {
  1315:     return createRadioButtonMenuItem (group, selected, enText, mnemonic, 0, listener);
  1316:   }  //createRadioButtonMenuItem(ButtonGroup,boolean,String,int,ActionListener)
  1317:   public static JRadioButtonMenuItem createRadioButtonMenuItem (ButtonGroup group, boolean selected, String enText, int mnemonic, int modifiers, ActionListener listener) {
  1318:     JRadioButtonMenuItem item = new JRadioButtonMenuItem ();
  1319:     group.add (item);
  1320:     item.setSelected (selected);
  1321:     if (modifiers != 0) {
  1322:       item.setAccelerator (KeyStroke.getKeyStroke (mnemonic, modifiers));
  1323:       mnemonic = KeyEvent.VK_UNDEFINED;
  1324:     }
  1325:     return setButtonCommons (item, enText, mnemonic, listener);  //ボタンの共通の設定
  1326:   }  //createRadioButtonMenuItem(ButtonGroup,boolean,String,int,int,ActionListener)
  1327: 
  1328:   //setButtonCommons (button, enText, mnemonic, listener)
  1329:   //  ボタンの共通の設定
  1330:   //  ニモニックを含まないテキストをそのままアクションコマンドにする
  1331:   //  Multilingual.mlnTextがアクションコマンドを英語のテキストとして使うのでアクションリスナーを省略してもアクションコマンドは設定される
  1332:   //  ニモニックはKeyEvent.VK_~で指定する。英数字は大文字のcharで指定しても問題ない
  1333:   //  Multilingual.mlnTextがニモニックの有無をgetMnemonicで確認するのでニモニックがKeyEvent.VK_UNDEFINEDのときもそのままニモニックとして設定される
  1334:   public static <T extends AbstractButton> T setButtonCommons (T button, String enText, int mnemonic, ActionListener listener) {
  1335:     button.setMnemonic (mnemonic);
  1336:     if (mnemonic == KeyEvent.VK_UNDEFINED) {  //ニモニックがないとき
  1337:       button.setText (enText);
  1338:     } else {  //ニモニックがあるとき
  1339:       //テキストにニモニックの大文字と小文字が両方含まれているとき、大文字と小文字が一致するほうにマークを付ける
  1340:       String mnemonicText = KeyEvent.getKeyText (mnemonic);
  1341:       int index = enText.indexOf (mnemonicText);  //大文字と小文字を区別して検索する
  1342:       if (index < 0) {
  1343:         index = enText.toLowerCase ().indexOf (mnemonicText.toLowerCase ());  //大文字と小文字を区別せずに検索する
  1344:       }
  1345:       if (index >= 0) {  //ニモニックがテキストに含まれているとき
  1346:         button.setText (enText);
  1347:         button.setDisplayedMnemonicIndex (index);
  1348:       } else {  //ニモニックがテキストに含まれていないとき
  1349:         button.setText (enText + "(" + mnemonicText + ")");
  1350:         button.setDisplayedMnemonicIndex (enText.length () + 1);
  1351:       }
  1352:     }
  1353:     button.setActionCommand (enText);
  1354:     return addListener (button, listener);
  1355:   }  //setButtonCommons(T extends AbstractButton,String,int,ActionListener)
  1356: 
  1357: 
  1358:   //--------------------------------------------------------------------------------
  1359:   //スクロールリストを作る
  1360: 
  1361:   //list = createScrollList (texts, visibleRowCount, selectedIndex, listener)
  1362:   //list = createScrollList (texts, visibleRowCount, selectedIndex, selectionMode, listener)
  1363:   //  selectionMode
  1364:   //    ListSelectionModel.SINGLE_SELECTION
  1365:   //    ListSelectionModel.SINGLE_INTERVAL_SELECTION
  1366:   //    ListSelectionModel.MULTIPLE_INTERVAL_SELECTION
  1367:   public static ScrollList createScrollList (String[] texts, int visibleRowCount, int selectedIndex, ListSelectionListener listener) {
  1368:     return createScrollList (texts, visibleRowCount, selectedIndex, ListSelectionModel.SINGLE_SELECTION, listener);
  1369:   }  //createScrollList(String[],int,int)
  1370:   public static ScrollList createScrollList (String[] texts, int visibleRowCount, int selectedIndex, int selectionMode, ListSelectionListener listener) {
  1371:     DefaultListModel<String> listModel = new DefaultListModel<String> ();
  1372:     for (String text : texts) {
  1373:       listModel.addElement (text);
  1374:     }
  1375:     ScrollList list = new ScrollList (listModel);
  1376:     list.setVisibleRowCount (visibleRowCount);
  1377:     list.setSelectionMode (selectionMode);
  1378:     list.setSelectedIndex (selectedIndex);
  1379:     return addListener (list, listener);
  1380:   }  //createScrollList(String[],int,int,int)
  1381: 
  1382: 
  1383:   //--------------------------------------------------------------------------------
  1384:   //スピナーを作る
  1385: 
  1386:   //spinner = createNumberSpinner (model, digits, listener)
  1387:   //  ナンバースピナーを作る
  1388:   public static NumberSpinner createNumberSpinner (SpinnerNumberModel model, int digits, ChangeListener listener) {
  1389:     NumberSpinner spinner = new NumberSpinner (model);
  1390:     spinner.setBorder (new LineBorder (MetalLookAndFeel.getBlack (), 1));  //black
  1391:     spinner.setPreferredSize (new Dimension (24 + 6 * digits, 16));
  1392:     spinner.setMaximumSize (new Dimension (24 + 6 * digits, 16));
  1393:     JSpinner.NumberEditor editor = (JSpinner.NumberEditor) spinner.getEditor ();
  1394:     editor.getFormat ().setGroupingUsed (false);  //3桁毎にグループ化しない
  1395:     JTextField textField = editor.getTextField ();
  1396:     textField.setHorizontalAlignment (JTextField.RIGHT);  //右寄せ
  1397:     textField.setFont (new Font ("Monospaced", Font.PLAIN, 12));
  1398:     return addListener (spinner, listener);
  1399:   }  //createNumberSpinner(SpinnerNumberModel,int,ChangeListener)
  1400: 
  1401:   //spinner = createDecimalSpinner (value, minimum, maximum, stepSize)
  1402:   //spinner = createDecimalSpinner (value, minimum, maximum, stepSize, option)
  1403:   //spinner = createDecimalSpinner (value, minimum, maximum, stepSize, option, listener)
  1404:   //  10進数スピナーを作る
  1405:   public static DecimalSpinner createDecimalSpinner (int value, int minimum, int maximum, int stepSize) {
  1406:     return createDecimalSpinner (value, minimum, maximum, stepSize, 0, null);
  1407:   }  //createDecimalSpinner(int,int,int,int)
  1408:   public static DecimalSpinner createDecimalSpinner (int value, int minimum, int maximum, int stepSize, int option) {
  1409:     return createDecimalSpinner (value, minimum, maximum, stepSize, option, null);
  1410:   }  //createDecimalSpinner(int,int,int,int,int)
  1411:   public static DecimalSpinner createDecimalSpinner (int value, int minimum, int maximum, int stepSize, int option, ChangeListener listener) {
  1412:     return addListener (new DecimalSpinner (value, minimum, maximum, stepSize, option), listener);
  1413:   }  //createDecimalSpinner(int,int,int,int,int,ChangeListener)
  1414: 
  1415:   //spinner = createHex8Spinner (value, mask, reverse, listener)
  1416:   //   8桁16進数スピナーを作る
  1417:   public static Hex8Spinner createHex8Spinner (int value, int mask, boolean reverse, ChangeListener listener) {
  1418:     return addListener (new Hex8Spinner (value, mask, reverse), listener);
  1419:   }  //createHex8Spinner(int,int,boolean,ChangeListener)
  1420: 
  1421:   //spinner = createListSpinner (list, value, listener)
  1422:   //  リストスピナーを作る
  1423:   public static JSpinner createListSpinner (java.util.List<?> list, Object value, ChangeListener listener) {
  1424:     SpinnerListModel model = new SpinnerListModel (list);
  1425:     JSpinner spinner = new JSpinner (model);
  1426:     spinner.setBorder (new LineBorder (MetalLookAndFeel.getSeparatorForeground (), 1));  //primary1
  1427:     int digits = 0;
  1428:     for (Object t : list) {
  1429:       digits = Math.max (digits, String.valueOf (t).length ());
  1430:     }
  1431:     spinner.setPreferredSize (new Dimension (24 + 10 * digits, 16));
  1432:     spinner.setMaximumSize (new Dimension (24 + 10 * digits, 16));
  1433:     JSpinner.ListEditor editor = (JSpinner.ListEditor) spinner.getEditor ();
  1434:     JTextField textField = editor.getTextField ();
  1435:     textField.setHorizontalAlignment (JTextField.RIGHT);  //右寄せ
  1436:     textField.setFont (new Font ("Monospaced", Font.PLAIN, 12));
  1437:     model.setValue (value);  //初期設定ではリスナーを呼び出さない
  1438:     return addListener (spinner, listener);
  1439:   }  //createListSpinner (java.util.List<?>,Object,ChangeListener)
  1440: 
  1441: 
  1442: }  //class ComponentFactory
  1443: 
  1444: 
  1445: